Eliminate unnecessary atomic operations in lprocfs_counter.
o=liang
i=andreas.dilger
i=maxim.patlasov
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_GET_SMP_ID = 0x0002, /* just record locking with
- * LPROCFS_GET_SMP_ID flag */
};
enum lprocfs_fields_flags {
};
enum lprocfs_fields_flags {
-static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int type)
+static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc)
- int rc = 0;
-
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
- if (type & LPROCFS_GET_NUM_CPU)
- rc = 1;
- if (type & LPROCFS_GET_SMP_ID)
- rc = 0;
- cfs_spin_lock(&stats->ls_lock);
- } else {
- if (type & LPROCFS_GET_NUM_CPU)
- rc = cfs_num_possible_cpus();
- if (type & LPROCFS_GET_SMP_ID) {
- stats->ls_flags |= LPROCFS_STATS_GET_SMP_ID;
- rc = cfs_get_cpu();
+ 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();
-static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats)
+static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc)
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
- cfs_spin_unlock(&stats->ls_lock);
- else if (stats->ls_flags & LPROCFS_STATS_GET_SMP_ID)
- cfs_put_cpu();
+ 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;
+ }
}
/* Two optimized LPROCFS counter increment functions are provided:
}
/* Two optimized LPROCFS counter increment functions are provided:
int index, long amount) { return; }
static inline void lprocfs_counter_incr(struct lprocfs_stats *stats,
int index) { return; }
int index, long amount) { return; }
static inline void lprocfs_counter_incr(struct lprocfs_stats *stats,
int index) { return; }
+static inline void lprocfs_counter_decr(struct lprocfs_stats *stats,
+ int index) { return; }
static inline void lprocfs_counter_sub(struct lprocfs_stats *stats,
int index, long amount) { return; }
static inline void lprocfs_counter_init(struct lprocfs_stats *stats,
static inline void lprocfs_counter_sub(struct lprocfs_stats *stats,
int index, long amount) { return; }
static inline void lprocfs_counter_init(struct lprocfs_stats *stats,
smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID);
percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]);
smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID);
percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]);
- cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
+ 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) {
percpu_cntr->lc_count++;
if (percpu_cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) {
if (amount > percpu_cntr->lc_max)
percpu_cntr->lc_max = amount;
}
if (amount > percpu_cntr->lc_max)
percpu_cntr->lc_max = amount;
}
- cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
- lprocfs_stats_unlock(stats);
+ 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);
}
EXPORT_SYMBOL(lprocfs_counter_add);
}
EXPORT_SYMBOL(lprocfs_counter_add);
smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID);
percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]);
smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID);
percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]);
- cfs_atomic_inc(&percpu_cntr->lc_cntl.la_entry);
+ 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) {
/*
* currently lprocfs_count_add() can only be called in thread
if (percpu_cntr->lc_config & LPROCFS_CNTR_AVGMINMAX) {
/*
* currently lprocfs_count_add() can only be called in thread
else
percpu_cntr->lc_sum -= amount;
}
else
percpu_cntr->lc_sum -= amount;
}
- cfs_atomic_inc(&percpu_cntr->lc_cntl.la_exit);
- lprocfs_stats_unlock(stats);
+ 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);
}
EXPORT_SYMBOL(lprocfs_counter_sub);
#endif /* LPROCFS */
}
EXPORT_SYMBOL(lprocfs_counter_sub);
#endif /* LPROCFS */
cnt->lc_min = LC_MIN_INIT;
cnt->lc_min = LC_MIN_INIT;
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
- num_cpu = 1;
- else
- num_cpu = cfs_num_possible_cpus();
+ num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU);
for (i = 0; i < num_cpu; i++) {
percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
for (i = 0; i < num_cpu; i++) {
percpu_cntr = &(stats->ls_percpu[i])->lp_cntr[idx];
}
cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
}
cnt->lc_units = stats->ls_percpu[0]->lp_cntr[idx].lc_units;
+ lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
- lprocfs_stats_unlock(stats);
+ lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
}
static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
}
static ssize_t lprocfs_stats_seq_write(struct file *file, const char *buf,
- lprocfs_stats_unlock(stats);
+ lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU);
}
EXPORT_SYMBOL(lprocfs_counter_init);
}
EXPORT_SYMBOL(lprocfs_counter_init);