Whamcloud - gitweb
LU-506 FC15: ctl_name & strategy removed from ctl_table.
[fs/lustre-release.git] / lnet / lnet / router_proc.c
index c053f4c..b7365f2 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  *
  *   This file is part of Portals
  *   http://sourceforge.net/projects/sandiaportals/
@@ -27,7 +27,8 @@
 
 #if defined(__KERNEL__) && defined(LNET_ROUTER)
 
-/* this is really lnet_proc.c */
+/* This is really lnet_proc.c. You might need to update sanity test 215
+ * if any file format is changed. */
 
 static cfs_sysctl_table_header_t *lnet_table_header = NULL;
 
@@ -51,6 +52,41 @@ enum {
 #define PSDEV_LNET_NIS     CTL_UNNUMBERED
 #endif
 
+/*
+ * NB: we don't use the highest bit of *ppos because it's signed;
+ *     next 9 bits is used to stash idx (assuming that
+ *     LNET_PEER_HASHSIZE < 512)
+ */
+#define LNET_LOFFT_BITS        (sizeof(loff_t) * 8)
+#define LNET_VERSION_BITS      MAX(((MIN(LNET_LOFFT_BITS, 64)) / 4), 8)
+#define LNET_PHASH_IDX_BITS    9
+#define LNET_PHASH_NUM_BITS    (LNET_LOFFT_BITS - 1 -\
+                                LNET_VERSION_BITS - LNET_PHASH_IDX_BITS)
+#define LNET_PHASH_BITS        (LNET_PHASH_IDX_BITS + LNET_PHASH_NUM_BITS)
+
+#define LNET_VERSION_BITMASK   ((1ULL << LNET_VERSION_BITS) - 1)
+#define LNET_PHASH_IDX_BITMASK ((1ULL << LNET_PHASH_IDX_BITS) - 1)
+#define LNET_PHASH_NUM_BITMASK ((1ULL << LNET_PHASH_NUM_BITS) - 1)
+
+#define LNET_VERSION_MASK      (LNET_VERSION_BITMASK << LNET_PHASH_BITS)
+#define LNET_PHASH_IDX_MASK    (LNET_PHASH_IDX_BITMASK << LNET_PHASH_NUM_BITS)
+#define LNET_PHASH_NUM_MASK    (LNET_PHASH_NUM_BITMASK)
+
+#define LNET_VERSION_GET(pos)   (int)(((pos) & LNET_VERSION_MASK) >> \
+                                     LNET_PHASH_BITS)
+#define LNET_PHASH_IDX_GET(pos) (int)(((pos) & LNET_PHASH_IDX_MASK) >> \
+                                      LNET_PHASH_NUM_BITS)
+#define LNET_PHASH_NUM_GET(pos) (int)((pos) & LNET_PHASH_NUM_MASK)
+#define LNET_VERSION_VALID_MASK(ver) \
+                                (unsigned int)((ver) & \
+                                 LNET_VERSION_BITMASK)
+#define LNET_PHASH_POS_MAKE(ver, idx, num)                                     \
+                                (((((loff_t)(ver)) & LNET_VERSION_BITMASK) <<  \
+                                   LNET_PHASH_BITS) |                          \
+                                 ((((loff_t)(idx)) & LNET_PHASH_IDX_BITMASK) <<\
+                                   LNET_PHASH_NUM_BITS) |                      \
+                                 ((num) & LNET_PHASH_NUM_BITMASK))
+
 static int __proc_lnet_stats(void *data, int write,
                              loff_t pos, void *buffer, int nob)
 {
@@ -113,10 +149,14 @@ int LL_PROC_PROTO(proc_lnet_routes)
         char      *s;
         const int  tmpsiz = 256;
         int        len;
-        int       *ver_p  = (unsigned int *)(&filp->private_data);
+        int        ver;
+        int        num;
 
         DECLARE_LL_PROC_PPOS_DECL;
 
+        num = LNET_PHASH_NUM_GET(*ppos);
+        ver = LNET_VERSION_GET(*ppos);
+
         LASSERT (!write);
 
         if (*lenp == 0)
@@ -138,18 +178,19 @@ int LL_PROC_PROTO(proc_lnet_routes)
                 LASSERT (tmpstr + tmpsiz - s > 0);
 
                 LNET_LOCK();
-                *ver_p = (unsigned int)the_lnet.ln_remote_nets_version;
+                ver = (unsigned int)the_lnet.ln_remote_nets_version;
                 LNET_UNLOCK();
+                *ppos = LNET_PHASH_POS_MAKE(ver, 0, num);
         } else {
                 cfs_list_t        *n;
                 cfs_list_t        *r;
                 lnet_route_t      *route = NULL;
                 lnet_remotenet_t  *rnet  = NULL;
-                int                skip  = *ppos - 1;
+                int                skip  = num - 1;
 
                 LNET_LOCK();
 
-                if (*ver_p != (unsigned int)the_lnet.ln_remote_nets_version) {
+                if (ver != LNET_VERSION_VALID_MASK(the_lnet.ln_remote_nets_version)) {
                         LNET_UNLOCK();
                         LIBCFS_FREE(tmpstr, tmpsiz);
                         return -ESTALE;
@@ -200,8 +241,10 @@ int LL_PROC_PROTO(proc_lnet_routes)
         } else if (len > 0) { /* wrote something */
                 if (cfs_copy_to_user(buffer, tmpstr, len))
                         rc = -EFAULT;
-                else
-                        *ppos += 1;
+                else {
+                        num += 1;
+                        *ppos = LNET_PHASH_POS_MAKE(ver, 0, num);
+                }
         }
 
         LIBCFS_FREE(tmpstr, tmpsiz);
@@ -219,10 +262,14 @@ int LL_PROC_PROTO(proc_lnet_routers)
         char      *s;
         const int  tmpsiz = 256;
         int        len;
-        int       *ver_p = (unsigned int *)(&filp->private_data);
+        int        ver;
+        int        num;
 
         DECLARE_LL_PROC_PPOS_DECL;
 
+        num = LNET_PHASH_NUM_GET(*ppos);
+        ver = LNET_VERSION_GET(*ppos);
+
         LASSERT (!write);
 
         if (*lenp == 0)
@@ -242,16 +289,17 @@ int LL_PROC_PROTO(proc_lnet_routers)
                 LASSERT (tmpstr + tmpsiz - s > 0);
 
                 LNET_LOCK();
-                *ver_p = (unsigned int)the_lnet.ln_routers_version;
+                ver = (unsigned int)the_lnet.ln_routers_version;
                 LNET_UNLOCK();
+                *ppos = LNET_PHASH_POS_MAKE(ver, 0, num);
         } else {
                 cfs_list_t        *r;
                 lnet_peer_t       *peer = NULL;
-                int                skip = *ppos - 1;
+                int                skip = num - 1;
 
                 LNET_LOCK();
 
-                if (*ver_p != (unsigned int)the_lnet.ln_routers_version) {
+                if (ver != LNET_VERSION_VALID_MASK(the_lnet.ln_routers_version)) {
                         LNET_UNLOCK();
                         LIBCFS_FREE(tmpstr, tmpsiz);
                         return -ESTALE;
@@ -314,8 +362,10 @@ int LL_PROC_PROTO(proc_lnet_routers)
         } else if (len > 0) { /* wrote something */
                 if (cfs_copy_to_user(buffer, tmpstr, len))
                         rc = -EFAULT;
-                else
-                        *ppos += 1;
+                else {
+                        num += 1;
+                        *ppos = LNET_PHASH_POS_MAKE(ver, 0, num);
+                }
         }
 
         LIBCFS_FREE(tmpstr, tmpsiz);
@@ -326,23 +376,6 @@ int LL_PROC_PROTO(proc_lnet_routers)
         return rc;
 }
 
-/*
- * NB: we don't use the highest bit of *ppos because it's signed;
- *     next 9 bits is used to stash idx (assuming that
- *     LNET_PEER_HASHSIZE < 512)
- */
-#define LNET_LOFFT_BITS (sizeof(loff_t) * 8)
-#define LNET_PHASH_BITS 9
-#define LNET_PHASH_IDX_MASK (((1ULL << LNET_PHASH_BITS) - 1) <<               \
-                             (LNET_LOFFT_BITS - LNET_PHASH_BITS - 1))
-#define LNET_PHASH_NUM_MASK ((1ULL <<                                         \
-                              (LNET_LOFFT_BITS - LNET_PHASH_BITS -1)) - 1)
-#define LNET_PHASH_IDX_GET(pos) (int)(((pos) & LNET_PHASH_IDX_MASK) >>  \
-                                      (LNET_LOFFT_BITS - LNET_PHASH_BITS -1))
-#define LNET_PHASH_NUM_GET(pos) (int)((pos) & LNET_PHASH_NUM_MASK)
-#define LNET_PHASH_POS_MAKE(idx, num) ((((loff_t)idx) << (LNET_LOFFT_BITS -   \
-                                                  LNET_PHASH_BITS -1)) | (num))
-
 int LL_PROC_PROTO(proc_lnet_peers)
 {
         int        rc = 0;
@@ -350,7 +383,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
         char      *s;
         const int  tmpsiz      = 256;
         int        len;
-        int       *ver_p       = (unsigned int *)(&filp->private_data);
+        int        ver;
         int        idx;
         int        num;
 
@@ -358,8 +391,9 @@ int LL_PROC_PROTO(proc_lnet_peers)
 
         idx = LNET_PHASH_IDX_GET(*ppos);
         num = LNET_PHASH_NUM_GET(*ppos);
+        ver = LNET_VERSION_GET(*ppos);
 
-        CLASSERT ((1 << LNET_PHASH_BITS) > LNET_PEER_HASHSIZE);
+        CLASSERT ((1ULL << LNET_PHASH_BITS) > LNET_PEER_HASHSIZE);
 
         LASSERT (!write);
 
@@ -374,14 +408,15 @@ int LL_PROC_PROTO(proc_lnet_peers)
 
         if (*ppos == 0) {
                 s += snprintf(s, tmpstr + tmpsiz - s,
-                              "%-24s %4s %5s %5s %5s %5s %5s %5s %s\n",
-                              "nid", "refs", "state", "max",
+                              "%-24s %4s %5s %5s %5s %5s %5s %5s %5s %s\n",
+                              "nid", "refs", "state", "last", "max",
                               "rtr", "min", "tx", "min", "queue");
                 LASSERT (tmpstr + tmpsiz - s > 0);
 
                 LNET_LOCK();
-                *ver_p  = (unsigned int)the_lnet.ln_peertable_version;
+                ver = (unsigned int)the_lnet.ln_peertable_version;
                 LNET_UNLOCK();
+                *ppos = LNET_PHASH_POS_MAKE(ver, idx, num);
 
                 num++;
         } else {
@@ -391,7 +426,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
 
                 LNET_LOCK();
 
-                if (*ver_p != (unsigned int)the_lnet.ln_peertable_version) {
+                if (ver != LNET_VERSION_VALID_MASK(the_lnet.ln_peertable_version)) {
                         LNET_UNLOCK();
                         LIBCFS_FREE(tmpstr, tmpsiz);
                         return -ESTALE;
@@ -407,7 +442,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
                                 if (skip == 0) {
                                         peer = lp;
 
-                                        /* minor optimiztion: start from idx+1
+                                        /* minor optimization: start from idx+1
                                          * on next iteration if we've just
                                          * drained lp_hashlist */
                                         if (lp->lp_hashlist.next ==
@@ -436,6 +471,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
                 if (peer != NULL) {
                         lnet_nid_t nid       = peer->lp_nid;
                         int        nrefs     = peer->lp_refcount;
+                        int        lastalive = -1;
                         char      *aliveness = "NA";
                         int        maxcr     = peer->lp_ni->ni_peertxcredits;
                         int        txcr      = peer->lp_txcredits;
@@ -448,10 +484,25 @@ int LL_PROC_PROTO(proc_lnet_peers)
                             lnet_peer_aliveness_enabled(peer))
                                 aliveness = peer->lp_alive ? "up" : "down";
 
+                        if (lnet_peer_aliveness_enabled(peer)) {
+                                cfs_time_t     now = cfs_time_current();
+                                cfs_duration_t delta;
+
+                                delta = cfs_time_sub(now, peer->lp_last_alive);
+                                lastalive = cfs_duration_sec(delta);
+
+                                /* No need to mess up peers contents with
+                                 * arbitrarily long integers - it suffices to
+                                 * know that lastalive is more than 10000s old
+                                 */
+                                if (lastalive >= 10000)
+                                        lastalive = 9999;
+                        }
+
                         s += snprintf(s, tmpstr + tmpsiz - s,
-                                      "%-24s %4d %5s %5d %5d %5d %5d %5d %d\n",
+                                      "%-24s %4d %5s %5d %5d %5d %5d %5d %5d %d\n",
                                       libcfs_nid2str(nid), nrefs, aliveness,
-                                      maxcr, rtrcr, minrtrcr, txcr,
+                                      lastalive, maxcr, rtrcr, minrtrcr, txcr,
                                       mintxcr, txqnob);
                         LASSERT (tmpstr + tmpsiz - s > 0);
                 }
@@ -467,7 +518,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
                 if (cfs_copy_to_user(buffer, tmpstr, len))
                         rc = -EFAULT;
                 else
-                        *ppos = LNET_PHASH_POS_MAKE(idx, num);
+                        *ppos = LNET_PHASH_POS_MAKE(ver, idx, num);
         }
 
         LIBCFS_FREE(tmpstr, tmpsiz);
@@ -640,47 +691,49 @@ static cfs_sysctl_table_t lnet_table[] = {
          * to go via /proc for portability.
          */
         {
-                .ctl_name = PSDEV_LNET_STATS,
+                INIT_CTL_NAME(PSDEV_LNET_STATS)
                 .procname = "stats",
                 .mode     = 0644,
                 .proc_handler = &proc_lnet_stats,
         },
         {
-                .ctl_name = PSDEV_LNET_ROUTES,
+                INIT_CTL_NAME(PSDEV_LNET_ROUTES)
                 .procname = "routes",
                 .mode     = 0444,
                 .proc_handler = &proc_lnet_routes,
         },
         {
-                .ctl_name = PSDEV_LNET_ROUTERS,
+                INIT_CTL_NAME(PSDEV_LNET_ROUTERS)
                 .procname = "routers",
                 .mode     = 0444,
                 .proc_handler = &proc_lnet_routers,
         },
         {
-                .ctl_name = PSDEV_LNET_PEERS,
+                INIT_CTL_NAME(PSDEV_LNET_PEERS)
                 .procname = "peers",
                 .mode     = 0444,
                 .proc_handler = &proc_lnet_peers,
         },
         {
-                .ctl_name = PSDEV_LNET_PEERS,
+                INIT_CTL_NAME(PSDEV_LNET_PEERS)
                 .procname = "buffers",
                 .mode     = 0444,
                 .proc_handler = &proc_lnet_buffers,
         },
         {
-                .ctl_name = PSDEV_LNET_NIS,
+                INIT_CTL_NAME(PSDEV_LNET_NIS)
                 .procname = "nis",
                 .mode     = 0444,
                 .proc_handler = &proc_lnet_nis,
         },
-        {0}
+        {
+                INIT_CTL_NAME(0)
+        }
 };
 
 static cfs_sysctl_table_t top_table[] = {
         {
-                .ctl_name = CTL_LNET,
+                INIT_CTL_NAME(CTL_LNET)
                 .procname = "lnet",
                 .mode     = 0555,
                 .data     = NULL,
@@ -688,7 +741,7 @@ static cfs_sysctl_table_t top_table[] = {
                 .child    = lnet_table,
         },
         {
-                .ctl_name = 0
+                INIT_CTL_NAME(0)
         }
 };