From: Darrick J. Wong <djwong@xxxxxxxxxx> Convert all kmem cache users to call kmem_cache_destroy, and make leak checking an explicit operation. This gets us closer to the kernel interface. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- include/kmem.h | 14 +++++--------- libxfs/init.c | 32 ++++++++++++++------------------ libxfs/kmem.c | 21 +++++++++++++++------ 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/include/kmem.h b/include/kmem.h index c710635d..53a2b37a 100644 --- a/include/kmem.h +++ b/include/kmem.h @@ -6,6 +6,9 @@ #ifndef __KMEM_H__ #define __KMEM_H__ +void kmem_start_leak_check(void); +bool kmem_found_leaks(void); + #define KM_NOFS 0x0004u #define KM_MAYFAIL 0x0008u #define KM_LARGE 0x0010u @@ -38,17 +41,10 @@ kmem_zone_init(unsigned int size, const char *name) return kmem_cache_create(name, size, 0, 0, NULL); } +void kmem_cache_destroy(kmem_zone_t *); + extern void *kmem_cache_alloc(kmem_zone_t *, gfp_t); extern void *kmem_cache_zalloc(kmem_zone_t *, gfp_t); -extern int kmem_zone_destroy(kmem_zone_t *); - - -static inline void -kmem_cache_destroy(kmem_zone_t *zone) -{ - kmem_zone_destroy(zone); -} - static inline void kmem_cache_free(kmem_zone_t *zone, void *ptr) diff --git a/libxfs/init.c b/libxfs/init.c index 3c1639db..0d693848 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -255,22 +255,18 @@ init_zones(void) sizeof(struct xfs_trans), "xfs_trans"); } -static int -destroy_zones(void) +static void +destroy_kmem_caches(void) { - int leaked = 0; - - leaked += kmem_zone_destroy(xfs_buf_zone); - leaked += kmem_zone_destroy(xfs_ili_zone); - leaked += kmem_zone_destroy(xfs_inode_zone); - leaked += kmem_zone_destroy(xfs_ifork_zone); - leaked += kmem_zone_destroy(xfs_buf_item_zone); - leaked += kmem_zone_destroy(xfs_da_state_zone); + kmem_cache_destroy(xfs_buf_zone); + kmem_cache_destroy(xfs_ili_zone); + kmem_cache_destroy(xfs_inode_zone); + kmem_cache_destroy(xfs_ifork_zone); + kmem_cache_destroy(xfs_buf_item_zone); + kmem_cache_destroy(xfs_da_state_zone); xfs_btree_destroy_cur_caches(); - leaked += kmem_zone_destroy(xfs_bmap_free_item_zone); - leaked += kmem_zone_destroy(xfs_trans_zone); - - return leaked; + kmem_cache_destroy(xfs_bmap_free_item_zone); + kmem_cache_destroy(xfs_trans_zone); } static void @@ -1025,17 +1021,17 @@ void libxfs_destroy( struct libxfs_xinit *li) { - int leaked; - + kmem_start_leak_check(); libxfs_close_devices(li); /* Free everything from the buffer cache before freeing buffer zone */ libxfs_bcache_purge(); libxfs_bcache_free(); cache_destroy(libxfs_bcache); - leaked = destroy_zones(); + destroy_kmem_caches(); rcu_unregister_thread(); - if (getenv("LIBXFS_LEAK_CHECK") && leaked) + + if (kmem_found_leaks()) exit(1); } diff --git a/libxfs/kmem.c b/libxfs/kmem.c index 221b3480..804d4b3c 100644 --- a/libxfs/kmem.c +++ b/libxfs/kmem.c @@ -3,6 +3,18 @@ #include "libxfs_priv.h" +static bool leaked; + +void kmem_start_leak_check(void) +{ + leaked = false; +} + +bool kmem_found_leaks(void) +{ + return leaked; +} + /* * Simple memory interface */ @@ -27,18 +39,15 @@ kmem_cache_create(const char *name, unsigned int size, unsigned int align, return ptr; } -int -kmem_zone_destroy(kmem_zone_t *zone) +void +kmem_cache_destroy(kmem_zone_t *zone) { - int leaked = 0; - if (getenv("LIBXFS_LEAK_CHECK") && zone->allocated) { - leaked = 1; + leaked = true; fprintf(stderr, "zone %s freed with %d items allocated\n", zone->zone_name, zone->allocated); } free(zone); - return leaked; } void *