On Fri, Apr 10, 2015 at 04:31:03PM +1000, Alexey Kardashevskiy wrote: > The iommu_free_table helper release memory it is using (the TCE table and > @it_map) and release the iommu_table struct as well. We might not want > the very last step as we store iommu_table in parent structures.
Yeah, as I commented on the earlier patch, freeing the surrounding group from a function taking just the individual table is wrong. > > Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> > --- > arch/powerpc/include/asm/iommu.h | 1 + > arch/powerpc/kernel/iommu.c | 57 > ++++++++++++++++++++++++---------------- > 2 files changed, 35 insertions(+), 23 deletions(-) > > diff --git a/arch/powerpc/include/asm/iommu.h > b/arch/powerpc/include/asm/iommu.h > index bde7ee7..8ed4648 100644 > --- a/arch/powerpc/include/asm/iommu.h > +++ b/arch/powerpc/include/asm/iommu.h > @@ -127,6 +127,7 @@ static inline void *get_iommu_table_base(struct device > *dev) > > extern struct iommu_table *iommu_table_alloc(int node); > /* Frees table for an individual device node */ > +extern void iommu_reset_table(struct iommu_table *tbl, const char > *node_name); > extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); > > /* Initializes an iommu_table based in values set in the passed-in > diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c > index 501e8ee..0bcd988 100644 > --- a/arch/powerpc/kernel/iommu.c > +++ b/arch/powerpc/kernel/iommu.c > @@ -721,24 +721,46 @@ struct iommu_table *iommu_table_alloc(int node) > return &table_group->tables[0]; > } > > +void iommu_reset_table(struct iommu_table *tbl, const char *node_name) > +{ > + if (!tbl) > + return; > + > + if (tbl->it_map) { > + unsigned long bitmap_sz; > + unsigned int order; > + > + /* > + * In case we have reserved the first bit, we should not emit > + * the warning below. > + */ > + if (tbl->it_offset == 0) > + clear_bit(0, tbl->it_map); > + > + /* verify that table contains no entries */ > + if (!bitmap_empty(tbl->it_map, tbl->it_size)) > + pr_warn("%s: Unexpected TCEs for %s\n", __func__, > + node_name); > + > + /* calculate bitmap size in bytes */ > + bitmap_sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long); > + > + /* free bitmap */ > + order = get_order(bitmap_sz); > + free_pages((unsigned long) tbl->it_map, order); > + } > + > + memset(tbl, 0, sizeof(*tbl)); > +} > + > void iommu_free_table(struct iommu_table *tbl, const char *node_name) > { > - unsigned long bitmap_sz; > - unsigned int order; > struct iommu_table_group *table_group = tbl->it_group; > > - if (!tbl || !tbl->it_map) { > - printk(KERN_ERR "%s: expected TCE map for %s\n", __func__, > - node_name); > + if (!tbl) > return; > - } > > - /* > - * In case we have reserved the first bit, we should not emit > - * the warning below. > - */ > - if (tbl->it_offset == 0) > - clear_bit(0, tbl->it_map); > + iommu_reset_table(tbl, node_name); > > #ifdef CONFIG_IOMMU_API > if (table_group->group) { > @@ -747,17 +769,6 @@ void iommu_free_table(struct iommu_table *tbl, const > char *node_name) > } > #endif > > - /* verify that table contains no entries */ > - if (!bitmap_empty(tbl->it_map, tbl->it_size)) > - pr_warn("%s: Unexpected TCEs for %s\n", __func__, node_name); > - > - /* calculate bitmap size in bytes */ > - bitmap_sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long); > - > - /* free bitmap */ > - order = get_order(bitmap_sz); > - free_pages((unsigned long) tbl->it_map, order); > - > /* free table */ > kfree(table_group); > } -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
pgpfqK1xnKhNy.pgp
Description: PGP signature
_______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev