Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / include / lprocfs_status.h
index f9aaac7..44d1a2a 100644 (file)
@@ -44,6 +44,7 @@ struct lprocfs_vars {
         cfs_read_proc_t *read_fptr;
         cfs_write_proc_t *write_fptr;
         void *data;
+        struct file_operations *fops;
 };
 
 struct lprocfs_static_vars {
@@ -135,10 +136,20 @@ struct lprocfs_percpu {
         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];
 };
 
@@ -152,6 +163,31 @@ struct obd_histogram;
 
 #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
@@ -163,10 +199,16 @@ static inline void lprocfs_counter_add(struct lprocfs_stats *stats, int idx,
                                        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++;
 
@@ -180,21 +222,28 @@ static inline void lprocfs_counter_add(struct lprocfs_stats *stats, int idx,
                         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, 
@@ -241,6 +290,7 @@ extern cfs_proc_dir_entry_t *lprocfs_srch(cfs_proc_dir_entry_t *root,
 
 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,
@@ -254,7 +304,13 @@ extern int lprocfs_obd_seq_create(struct obd_device *dev, char *name,
 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,
@@ -389,7 +445,8 @@ static inline void lprocfs_counter_init(struct lprocfs_stats *stats,
                                         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; }