From 9219ce0081c665ec42a83ee10fb44cf1ace5e932 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Mon, 5 Nov 2012 13:18:52 -0800 Subject: [PATCH] LU-744 obdclass: revise percpu stats of lprocfs_stats Atomic doesn't scale well and there is an atomic counter to remember if updating stats is on going. This will introduce performance problem if the percpu stats is used in a highly contended code. I'll remove that atomic counter in this patch, this is okay as percpu counter is not accurate essentially. Signed-off-by: Jinshan Xiong Change-Id: I5c7a094b78ab53798266d48d56f3a16e7c7d436f Reviewed-on: http://review.whamcloud.com/4472 Tested-by: Hudson Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Bobi Jam --- lustre/include/lprocfs_status.h | 6 ---- lustre/lvfs/lvfs_lib.c | 9 ------ lustre/lvfs/lvfs_linux.c | 69 +++++++++++++++++++--------------------- lustre/obdclass/lprocfs_status.c | 52 +++++++++++------------------- 4 files changed, 50 insertions(+), 86 deletions(-) diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 08658d8..354f9eb 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -144,15 +144,9 @@ enum { LPROCFS_TYPE_CYCLE = 0x0800, }; -struct lprocfs_atomic { - cfs_atomic_t la_entry; - cfs_atomic_t la_exit; -}; - #define LC_MIN_INIT ((~(__u64)0) >> 1) struct lprocfs_counter { - struct lprocfs_atomic lc_cntl; /* may need to move to per set */ unsigned int lc_config; __s64 lc_count; __s64 lc_sum; diff --git a/lustre/lvfs/lvfs_lib.c b/lustre/lvfs/lvfs_lib.c index 19c597c..7079026 100644 --- a/lustre/lvfs/lvfs_lib.c +++ b/lustre/lvfs/lvfs_lib.c @@ -86,10 +86,7 @@ void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, return; percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]); - if (!(stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)) - cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry); percpu_cntr->lc_count++; - if (percpu_cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) { /* * lprocfs_counter_add() can be called in interrupt context, @@ -108,8 +105,6 @@ void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, if (amount > percpu_cntr->lc_max) percpu_cntr->lc_max = amount; } - 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, &flags); } EXPORT_SYMBOL(lprocfs_counter_add); @@ -130,8 +125,6 @@ void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, long amount) return; percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]); - if (!(stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)) - cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry); if (percpu_cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) { /* * Sometimes we use RCU callbacks to free memory which calls @@ -145,8 +138,6 @@ void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, long amount) else percpu_cntr->lc_sum -= amount; } - 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, &flags); } EXPORT_SYMBOL(lprocfs_counter_sub); diff --git a/lustre/lvfs/lvfs_linux.c b/lustre/lvfs/lvfs_linux.c index 5f1274c..a864be4 100644 --- a/lustre/lvfs/lvfs_linux.c +++ b/lustre/lvfs/lvfs_linux.c @@ -585,43 +585,38 @@ EXPORT_SYMBOL(obd_pages_max); __s64 lprocfs_read_helper(struct lprocfs_counter *lc, enum lprocfs_fields_flags field) { - __s64 ret = 0; - int centry; - - if (!lc) - RETURN(0); - do { - centry = cfs_atomic_read(&lc->lc_cntl.la_entry); - - switch (field) { - case LPROCFS_FIELDS_FLAGS_CONFIG: - ret = lc->lc_config; - break; - case LPROCFS_FIELDS_FLAGS_SUM: - ret = lc->lc_sum + lc->lc_sum_irq; - break; - case LPROCFS_FIELDS_FLAGS_MIN: - ret = lc->lc_min; - break; - case LPROCFS_FIELDS_FLAGS_MAX: - ret = lc->lc_max; - break; - case LPROCFS_FIELDS_FLAGS_AVG: - ret = (lc->lc_max - lc->lc_min)/2; - break; - case LPROCFS_FIELDS_FLAGS_SUMSQUARE: - ret = lc->lc_sumsquare; - break; - case LPROCFS_FIELDS_FLAGS_COUNT: - ret = lc->lc_count; - break; - default: - break; - }; - } while (centry != cfs_atomic_read(&lc->lc_cntl.la_entry) && - centry != cfs_atomic_read(&lc->lc_cntl.la_exit)); - - RETURN(ret); + __s64 ret = 0; + + if (lc == NULL) + RETURN(0); + + switch (field) { + case LPROCFS_FIELDS_FLAGS_CONFIG: + ret = lc->lc_config; + break; + case LPROCFS_FIELDS_FLAGS_SUM: + ret = lc->lc_sum + lc->lc_sum_irq; + break; + case LPROCFS_FIELDS_FLAGS_MIN: + ret = lc->lc_min; + break; + case LPROCFS_FIELDS_FLAGS_MAX: + ret = lc->lc_max; + break; + case LPROCFS_FIELDS_FLAGS_AVG: + ret = (lc->lc_max - lc->lc_min) / 2; + break; + case LPROCFS_FIELDS_FLAGS_SUMSQUARE: + ret = lc->lc_sumsquare; + break; + case LPROCFS_FIELDS_FLAGS_COUNT: + ret = lc->lc_count; + break; + default: + break; + }; + + RETURN(ret); } EXPORT_SYMBOL(lprocfs_read_helper); #endif /* LPROCFS */ diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index ba166e3..9a78fe4 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -876,50 +876,36 @@ EXPORT_SYMBOL(lprocfs_rd_conn_uuid); void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, struct lprocfs_counter *cnt) { + struct lprocfs_counter *ptr; 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)); + memset(cnt, 0, sizeof(*cnt)); - if (stats == NULL) { - /* set count to 1 to avoid divide-by-zero errs in callers */ - cnt->lc_count = 1; - return; - } + if (stats == NULL) { + /* set count to 1 to avoid divide-by-zero errs in callers */ + cnt->lc_count = 1; + return; + } - cnt->lc_min = LC_MIN_INIT; + cnt->lc_min = LC_MIN_INIT; num_entry = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags); 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-> \ - lc_cntl.la_entry); - t.lc_count = percpu_cntr->lc_count; - t.lc_sum = percpu_cntr->lc_sum; - t.lc_min = percpu_cntr->lc_min; - t.lc_max = percpu_cntr->lc_max; - t.lc_sumsquare = percpu_cntr->lc_sumsquare; - } while (centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \ - la_entry) && - centry != cfs_atomic_read(&percpu_cntr->lc_cntl. \ - la_exit)); - cnt->lc_count += t.lc_count; - cnt->lc_sum += t.lc_sum; - if (t.lc_min < cnt->lc_min) - cnt->lc_min = t.lc_min; - if (t.lc_max > cnt->lc_max) - cnt->lc_max = t.lc_max; - cnt->lc_sumsquare += t.lc_sumsquare; - } + + ptr = &(stats->ls_percpu[i])->lp_cntr[idx]; + cnt->lc_count += ptr->lc_count; + cnt->lc_sum += ptr->lc_sum; + if (ptr->lc_min < cnt->lc_min) + cnt->lc_min = ptr->lc_min; + if (ptr->lc_max > cnt->lc_max) + cnt->lc_max = ptr->lc_max; + cnt->lc_sumsquare += ptr->lc_sumsquare; + } cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units; lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags); @@ -1464,13 +1450,11 @@ void lprocfs_clear_stats(struct lprocfs_stats *stats) 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); } } -- 1.8.3.1