From: Bobi Jam Date: Thu, 5 Apr 2012 06:25:40 +0000 (+0800) Subject: LU-1282 lprocfs: Use present cpu numbers to save memory X-Git-Tag: 2.1.3-RC2~1 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=763e3f98e9dc4140f8922709277c501a7d3265c0;p=fs%2Flustre-release.git LU-1282 lprocfs: Use present cpu numbers to save memory Port of combined patch from master branch: Commit 65dc702123f91c4fb2ae25604f98e195fcc15544 Commit 8c831cb8a05f0d6f63b88e9b2dfb85ba4eca217a Commit 560efa06be97651252caff4ba9bc2c014cf62ff9 * lprocfs stats data should allocated by the number of present cpus in stead of by possible cpu number which wastes a lot of memory. * When new cpus are hot-plugged in, alloc necessary percpu array elements on demand. * Add a LPROCFS_STATS_FLAG_IRQ_SAFE flag, when a stat is non-percpu stats with this flag, lprocfs_stats_lock() should disable irq. * OSS minimum thread number also better be decided by online cpu number. Signed-off-by: Bobi Jam Change-Id: I7e80f27123d2e0a6352dc8d01e6ca70b9f137220 Reviewed-on: http://review.whamcloud.com/3607 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/libcfs/include/libcfs/linux/kp30.h b/libcfs/include/libcfs/linux/kp30.h index 122a506..bf074ff 100644 --- a/libcfs/include/libcfs/linux/kp30.h +++ b/libcfs/include/libcfs/linux/kp30.h @@ -159,11 +159,8 @@ do { \ # define printf(format, b...) CDEBUG(D_OTHER, format , ## b) # define time(a) CURRENT_TIME -#ifndef num_possible_cpus -#define cfs_num_possible_cpus() NR_CPUS -#else -#define cfs_num_possible_cpus() num_possible_cpus() -#endif +# define cfs_num_possible_cpus() num_possible_cpus() +# define cfs_num_present_cpus() num_present_cpus() /******************************************************************************/ /* Light-weight trace diff --git a/libcfs/include/libcfs/user-prim.h b/libcfs/include/libcfs/user-prim.h index 39cb8bf..e6a217b 100644 --- a/libcfs/include/libcfs/user-prim.h +++ b/libcfs/include/libcfs/user-prim.h @@ -59,21 +59,25 @@ typedef struct proc_dir_entry cfs_proc_dir_entry_t; * Just present a single processor until will add thread support. */ #ifndef smp_processor_id -#define cfs_smp_processor_id() 0 +# define cfs_smp_processor_id() 0 #else -#define cfs_smp_processor_id() smp_processor_id() +# define cfs_smp_processor_id() smp_processor_id() #endif #ifndef num_online_cpus -#define cfs_num_online_cpus() 1 +# define cfs_num_online_cpus() 1 #else -#define cfs_num_online_cpus() num_online_cpus() +# define cfs_num_online_cpus() num_online_cpus() #endif #ifndef num_possible_cpus -#define cfs_num_possible_cpus() 1 +# define cfs_num_possible_cpus() 1 #else -#define cfs_num_possible_cpus() num_possible_cpus() +# define cfs_num_possible_cpus() num_possible_cpus() +#endif +#ifndef num_present_cpus +# define cfs_num_present_cpus() 1 +#else +# define cfs_num_present_cpus() num_present_cpus() #endif - /* * Wait Queue. */ diff --git a/libcfs/include/libcfs/winnt/winnt-prim.h b/libcfs/include/libcfs/winnt/winnt-prim.h index f2792d5..9c01f36 100644 --- a/libcfs/include/libcfs/winnt/winnt-prim.h +++ b/libcfs/include/libcfs/winnt/winnt-prim.h @@ -862,6 +862,7 @@ libcfs_arch_cleanup(void); #define CFS_NR_CPUS (32) #define smp_num_cpus ((CCHAR)KeNumberProcessors) #define cfs_num_possible_cpus() smp_num_cpus +#define cfs_num_present_cpus() smp_num_cpus #define cfs_num_online_cpus() smp_num_cpus #define cfs_smp_processor_id() ((USHORT)KeGetCurrentProcessorNumber()) #define smp_call_function(f, a, n, w) do {} while(0) diff --git a/libcfs/libcfs/linux/linux-tracefile.c b/libcfs/libcfs/linux/linux-tracefile.c index 51d7d7f..2071494 100644 --- a/libcfs/libcfs/linux/linux-tracefile.c +++ b/libcfs/libcfs/linux/linux-tracefile.c @@ -63,8 +63,8 @@ int cfs_tracefile_init_arch() memset(cfs_trace_data, 0, sizeof(cfs_trace_data)); for (i = 0; i < CFS_TCD_TYPE_MAX; i++) { cfs_trace_data[i] = - kmalloc(sizeof(union cfs_trace_data_union) * NR_CPUS, - GFP_KERNEL); + kmalloc(sizeof(union cfs_trace_data_union) * + cfs_num_possible_cpus(), GFP_KERNEL); if (cfs_trace_data[i] == NULL) goto out; @@ -78,11 +78,11 @@ int cfs_tracefile_init_arch() tcd->tcd_cpu = j; } - for (i = 0; i < num_possible_cpus(); i++) + for (i = 0; i < cfs_num_possible_cpus(); i++) for (j = 0; j < 3; j++) { - cfs_trace_console_buffers[i][j] = - kmalloc(CFS_TRACE_CONSOLE_BUFFER_SIZE, - GFP_KERNEL); + cfs_trace_console_buffers[i][j] = + kmalloc(CFS_TRACE_CONSOLE_BUFFER_SIZE, + GFP_KERNEL); if (cfs_trace_console_buffers[i][j] == NULL) goto out; @@ -94,7 +94,6 @@ out: cfs_tracefile_fini_arch(); printk(KERN_ERR "lnet: Not enough memory\n"); return -ENOMEM; - } void cfs_tracefile_fini_arch() @@ -102,7 +101,7 @@ void cfs_tracefile_fini_arch() int i; int j; - for (i = 0; i < num_possible_cpus(); i++) + for (i = 0; i < cfs_num_possible_cpus(); i++) for (j = 0; j < 3; j++) if (cfs_trace_console_buffers[i][j] != NULL) { kfree(cfs_trace_console_buffers[i][j]); diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 6df4466..9ee6379 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -168,8 +168,8 @@ struct lprocfs_counter { }; struct lprocfs_percpu { -#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L - __s64 pad; +#ifndef __GNUC__ + __s64 pad; #endif struct lprocfs_counter lp_cntr[0]; }; @@ -178,9 +178,10 @@ struct lprocfs_percpu { #define LPROCFS_GET_SMP_ID 0x0002 enum lprocfs_stats_flags { - LPROCFS_STATS_FLAG_NONE = 0x0000, /* per cpu counter */ - LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu - * area and need locking */ + LPROCFS_STATS_FLAG_NONE = 0x0000, /* per cpu counter */ + LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu + * area and need locking */ + LPROCFS_STATS_FLAG_IRQ_SAFE = 0x0002, /* alloc need irq safe */ }; enum lprocfs_fields_flags { @@ -194,11 +195,16 @@ enum lprocfs_fields_flags { }; struct lprocfs_stats { - unsigned int ls_num; /* # of counters */ - int ls_flags; /* See LPROCFS_STATS_FLAG_* */ - cfs_spinlock_t ls_lock; /* Lock used only when there are - * no percpu stats areas */ - struct lprocfs_percpu *ls_percpu[0]; + unsigned short ls_num; /* # of counters */ + unsigned short ls_biggest_alloc_num; + /* 1 + the highest slot index which has + * been allocated, the 0th entry is + * a statically intialized template */ + int ls_flags; /* See LPROCFS_STATS_FLAG_* */ + /* Lock used when there are no percpu stats areas; For percpu stats, + * it is used to protect ls_biggest_alloc_num change */ + cfs_spinlock_t ls_lock; + struct lprocfs_percpu *ls_percpu[0]; }; #define OPC_RANGE(seg) (seg ## _LAST_OPC - seg ## _FIRST_OPC) @@ -356,48 +362,84 @@ static inline void s2dhms(struct dhms *ts, time_t secs) #ifdef LPROCFS -static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc) +extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, + unsigned int cpuid); +/* + * \return value + * < 0 : on error (only possible for opc as LPROCFS_GET_SMP_ID) + */ +static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc, + unsigned long *flags) { - switch (opc) { - default: - LBUG(); - - case LPROCFS_GET_SMP_ID: - if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { - cfs_spin_lock(&stats->ls_lock); - return 0; - } else { - return cfs_get_cpu(); - } - - case LPROCFS_GET_NUM_CPU: - if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { - cfs_spin_lock(&stats->ls_lock); - return 1; - } else { - return cfs_num_possible_cpus(); - } - } + int rc = 0; + unsigned int cpuid; + + switch (opc) { + default: + LBUG(); + + case LPROCFS_GET_SMP_ID: + /* percpu counter stats */ + if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0) { + cpuid = cfs_get_cpu(); + + if (unlikely(stats->ls_percpu[cpuid + 1] == NULL)) + rc = lprocfs_stats_alloc_one(stats, cpuid + 1); + return rc < 0 ? rc : cpuid + 1; + } + + /* non-percpu counter stats */ + if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) + cfs_spin_lock_irqsave(&stats->ls_lock, *flags); + else + cfs_spin_lock(&stats->ls_lock); + return 0; + + case LPROCFS_GET_NUM_CPU: + /* percpu counter stats */ + if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0) + return stats->ls_biggest_alloc_num; + + /* non-percpu counter stats */ + if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0) + cfs_spin_lock_irqsave(&stats->ls_lock, *flags); + else + cfs_spin_lock(&stats->ls_lock); + return 1; + } } -static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc) +static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc, + unsigned long *flags) { - switch (opc) { - default: - LBUG(); - - case LPROCFS_GET_SMP_ID: - if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) - cfs_spin_unlock(&stats->ls_lock); - else - cfs_put_cpu(); - return; - - case LPROCFS_GET_NUM_CPU: - if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) - cfs_spin_unlock(&stats->ls_lock); - return; - } + switch (opc) { + default: + LBUG(); + + case LPROCFS_GET_SMP_ID: + if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { + if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) { + cfs_spin_unlock_irqrestore(&stats->ls_lock, + *flags); + } else { + cfs_spin_unlock(&stats->ls_lock); + } + } else { + cfs_put_cpu(); + } + return; + + case LPROCFS_GET_NUM_CPU: + if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) { + if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) { + cfs_spin_unlock_irqrestore(&stats->ls_lock, + *flags); + } else { + cfs_spin_unlock(&stats->ls_lock); + } + } + return; + } } /* Two optimized LPROCFS counter increment functions are provided: @@ -423,18 +465,22 @@ static inline __u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx, enum lprocfs_fields_flags field) { - __u64 ret = 0; - int i; - unsigned int num_cpu; - - LASSERT(stats != NULL); - - num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU); - for (i = 0; i < num_cpu; i++) - ret += lprocfs_read_helper(&(stats->ls_percpu[i]->lp_cntr[idx]), - field); - lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU); - return ret; + int i; + unsigned int num_cpu; + unsigned long flags = 0; + __u64 ret = 0; + + LASSERT(stats != NULL); + + num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); + for (i = 0; i < num_cpu; i++) { + if (stats->ls_percpu[i] == NULL) + continue; + ret += lprocfs_read_helper(&(stats->ls_percpu[i]->lp_cntr[idx]), + field); + } + lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); + return ret; } extern struct lprocfs_stats * diff --git a/lustre/lvfs/lvfs_lib.c b/lustre/lvfs/lvfs_lib.c index 9660b90..187281f 100644 --- a/lustre/lvfs/lvfs_lib.c +++ b/lustre/lvfs/lvfs_lib.c @@ -74,15 +74,18 @@ EXPORT_SYMBOL(obd_alloc_fail); void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, long amount) { - struct lprocfs_counter *percpu_cntr; - int smp_id; + struct lprocfs_counter *percpu_cntr; + int smp_id; + unsigned long flags = 0; if (stats == NULL) return; - /* With per-client stats, statistics are allocated only for - * single CPU area, so the smp_id should be 0 always. */ - smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID); + /* With per-client stats, statistics are allocated only for + * single CPU area, so the smp_id should be 0 always. */ + smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID, &flags); + if (smp_id < 0) + return; percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]); if (!(stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)) @@ -103,22 +106,24 @@ void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, } if (!(stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)) cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit); - lprocfs_stats_unlock(stats, LPROCFS_GET_SMP_ID); + lprocfs_stats_unlock(stats, LPROCFS_GET_SMP_ID, &flags); } EXPORT_SYMBOL(lprocfs_counter_add); -void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, - long amount) +void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, long amount) { - struct lprocfs_counter *percpu_cntr; - int smp_id; + struct lprocfs_counter *percpu_cntr; + int smp_id; + unsigned long flags = 0; if (stats == NULL) return; - /* With per-client stats, statistics are allocated only for - * single CPU area, so the smp_id should be 0 always. */ - smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID); + /* With per-client stats, statistics are allocated only for + * single CPU area, so the smp_id should be 0 always. */ + smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID, &flags); + if (smp_id < 0) + return; percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]); if (!(stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)) @@ -139,9 +144,51 @@ void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, } if (!(stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)) cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit); - lprocfs_stats_unlock(stats, LPROCFS_GET_SMP_ID); + lprocfs_stats_unlock(stats, LPROCFS_GET_SMP_ID, &flags); } EXPORT_SYMBOL(lprocfs_counter_sub); + +int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int idx) +{ + unsigned int percpusize; + int rc = -ENOMEM; + unsigned long flags = 0; + + /* the 1st percpu entry was statically allocated in + * lprocfs_alloc_stats() */ + LASSERT(idx != 0 && stats->ls_percpu[0] != NULL); + LASSERT(stats->ls_percpu[idx] == NULL); + LASSERT((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0); + + percpusize = CFS_L1_CACHE_ALIGN(offsetof(struct lprocfs_percpu, + lp_cntr[stats->ls_num])); + OBD_ALLOC_GFP(stats->ls_percpu[idx], percpusize, CFS_ALLOC_ATOMIC); + if (stats->ls_percpu[idx] != NULL) { + rc = 0; + if (unlikely(stats->ls_biggest_alloc_num <= idx)) { + if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) + cfs_spin_lock_irqsave(&stats->ls_lock, flags); + else + cfs_spin_lock(&stats->ls_lock); + if (stats->ls_biggest_alloc_num <= idx) + stats->ls_biggest_alloc_num = idx + 1; + if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) { + cfs_spin_unlock_irqrestore(&stats->ls_lock, + flags); + } else { + cfs_spin_unlock(&stats->ls_lock); + } + } + + /* initialize the ls_percpu[idx] by copying the 0th template + * entry */ + memcpy(stats->ls_percpu[idx], stats->ls_percpu[0], + percpusize); + } + + return rc; +} +EXPORT_SYMBOL(lprocfs_stats_alloc_one); #endif /* LPROCFS */ EXPORT_SYMBOL(obd_alloc_fail_rate); diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index 149fb72..577afbc 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -513,7 +513,8 @@ int init_obdclass(void) obd_zombie_impexp_init(); #ifdef LPROCFS obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM, - LPROCFS_STATS_FLAG_NONE); + LPROCFS_STATS_FLAG_NONE | + LPROCFS_STATS_FLAG_IRQ_SAFE); if (obd_memory == NULL) { CERROR("kmalloc of 'obd_memory' failed\n"); RETURN(-ENOMEM); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 8c0c854..9cee976 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -707,10 +707,12 @@ int lprocfs_rd_conn_uuid(char *page, char **start, off_t off, int count, void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, struct lprocfs_counter *cnt) { - unsigned int num_cpu; - struct lprocfs_counter t; - struct lprocfs_counter *percpu_cntr; - int centry, i; + unsigned int num_entry; + struct lprocfs_counter t; + struct lprocfs_counter *percpu_cntr; + int centry; + int i; + unsigned long flags = 0; memset(cnt, 0, sizeof(*cnt)); @@ -722,10 +724,12 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, cnt->lc_min = LC_MIN_INIT; - num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU); + num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); - for (i = 0; i < num_cpu; i++) { - percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx]; + for (i = 0; i < num_entry; i++) { + if (stats->ls_percpu[i] == NULL) + continue; + percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx]; do { centry = cfs_atomic_read(&percpu_cntr-> \ @@ -748,8 +752,8 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, cnt->lc_sumsquare += t.lc_sumsquare; } - cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units; - lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU); + cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units; + lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); } /** @@ -1190,10 +1194,9 @@ void lprocfs_free_per_client_stats(struct obd_device *obd) struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags) { - struct lprocfs_stats *stats; - unsigned int percpusize; - unsigned int i, j; - unsigned int num_cpu; + struct lprocfs_stats *stats; + unsigned int percpusize; + unsigned int num_entry; if (num == 0) return NULL; @@ -1201,93 +1204,87 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, if (lprocfs_no_percpu_stats != 0) flags |= LPROCFS_STATS_FLAG_NOPERCPU; - if (flags & LPROCFS_STATS_FLAG_NOPERCPU) - num_cpu = 1; - else - num_cpu = cfs_num_possible_cpus(); - - OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu])); - if (stats == NULL) - return NULL; + if (flags & LPROCFS_STATS_FLAG_NOPERCPU) + num_entry = 1; + else + num_entry = cfs_num_possible_cpus() + 1; - if (flags & LPROCFS_STATS_FLAG_NOPERCPU) { - stats->ls_flags = flags; - cfs_spin_lock_init(&stats->ls_lock); - /* Use this lock only if there are no percpu areas */ - } else { - stats->ls_flags = 0; - } + /* alloc percpu pointers for all possible cpu slots */ + OBD_ALLOC(stats, offsetof(struct lprocfs_stats, ls_percpu[num_entry])); + if (stats == NULL) + return NULL; - percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]); - if (num_cpu > 1) - percpusize = CFS_L1_CACHE_ALIGN(percpusize); + stats->ls_num = num; + stats->ls_biggest_alloc_num = 1; + stats->ls_flags = flags; + cfs_spin_lock_init(&stats->ls_lock); - 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])); - return NULL; - } + percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]); + if (num_entry > 1) + percpusize = CFS_L1_CACHE_ALIGN(percpusize); - stats->ls_num = num; - return stats; + /* for no percpu area, the 0th entry is for real use, + * for percpu area, the 0th entry is for intialized entry template */ + OBD_ALLOC(stats->ls_percpu[0], percpusize); + if (stats->ls_percpu[0] == NULL) { + OBD_FREE(stats, + offsetof(struct lprocfs_stats, ls_percpu[num_entry])); + stats = NULL; + } + return stats; } void lprocfs_free_stats(struct lprocfs_stats **statsh) { - struct lprocfs_stats *stats = *statsh; - unsigned int num_cpu; - unsigned int percpusize; - unsigned int i; + struct lprocfs_stats *stats = *statsh; + unsigned int num_entry; + unsigned int percpusize; + unsigned int i; if (stats == NULL || stats->ls_num == 0) return; *statsh = NULL; - if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) - num_cpu = 1; - else - num_cpu = cfs_num_possible_cpus(); + if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) + num_entry = 1; + else + num_entry = cfs_num_possible_cpus() + 1; - percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]); - if (num_cpu > 1) - percpusize = CFS_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])); + percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]); + if (num_entry > 1) + percpusize = CFS_L1_CACHE_ALIGN(percpusize); + for (i = 0; i < num_entry; i++) + if (stats->ls_percpu[i] != NULL) + OBD_FREE(stats->ls_percpu[i], percpusize); + OBD_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry])); } void lprocfs_clear_stats(struct lprocfs_stats *stats) { - struct lprocfs_counter *percpu_cntr; - int i,j; - unsigned int num_cpu; - - num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU); - - for (i = 0; i < num_cpu; i++) { - for (j = 0; j < stats->ls_num; j++) { - percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j]; - cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry); - percpu_cntr->lc_count = 0; - percpu_cntr->lc_sum = 0; - percpu_cntr->lc_min = LC_MIN_INIT; - percpu_cntr->lc_max = 0; - percpu_cntr->lc_sumsquare = 0; - cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit); - } - } + struct lprocfs_counter *percpu_cntr; + int i; + int j; + unsigned int num_entry; + unsigned long flags = 0; + + num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); - lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU); + for (i = 0; i < num_entry; i++) { + if (stats->ls_percpu[i] == NULL) + continue; + for (j = 0; j < stats->ls_num; j++) { + percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[j]; + cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry); + percpu_cntr->lc_count = 0; + percpu_cntr->lc_sum = 0; + percpu_cntr->lc_min = LC_MIN_INIT; + percpu_cntr->lc_max = 0; + percpu_cntr->lc_sumsquare = 0; + cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit); + } + } + + lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); } static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf, @@ -1422,28 +1419,23 @@ int lprocfs_register_stats(struct proc_dir_entry *root, const char *name, } void lprocfs_counter_init(struct lprocfs_stats *stats, int index, - unsigned conf, const char *name, const char *units) -{ - struct lprocfs_counter *c; - int i; - unsigned int num_cpu; - - LASSERT(stats != NULL); - - num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU); - - for (i = 0; i < num_cpu; i++) { - c = &(stats->ls_percpu[i]->lp_cntr[index]); - c->lc_config = conf; - c->lc_count = 0; - c->lc_sum = 0; - c->lc_min = LC_MIN_INIT; - c->lc_max = 0; - c->lc_name = name; - c->lc_units = units; - } - - lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU); + unsigned conf, const char *name, const char *units) +{ + struct lprocfs_counter *c = &(stats->ls_percpu[0]->lp_cntr[index]); + unsigned long flags = 0; + + LASSERT(stats != NULL); + LASSERT(stats->ls_percpu[0] != NULL); + + lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); + c->lc_config = conf; + c->lc_count = 0; + c->lc_sum = 0; + c->lc_min = LC_MIN_INIT; + c->lc_max = 0; + c->lc_name = name; + c->lc_units = units; + lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); } EXPORT_SYMBOL(lprocfs_counter_init); diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 5e77e9a..1541a12 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -2391,18 +2391,18 @@ static int ost_setup(struct obd_device *obd, struct lustre_cfg* lcfg) if (oss_num_threads < OSS_THREADS_MIN) oss_num_threads = OSS_THREADS_MIN; oss_max_threads = oss_min_threads = oss_num_threads; - } else { - /* Base min threads on memory and cpus */ - oss_min_threads = - cfs_num_possible_cpus() * CFS_NUM_CACHEPAGES >> - (27 - CFS_PAGE_SHIFT); - if (oss_min_threads < OSS_THREADS_MIN) - oss_min_threads = OSS_THREADS_MIN; - /* Insure a 4x range for dynamic threads */ - if (oss_min_threads > OSS_THREADS_MAX / 4) - oss_min_threads = OSS_THREADS_MAX / 4; - oss_max_threads = min(OSS_THREADS_MAX, oss_min_threads * 4 + 1); - } + } else { + /* Base min threads on memory and cpus */ + oss_min_threads = + cfs_num_online_cpus() * CFS_NUM_CACHEPAGES >> + (27 - CFS_PAGE_SHIFT); + if (oss_min_threads < OSS_THREADS_MIN) + oss_min_threads = OSS_THREADS_MIN; + /* Insure a 4x range for dynamic threads */ + if (oss_min_threads > OSS_THREADS_MAX / 4) + oss_min_threads = OSS_THREADS_MAX / 4; + oss_max_threads = min(OSS_THREADS_MAX, oss_min_threads * 4 + 1); + } ost->ost_service = ptlrpc_init_svc(OST_NBUFS, OST_BUFSIZE, OST_MAXREQSIZE,