Whamcloud - gitweb
LU-5275 lprocfs: reduce scope of params_tree.h
[fs/lustre-release.git] / lustre / include / lprocfs_status.h
index edb85d4..beb0413 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2014, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #include <lustre/lustre_idl.h>
 #include <libcfs/params_tree.h>
 
+#ifndef HAVE_ONLY_PROCFS_SEQ
 struct lprocfs_vars {
        const char                      *name;
+       read_proc_t                     *read_fptr;
+       write_proc_t                    *write_fptr;
+       void                            *data;
+       const struct file_operations    *fops;
+       /**
+        * /proc file mode.
+        */
+       mode_t                          proc_mode;
+};
+
+struct lprocfs_static_vars {
+       struct lprocfs_vars *module_vars;
+       struct lprocfs_vars *obd_vars;
+};
+
+#endif
+
+struct lprocfs_seq_vars {
+       const char                      *name;
        const struct file_operations    *fops;
        void                            *data;
        /**
@@ -153,11 +173,13 @@ struct lprocfs_counter {
 #define lc_sum_irq     lc_array_sum[1]
 
 struct lprocfs_percpu {
-        struct lprocfs_counter lp_cntr[0];
+       struct lprocfs_counter lp_cntr[0];
 };
 
-#define LPROCFS_GET_NUM_CPU 0x0001
-#define LPROCFS_GET_SMP_ID  0x0002
+enum lprocfs_stats_lock_ops {
+       LPROCFS_GET_NUM_CPU     = 0x0001, /* number allocated per-CPU stats */
+       LPROCFS_GET_SMP_ID      = 0x0002, /* current stat to be updated */
+};
 
 enum lprocfs_stats_flags {
        LPROCFS_STATS_FLAG_NONE     = 0x0000, /* per cpu counter */
@@ -167,13 +189,13 @@ enum lprocfs_stats_flags {
 };
 
 enum lprocfs_fields_flags {
-        LPROCFS_FIELDS_FLAGS_CONFIG     = 0x0001,
-        LPROCFS_FIELDS_FLAGS_SUM        = 0x0002,
-        LPROCFS_FIELDS_FLAGS_MIN        = 0x0003,
-        LPROCFS_FIELDS_FLAGS_MAX        = 0x0004,
-        LPROCFS_FIELDS_FLAGS_AVG        = 0x0005,
-        LPROCFS_FIELDS_FLAGS_SUMSQUARE  = 0x0006,
-        LPROCFS_FIELDS_FLAGS_COUNT      = 0x0007,
+       LPROCFS_FIELDS_FLAGS_CONFIG     = 0x0001,
+       LPROCFS_FIELDS_FLAGS_SUM        = 0x0002,
+       LPROCFS_FIELDS_FLAGS_MIN        = 0x0003,
+       LPROCFS_FIELDS_FLAGS_MAX        = 0x0004,
+       LPROCFS_FIELDS_FLAGS_AVG        = 0x0005,
+       LPROCFS_FIELDS_FLAGS_SUMSQUARE  = 0x0006,
+       LPROCFS_FIELDS_FLAGS_COUNT      = 0x0007,
 };
 
 struct lprocfs_stats {
@@ -391,83 +413,91 @@ struct obd_job_stats {
 #ifdef LPROCFS
 
 extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats,
-                                   unsigned int cpuid);
-/*
- * \return value
- *      < 0     : on error (only possible for opc as LPROCFS_GET_SMP_ID)
+                                  unsigned int cpuid);
+
+/**
+ * Lock statistics structure for access, possibly only on this CPU.
+ *
+ * The statistics struct may be allocated with per-CPU structures for
+ * efficient concurrent update (usually only on server-wide stats), or
+ * as a single global struct (e.g. for per-client or per-job statistics),
+ * so the required locking depends on the type of structure allocated.
+ *
+ * For per-CPU statistics, pin the thread to the current cpuid so that
+ * will only access the statistics for that CPU.  If the stats structure
+ * for the current CPU has not been allocated (or previously freed),
+ * allocate it now.  The per-CPU statistics do not need locking since
+ * the thread is pinned to the CPU during update.
+ *
+ * For global statistics, lock the stats structure to prevent concurrent update.
+ *
+ * \param[in] stats    statistics structure to lock
+ * \param[in] opc      type of operation:
+ *                     LPROCFS_GET_SMP_ID: "lock" and return current CPU index
+ *                             for incrementing statistics for that CPU
+ *                     LPROCFS_GET_NUM_CPU: "lock" and return number of used
+ *                             CPU indices to iterate over all indices
+ * \param[out] flags   CPU interrupt saved state for IRQ-safe locking
+ *
+ * \retval cpuid of current thread or number of allocated structs
+ * \retval negative on error (only for opc LPROCFS_GET_SMP_ID + per-CPU stats)
  */
-static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc,
+static inline int lprocfs_stats_lock(struct lprocfs_stats *stats,
+                                    enum lprocfs_stats_lock_ops opc,
                                     unsigned long *flags)
 {
-       int             rc = 0;
+       if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+               if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
+                       spin_lock_irqsave(&stats->ls_lock, *flags);
+               else
+                       spin_lock(&stats->ls_lock);
+               return opc == LPROCFS_GET_NUM_CPU ? 1 : 0;
+       }
 
        switch (opc) {
-       default:
-               LBUG();
-
-       case LPROCFS_GET_SMP_ID:
-               if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
-                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
-                               spin_lock_irqsave(&stats->ls_lock, *flags);
-                       else
-                               spin_lock(&stats->ls_lock);
-                       return 0;
-               } else {
-                       unsigned int cpuid = get_cpu();
-
-                       if (unlikely(stats->ls_percpu[cpuid] == NULL)) {
-                               rc = lprocfs_stats_alloc_one(stats, cpuid);
-                               if (rc < 0) {
-                                       put_cpu();
-                                       return rc;
-                               }
+       case LPROCFS_GET_SMP_ID: {
+               unsigned int cpuid = get_cpu();
+
+               if (unlikely(stats->ls_percpu[cpuid] == NULL)) {
+                       int rc = lprocfs_stats_alloc_one(stats, cpuid);
+                       if (rc < 0) {
+                               put_cpu();
+                               return rc;
                        }
-                       return cpuid;
                }
-
+               return cpuid;
+       }
        case LPROCFS_GET_NUM_CPU:
-               if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
-                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
-                               spin_lock_irqsave(&stats->ls_lock, *flags);
-                       else
-                               spin_lock(&stats->ls_lock);
-                       return 1;
-               } else {
-                       return stats->ls_biggest_alloc_num;
-               }
+               return stats->ls_biggest_alloc_num;
+       default:
+               LBUG();
        }
 }
 
-static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc,
+/**
+ * Unlock statistics structure after access.
+ *
+ * Unlock the lock acquired via lprocfs_stats_lock() for global statistics,
+ * or unpin this thread from the current cpuid for per-CPU statistics.
+ *
+ * This function must be called using the same arguments as used when calling
+ * lprocfs_stats_lock() so that the correct operation can be performed.
+ *
+ * \param[in] stats    statistics structure to unlock
+ * \param[in] opc      type of operation (current cpuid or number of structs)
+ * \param[in] flags    CPU interrupt saved state for IRQ-safe locking
+ */
+static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats,
+                                       enum lprocfs_stats_lock_ops opc,
                                        unsigned long *flags)
 {
-       switch (opc) {
-       default:
-               LBUG();
-
-       case LPROCFS_GET_SMP_ID:
-               if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
-                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
-                               spin_unlock_irqrestore(&stats->ls_lock,
-                                                          *flags);
-                       } else {
-                               spin_unlock(&stats->ls_lock);
-                       }
-               } else {
-                       put_cpu();
-               }
-               return;
-
-       case LPROCFS_GET_NUM_CPU:
-               if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
-                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
-                               spin_unlock_irqrestore(&stats->ls_lock,
-                                                          *flags);
-                       } else {
-                               spin_unlock(&stats->ls_lock);
-                       }
-               }
-               return;
+       if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+               if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
+                       spin_unlock_irqrestore(&stats->ls_lock, *flags);
+               else
+                       spin_unlock(&stats->ls_lock);
+       } else if (opc == LPROCFS_GET_SMP_ID) {
+               put_cpu();
        }
 }
 
