Whamcloud - gitweb
LU-12678 lnet: prepare to make lnet_lnd const. 30/36830/5
authorMr NeilBrown <neilb@suse.com>
Mon, 30 Dec 2019 15:54:09 +0000 (10:54 -0500)
committerOleg Drokin <green@whamcloud.com>
Fri, 10 Jan 2020 07:42:09 +0000 (07:42 +0000)
Preferred practice is for structs containing function
pointers to be 'const'.  Such structs are generally tempting
attack vectors, and making them const allows linux to place
them in read-only memory, thus reducing the attack surface.

'struct lnet_lnd' is mostly function pointers, but contains
one writable field - a list_head.

Rather than keeping registered lnds in a linked-list, we can place
them in an array indexed by type - type numbers are at most 15 so
this is not a burden.

With these changes, no part of an lnet_lnd is ever modified.

Test-Parameters: trivial
Test-Parameters: testlist=sanity-lnet

Signed-off-by: Mr NeilBrown <neilb@suse.com>
Change-Id: I08c7df551109e05ca4a3cef866e8df737d1a1ad4
Reviewed-on: https://review.whamcloud.com/36830
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Serguei Smirnov <ssmirnov@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/include/lnet/lib-types.h
lnet/include/uapi/linux/lnet/nidstr.h
lnet/lnet/api-ni.c
lnet/lnet/lo.c

index d17929d..703251e 100644 (file)
@@ -49,6 +49,7 @@
 
 #include <uapi/linux/lnet/lnet-dlc.h>
 #include <uapi/linux/lnet/lnetctl.h>
+#include <uapi/linux/lnet/nidstr.h>
 
 /* Max payload size */
 #define LNET_MAX_PAYLOAD       LNET_MTU
@@ -248,9 +249,6 @@ struct lnet_ni;                                      /* forward ref */
 struct socket;
 
 struct lnet_lnd {
-       /* fields managed by portals */
-       struct list_head        lnd_list;       /* stash in the LND table */
-
        /* fields initialized by the LND */
        __u32                   lnd_type;
 
@@ -1112,7 +1110,7 @@ struct lnet {
        /* uniquely identifies this ni in this epoch */
        __u64                           ln_interface_cookie;
        /* registered LNDs */
-       struct list_head                ln_lnds;
+       struct lnet_lnd                 *ln_lnds[NUM_LNDS];
 
        /* test protocol compatibility flags */
        int                             ln_testprotocompat;
index 6e3f4ca..c4a297f 100644 (file)
@@ -60,6 +60,8 @@ enum {
        GNILND          = 13,
        GNIIPLND        = 14,
        PTL4LND         = 15,
+
+       NUM_LNDS
 };
 
 struct list_head;
index d6e5e3d..a593597 100644 (file)
@@ -800,16 +800,14 @@ static void lnet_assert_wire_constants(void)
 static struct lnet_lnd *lnet_find_lnd_by_type(__u32 type)
 {
        struct lnet_lnd *lnd;
-       struct list_head *tmp;
 
        /* holding lnd mutex */
-       list_for_each(tmp, &the_lnet.ln_lnds) {
-               lnd = list_entry(tmp, struct lnet_lnd, lnd_list);
+       if (type >= NUM_LNDS)
+               return NULL;
+       lnd = the_lnet.ln_lnds[type];
+       LASSERT(!lnd || lnd->lnd_type == type);
 
-               if (lnd->lnd_type == type)
-                       return lnd;
-       }
-       return NULL;
+       return lnd;
 }
 
 unsigned int
@@ -827,7 +825,7 @@ lnet_register_lnd(struct lnet_lnd *lnd)
        LASSERT(libcfs_isknown_lnd(lnd->lnd_type));
        LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == NULL);
 
-       list_add_tail(&lnd->lnd_list, &the_lnet.ln_lnds);
+       the_lnet.ln_lnds[lnd->lnd_type] = lnd;
 
        CDEBUG(D_NET, "%s LND registered\n", libcfs_lnd2str(lnd->lnd_type));
 
@@ -842,7 +840,7 @@ lnet_unregister_lnd(struct lnet_lnd *lnd)
 
        LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == lnd);
 
-       list_del(&lnd->lnd_list);
+       the_lnet.ln_lnds[lnd->lnd_type] = NULL;
        CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type));
 
        mutex_unlock(&the_lnet.ln_lnd_mutex);
@@ -2517,7 +2515,6 @@ int lnet_lib_init(void)
        }
 
        the_lnet.ln_refcount = 0;
-       INIT_LIST_HEAD(&the_lnet.ln_lnds);
        INIT_LIST_HEAD(&the_lnet.ln_net_zombie);
        INIT_LIST_HEAD(&the_lnet.ln_msg_resend);
 
@@ -2543,14 +2540,18 @@ int lnet_lib_init(void)
  *
  * \pre lnet_lib_init() called with success.
  * \pre All LNet users called LNetNIFini() for matching LNetNIInit() calls.
+ *
+ * As this happens at module-unload, all lnds must already be unloaded,
+ * so they must already be unregistered.
  */
 void lnet_lib_exit(void)
 {
-       LASSERT(the_lnet.ln_refcount == 0);
+       int i;
 
-       while (!list_empty(&the_lnet.ln_lnds))
-               lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
-                                              struct lnet_lnd, lnd_list));
+       LASSERT(the_lnet.ln_refcount == 0);
+       lnet_unregister_lnd(&the_lolnd);
+       for (i = 0; i < NUM_LNDS; i++)
+               LASSERT(!the_lnet.ln_lnds[i]);
        lnet_destroy_locks();
 }
 
index a11ecdd..4f0ec8b 100644 (file)
@@ -104,10 +104,6 @@ lolnd_startup(struct lnet_ni *ni)
 }
 
 struct lnet_lnd the_lolnd = {
-       .lnd_list       = {
-                               .next = &the_lolnd.lnd_list,
-                               .prev = &the_lolnd.lnd_list
-                       },
        .lnd_type       = LOLND,
        .lnd_startup    = lolnd_startup,
        .lnd_shutdown   = lolnd_shutdown,