Whamcloud - gitweb
LU-1282 misc: Use present cpu numbers to save memory.
authorBobi Jam <bobijam@whamcloud.com>
Thu, 5 Apr 2012 06:25:40 +0000 (14:25 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 30 May 2012 21:41:02 +0000 (17:41 -0400)
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.

OSS minimum thread number also better be decided by online cpu
number.

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: Id1690f185f4f83fae75be7eddb756e413cbc4fba
Reviewed-on: http://review.whamcloud.com/2451
Tested-by: Hudson
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/include/libcfs/linux/kp30.h
libcfs/include/libcfs/user-prim.h
libcfs/include/libcfs/winnt/winnt-prim.h
libcfs/libcfs/linux/linux-tracefile.c
lustre/include/lprocfs_status.h
lustre/lvfs/lvfs_lib.c
lustre/obdclass/lprocfs_status.c
lustre/ost/ost_handler.c

index 7400039..ce77cec 100644 (file)
@@ -161,11 +161,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
index b65148a..baad28a 100644 (file)
@@ -57,21 +57,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.
  */
index cd98a23..988e9b5 100644 (file)
@@ -860,6 +860,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)
index 7352e14..411178c 100644 (file)
@@ -61,8 +61,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;
 
@@ -76,11 +76,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;
@@ -92,7 +92,6 @@ out:
        cfs_tracefile_fini_arch();
        printk(KERN_ERR "lnet: Not enough memory\n");
        return -ENOMEM;
-
 }
 
 void cfs_tracefile_fini_arch()
@@ -100,7 +99,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]);
index 97336f8..3844583 100644 (file)
@@ -165,8 +165,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];
 };
@@ -191,11 +191,15 @@ 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_* */
+       cfs_spinlock_t         ls_lock;  /* Lock used only when there are
+                                         * no percpu stats areas */
+       struct lprocfs_percpu *ls_percpu[0];
 };
 
 #define OPC_RANGE(seg) (seg ## _LAST_OPC - seg ## _FIRST_OPC)
@@ -368,48 +372,62 @@ struct obd_job_stats {
 
 #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;
+
+       switch (opc) {
+       default:
+               LBUG();
+
+       case LPROCFS_GET_SMP_ID:
+               if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+                       cfs_spin_lock_irqsave(&stats->ls_lock, *flags);
+                       return 0;
+               } else {
+                       unsigned int 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;
+               }
+
+       case LPROCFS_GET_NUM_CPU:
+               if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+                       cfs_spin_lock_irqsave(&stats->ls_lock, *flags);
+                       return 1;
+               } else {
+                       return stats->ls_biggest_alloc_num;
+               }
+       }
 }
 
-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)
+                       cfs_spin_unlock_irqrestore(&stats->ls_lock, *flags);
+               else
+                       cfs_put_cpu();
+               return;
+
+       case LPROCFS_GET_NUM_CPU:
+               if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
+                       cfs_spin_unlock_irqrestore(&stats->ls_lock, *flags);
+               return;
+       }
 }
 
 /* Two optimized LPROCFS counter increment functions are provided:
@@ -435,18 +453,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 *
index 4a1a999..ffdfadf 100644 (file)
@@ -72,15 +72,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))
@@ -101,22 +104,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))
@@ -137,9 +142,38 @@ 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;
+
+       /* 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))
+                       stats->ls_biggest_alloc_num = idx + 1;
+
+               /* 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);
index d3816a9..765d017 100644 (file)
@@ -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);
 }
 
 /**
@@ -1192,10 +1196,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;
@@ -1203,15 +1206,18 @@ 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();
+       if (flags & LPROCFS_STATS_FLAG_NOPERCPU)
+               num_entry = 1;
+       else
+               num_entry = cfs_num_possible_cpus() + 1;
 
-        OBD_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_cpu]));
-        if (stats == NULL)
-                return NULL;
+       /* alloc percpu pointers for all possible cpu slots */
+       OBD_ALLOC(stats, offsetof(struct lprocfs_stats, ls_percpu[num_entry]));
+       if (stats == NULL)
+               return NULL;
 
+       stats->ls_num = num;
+       stats->ls_biggest_alloc_num = 1;
         if (flags & LPROCFS_STATS_FLAG_NOPERCPU) {
                 stats->ls_flags = flags;
                 cfs_spin_lock_init(&stats->ls_lock);
@@ -1220,63 +1226,59 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
                 stats->ls_flags = 0;
         }
 
-        percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
-        if (num_cpu > 1)
-                percpusize = CFS_L1_CACHE_ALIGN(percpusize);
+       percpusize = offsetof(struct lprocfs_percpu, lp_cntr[num]);
+       if (num_entry > 1)
+               percpusize = CFS_L1_CACHE_ALIGN(percpusize);
 
-        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;
-        }
-
-        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;
+       struct lprocfs_counter *percpu_cntr;
+       int                     i;
+       int                     j;
+       unsigned int            num_entry;
+       unsigned long           flags = 0;
 
-        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++) {
+       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);
@@ -1289,7 +1291,7 @@ void lprocfs_clear_stats(struct lprocfs_stats *stats)
                 }
         }
 
-        lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
+       lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
 }
 
 static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
@@ -1424,28 +1426,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);
 
index 03b5303..520d1af 100644 (file)
@@ -2423,18 +2423,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,