cfs_read_proc_t *read_fptr;
cfs_write_proc_t *write_fptr;
void *data;
+ struct file_operations *fops;
};
struct lprocfs_static_vars {
struct lprocfs_counter lp_cntr[0];
};
+#define LPROCFS_GET_NUM_CPU 0x0001
+#define LPROCFS_GET_SMP_ID 0x0002
+
+enum lprocfs_stats_flags {
+ LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu
+ * area and need locking */
+};
struct lprocfs_stats {
unsigned int ls_num; /* # of counters */
unsigned int ls_percpu_size;
+ int ls_flags; /* See LPROCFS_STATS_FLAG_* */
+ spinlock_t ls_lock; /* Lock used only when there are
+ * no percpu stats areas */
struct lprocfs_percpu *ls_percpu[0];
};
#ifdef LPROCFS
+static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int type)
+{
+ 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;
+ spin_lock(&stats->ls_lock);
+ } else {
+ if (type & LPROCFS_GET_NUM_CPU)
+ rc = num_possible_cpus();
+ if (type & LPROCFS_GET_SMP_ID)
+ rc = smp_processor_id();
+ }
+ return rc;
+}
+
+static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats)
+{
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU)
+ spin_unlock(&stats->ls_lock);
+}
+
/* Two optimized LPROCFS counter increment functions are provided:
* lprocfs_counter_incr(cntr, value) - optimized for by-one counters
* lprocfs_counter_add(cntr) - use for multi-valued counters
long amount)
{
struct lprocfs_counter *percpu_cntr;
+ int smp_id;
if (stats == NULL)
return;
- percpu_cntr = &(stats->ls_percpu[smp_processor_id()]->lp_cntr[idx]);
+
+ /* 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);
+
+ percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]);
atomic_inc(&percpu_cntr->lc_cntl.la_entry);
percpu_cntr->lc_count++;
percpu_cntr->lc_max = amount;
}
atomic_inc(&percpu_cntr->lc_cntl.la_exit);
+ lprocfs_stats_unlock(stats);
}
static inline void lprocfs_counter_incr(struct lprocfs_stats *stats, int idx)
{
struct lprocfs_counter *percpu_cntr;
+ int smp_id;
if (stats == NULL)
return;
- percpu_cntr = &(stats->ls_percpu[smp_processor_id()]->lp_cntr[idx]);
+
+ smp_id = lprocfs_stats_lock(stats, LPROCFS_GET_SMP_ID);
+ percpu_cntr = &(stats->ls_percpu[smp_id]->lp_cntr[idx]);
+
atomic_inc(&percpu_cntr->lc_cntl.la_entry);
percpu_cntr->lc_count++;
atomic_inc(&percpu_cntr->lc_cntl.la_exit);
+ lprocfs_stats_unlock(stats);
}
-extern struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num);
+extern struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
+ enum lprocfs_stats_flags flags);
extern void lprocfs_clear_stats(struct lprocfs_stats *stats);
extern void lprocfs_free_stats(struct lprocfs_stats **stats);
extern void lprocfs_init_ops_stats(int num_private_stats,
extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list);
extern int lprocfs_obd_cleanup(struct obd_device *obd);
+extern struct file_operations lprocfs_evict_client_fops;
extern int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name,
mode_t mode, struct file_operations *seq_fops,
extern int lprocfs_rd_u64(char *page, char **start, off_t off,
int count, int *eof, void *data);
extern int lprocfs_rd_atomic(char *page, char **start, off_t off,
- int count, int *eof, void *data);
+ int count, int *eof, void *data);
+extern int lprocfs_wr_atomic(struct file *file, const char *buffer,
+ unsigned long count, void *data);
+extern int lprocfs_rd_uint(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+extern int lprocfs_wr_uint(struct file *file, const char *buffer,
+ unsigned long count, void *data);
extern int lprocfs_rd_uuid(char *page, char **start, off_t off,
int count, int *eof, void *data);
extern int lprocfs_rd_name(char *page, char **start, off_t off,
const char *name, const char *units)
{ return; }
-static inline struct lprocfs_stats* lprocfs_alloc_stats(unsigned int num)
+static inline struct lprocfs_stats* lprocfs_alloc_stats(unsigned int num,
+ int client_stat)
{ return NULL; }
static inline void lprocfs_clear_stats(struct lprocfs_stats *stats)
{ return; }