@@ -570,8 +600,7 @@ struct nid_stat;
 extern int lprocfs_add_clear_entry(struct obd_device * obd,
                                   struct proc_dir_entry *entry);
 #ifdef HAVE_SERVER_SUPPORT
-extern int lprocfs_exp_setup(struct obd_export *exp,
-                             lnet_nid_t *peer_nid, int *newnid);
+extern int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *peer_nid);
 extern int lprocfs_exp_cleanup(struct obd_export *exp);
 #else
 static inline int lprocfs_exp_cleanup(struct obd_export *exp)
@@ -594,17 +623,32 @@ extern int lprocfs_register_stats(struct proc_dir_entry *root, const char *name,
                                   struct lprocfs_stats *stats);
 
 /* lprocfs_status.c */
+#ifndef HAVE_ONLY_PROCFS_SEQ
 extern int lprocfs_add_vars(struct proc_dir_entry *root,
-                           struct lprocfs_vars *var, void *data);
+                            struct lprocfs_vars *var,
+                            void *data);
+
+extern struct proc_dir_entry *lprocfs_register(const char *name,
+                                             struct proc_dir_entry *parent,
+                                             struct lprocfs_vars *list,
+                                             void *data);
+#endif
+extern int lprocfs_seq_add_vars(struct proc_dir_entry *root,
+                               struct lprocfs_seq_vars *var,
+                               void *data);
+
 extern struct proc_dir_entry *
