From 69c86c54469a3fb7d62850a1a85c3b93bf529bf3 Mon Sep 17 00:00:00 2001 From: Dmitry Zogin Date: Tue, 2 Mar 2010 08:58:41 -0500 Subject: [PATCH] b=19873 sanity: Memory leaks detected, FAILed to clean up Patch backport from bz 20650, attachment 26416 - introduce lprocfs counter on IRQs The lc_sum_irq counter is used to calculate memory freed on the interrupt. i=adilger i=andrew.perepechko --- lustre/include/lprocfs_status.h | 1 + lustre/lvfs/lvfs_lib.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 6727305..454ba17 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -150,6 +150,7 @@ struct lprocfs_counter { unsigned int lc_config; __s64 lc_count; __s64 lc_sum; + __s64 lc_sum_irq; __s64 lc_min; __s64 lc_max; __s64 lc_sumsquare; diff --git a/lustre/lvfs/lvfs_lib.c b/lustre/lvfs/lvfs_lib.c index dde2c34..2c4be88 100644 --- a/lustre/lvfs/lvfs_lib.c +++ b/lustre/lvfs/lvfs_lib.c @@ -147,7 +147,7 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc, ret = lc->lc_config; break; case LPROCFS_FIELDS_FLAGS_SUM: - ret = lc->lc_sum; + ret = lc->lc_sum + lc->lc_sum_irq; break; case LPROCFS_FIELDS_FLAGS_MIN: ret = lc->lc_min; @@ -192,6 +192,9 @@ void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, percpu_cntr->lc_count++; if (percpu_cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) { + /* see comment in lprocfs_counter_sub */ + LASSERT(!cfs_in_interrupt()); + percpu_cntr->lc_sum += amount; if (percpu_cntr->lc_config & LPROCFS_CNTR_STDDEV) percpu_cntr->lc_sumsquare += (__u64)amount * amount; @@ -220,8 +223,20 @@ void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]); atomic_inc(&percpu_cntr->lc_cntl.la_entry); - if (percpu_cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) - percpu_cntr->lc_sum -= amount; + if (percpu_cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) { + /* + * currently lprocfs_count_add() can only be called in thread + * context; sometimes we use RCU callbacks to free memory + * which calls lprocfs_counter_sub(), and RCU callbacks may + * execute in softirq context - right now that's the only case + * we're in softirq context here, use separate counter for that. + * bz20650. + */ + if (cfs_in_interrupt()) + percpu_cntr->lc_sum_irq -= amount; + else + percpu_cntr->lc_sum -= amount; + } atomic_inc(&percpu_cntr->lc_cntl.la_exit); lprocfs_stats_unlock(stats); } -- 1.8.3.1