From 64093482a6b3085bae1c483609a527fcaeb97639 Mon Sep 17 00:00:00 2001 From: bwzhou <bwzhou> Date: Tue, 13 May 2008 05:56:39 +0000 Subject: [PATCH] Branch b1_6 b=14740 r=adilger, bobijam break a single big chunk of memory allocation for lprocfs_stats into separately allocated small chunks to prevent kmalloc failure in a huge cluster --- lustre/include/lprocfs_status.h | 1 - lustre/obdclass/lprocfs_status.c | 29 +++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index eadf96db40..842576f253 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -160,7 +160,6 @@ enum lprocfs_fields_flags { struct lprocfs_stats { unsigned int ls_num; /* # of counters */ - unsigned int ls_percpu_size; int ls_flags; /* See LPROCFS_STATS_FLAG_* */ spinlock_t ls_lock; /* Lock used only when there are * no percpu stats areas */ diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 44cdf07d11..bd2629416b 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -800,9 +800,8 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags) { struct lprocfs_stats *stats; - struct lprocfs_percpu *percpu; unsigned int percpusize; - unsigned int i; + unsigned int i, j; unsigned int num_cpu; if (num == 0) @@ -825,12 +824,20 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, stats->ls_flags = 0; } - percpusize = offsetof(typeof(*percpu), lp_cntr[num]); + percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]); if (num_cpu > 1) percpusize = L1_CACHE_ALIGN(percpusize); - stats->ls_percpu_size = num_cpu * percpusize; - OBD_ALLOC(stats->ls_percpu[0], stats->ls_percpu_size); + for (i = 0; i < num_cpu; i++) { + OBD_ALLOC(stats->ls_percpu[i], percpusize); + if (stats->ls_percpu[i] == NULL) { + for (j = 0; j < i; j++) { + OBD_FREE(stats->ls_percpu[j], percpusize); + stats->ls_percpu[j] = NULL; + } + break; + } + } if (stats->ls_percpu[0] == NULL) { OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu])); @@ -838,10 +845,6 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, } stats->ls_num = num; - for (i = 1; i < num_cpu; i++) - stats->ls_percpu[i] = (void *)(stats->ls_percpu[i - 1]) + - percpusize; - return stats; } @@ -849,6 +852,8 @@ void lprocfs_free_stats(struct lprocfs_stats **statsh) { struct lprocfs_stats *stats = *statsh; unsigned int num_cpu; + unsigned int percpusize; + unsigned int i; if (!stats || (stats->ls_num == 0)) return; @@ -858,7 +863,11 @@ void lprocfs_free_stats(struct lprocfs_stats **statsh) else num_cpu = num_possible_cpus(); - OBD_FREE(stats->ls_percpu[0], stats->ls_percpu_size); + percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]); + if (num_cpu > 1) + percpusize = L1_CACHE_ALIGN(percpusize); + for (i = 0; i < num_cpu; i++) + OBD_FREE(stats->ls_percpu[i], percpusize); OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_cpu])); } -- GitLab