-lprocfs_register(const char *name, struct proc_dir_entry *parent,
-                struct lprocfs_vars *list, void *data);
+lprocfs_seq_register(const char *name, struct proc_dir_entry *parent,
+                    struct lprocfs_seq_vars *list, void *data);
 extern void lprocfs_remove(struct proc_dir_entry **root);
 extern void lprocfs_remove_proc_entry(const char *name,
                                       struct proc_dir_entry *parent);
 #ifndef HAVE_ONLY_PROCFS_SEQ
-extern void remove_proc_subtree(const char *name,
-                               struct proc_dir_entry *parent);
+extern void lprocfs_try_remove_proc_entry(const char *name,
+                                         struct proc_dir_entry *parent);
+
+extern struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *root,
+                                          const char *name);
 #endif
 extern int lprocfs_obd_setup(struct obd_device *dev);
 extern int lprocfs_obd_cleanup(struct obd_device *obd);
@@ -643,13 +687,19 @@ extern int lprocfs_connect_flags_seq_show(struct seq_file *m, void *data);
 extern int lprocfs_num_exports_seq_show(struct seq_file *m, void *data);
 #endif
 struct adaptive_timeout;
-extern int lprocfs_at_hist_helper(struct seq_file *m,
+extern int lprocfs_seq_at_hist_helper(struct seq_file *m,
                                      struct adaptive_timeout *at);
 extern int lprocfs_timeouts_seq_show(struct seq_file *m, void *data);
 extern ssize_t
 lprocfs_timeouts_seq_write(struct file *file, const char *buffer,
                           size_t count, loff_t *off);
 #ifdef HAVE_SERVER_SUPPORT
+#ifndef HAVE_ONLY_PROCFS_SEQ
+extern ssize_t lprocfs_fops_read(struct file *f, char __user *buf,
+                                size_t size, loff_t *ppos);
+extern ssize_t lprocfs_fops_write(struct file *f, const char __user *buf,
+                                 size_t size, loff_t *ppos);
+#endif
 extern ssize_t
 lprocfs_evict_client_seq_write(struct file *file, const char *buffer,
                                size_t count, loff_t *off);
@@ -732,10 +782,15 @@ extern int lprocfs_seq_release(struct inode *, struct file *);
 #define __LPROC_SEQ_FOPS(name, custom_seq_write)                       \
 static int name##_single_open(struct inode *inode, struct file *file)  \
 {                                                                      \
-       LPROCFS_ENTRY_CHECK(PDE(inode));                                \
+       int rc;                                                         \
+                                                                       \
+       rc = LPROCFS_ENTRY_CHECK(inode);                                \
+       if (rc < 0)                                                     \
+               return rc;                                              \
+                                                                       \
        return single_open(file, name##_seq_show, PDE_DATA(inode));     \
 }                                                                      \
-struct file_operations name##_fops = {                                 \
+static const struct file_operations name##_fops = {                    \
        .owner   = THIS_MODULE,                                         \
        .open    = name##_single_open,                                  \
        .read    = seq_read,                                            \
@@ -780,7 +835,7 @@ struct file_operations name##_fops = {                                      \
        {                                                               \
                return single_open(file, NULL, PDE_DATA(inode));        \
        }                                                               \
-       struct file_operations name##_##type##_fops = {                 \
+       static const struct file_operations name##_##type##_fops = {    \
                .open    = name##_##type##_open,                        \
                .write   = name##_##type##_write,                       \
                .release = lprocfs_single_release,                      \
@@ -952,8 +1007,7 @@ ssize_t lprocfs_nid_stats_seq_write(struct file *file, const char *buffer,
 static inline
 int lprocfs_nid_stats_clear_seq_show(struct seq_file *m, void *data)
 {return 0;}
-static inline int lprocfs_exp_setup(struct obd_export *exp,lnet_nid_t *peer_nid,
-                                    int *newnid)
+static inline int lprocfs_exp_setup(struct obd_export *exp,lnet_nid_t *peer_nid)
 { return 0; }
 #endif
 static inline int lprocfs_exp_cleanup(struct obd_export *exp)
@@ -966,23 +1020,36 @@ static inline struct proc_dir_entry *
 lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent,
                     const char *format, ...)
 {return NULL; }
-static inline int lprocfs_add_vars(struct proc_dir_entry *root,
-                                  struct lprocfs_vars *var,
-                                  void *data)
-{ return 0; }
+#ifndef HAVE_ONLY_PROCFS_SEQ
 static inline struct proc_dir_entry *
 lprocfs_register(const char *name, struct proc_dir_entry *parent,
                 struct lprocfs_vars *list, void *data)
 { return NULL; }
+static inline int lprocfs_add_vars(struct proc_dir_entry *root,
+                                   struct lprocfs_vars *var,
+                                   void *data)
+{ return 0; }
+#endif
+static inline int lprocfs_seq_add_vars(struct proc_dir_entry *root,
+                                      struct lprocfs_seq_vars *var,
+                                      void *data)
+{ return 0; }
+static inline struct proc_dir_entry *
+lprocfs_seq_register(const char *name, struct proc_dir_entry *parent,
+                    struct lprocfs_seq_vars *list, void *data)
+{ return NULL; }
 static inline void lprocfs_remove(struct proc_dir_entry **root)
 { return; }
 static inline void lprocfs_remove_proc_entry(const char *name,
                                              struct proc_dir_entry *parent)
 { return; }
 #ifndef HAVE_ONLY_PROCFS_SEQ
-static inline void remove_proc_subtree(const char *name,
-                                      struct proc_dir_entry *parent)
+static inline void lprocfs_try_remove_proc_entry(const char *name,
+                                                struct proc_dir_entry *parent)
 { return; }
+static inline struct proc_dir_entry *lprocfs_srch(struct proc_dir_entry *head,
+                                                 const char *name)
+{ return 0; }
 #endif
 static inline int lprocfs_obd_setup(struct obd_device *dev)
 { return 0; }
@@ -1007,8 +1074,8 @@ static inline int lprocfs_num_exports_seq_show(struct seq_file *m, void *data)
 { return 0; }
 #endif
 struct adaptive_timeout;
-static inline int lprocfs_at_hist_helper(struct seq_file *m,
-                                        struct adaptive_timeout *at)
+static inline int lprocfs_seq_at_hist_helper(struct seq_file *m,
+                                            struct adaptive_timeout *at)
 { return 0; }
 static inline int lprocfs_timeouts_seq_show(struct seq_file *m, void *data)
 { return 0; }