Whamcloud - gitweb
* Changed parsing of 'routes=' to allow routes via different networks with
authoreeb <eeb>
Fri, 23 Sep 2005 14:30:47 +0000 (14:30 +0000)
committereeb <eeb>
Fri, 23 Sep 2005 14:30:47 +0000 (14:30 +0000)
    and with different hopcounts; it just uses the shortest hopcount.

    NB this still needs a change to LNet{Put,Get} to allow the caller to
    specify the source NI and for ptlrpc to use it.

*   forwarding="enabled" explicitly enables the node as a router
    forwarding="disabled" explicitly disables the node as a router
    otherwise if any of the node's NIDs are mentioned as routers in 'routes='
    the node is implicitly enabled as a router.

*   Added LNET_SINGLE_THREADED to tell LNET if the userspace runtime supports
    posix threads.

*   Added lnd_wait() to tell LNET that to call into the LND if the APP wants to
    block for an event.

14 files changed:
lnet/include/lnet/lib-lnet.h
lnet/include/lnet/lib-types.h
lnet/lnet/api-ni.c
lnet/lnet/autoMakefile.am
lnet/lnet/config.c
lnet/lnet/lib-eq.c
lnet/lnet/lib-move.c
lnet/lnet/lib-msg.c
lnet/lnet/lo.c
lnet/lnet/router.c
lnet/lnet/router_proc.c
lnet/ulnds/ptllnd/ptllnd.h
lnet/ulnds/socklnd/procapi.c
lnet/ulnds/socklnd/utypes.h [deleted file]

index 6ad03f0..36226ae 100644 (file)
@@ -38,19 +38,34 @@ static inline int lnet_md_exhausted (lnet_libmd_t *md)
 }
 
 #ifdef __KERNEL__
-#define LNET_LOCK()                                                \
-        spin_lock(&the_lnet.ln_lock)                 
-#define LNET_UNLOCK()                                              \
-        spin_unlock(&the_lnet.ln_lock)               
+#define LNET_LOCK()        spin_lock(&the_lnet.ln_lock)                 
+#define LNET_UNLOCK()      spin_unlock(&the_lnet.ln_lock)               
 #define LNET_MUTEX_DOWN(m) mutex_down(m)
 #define LNET_MUTEX_UP(m)   mutex_up(m)
-#else                                                                   
-#define LNET_LOCK()                                                \
-        pthread_mutex_lock(&the_lnet.ln_mutex)       
-#define LNET_UNLOCK()                                              \
-        pthread_mutex_unlock(&the_lnet.ln_mutex)
+#else
+# if LNET_SINGLE_THREADED
+#define LNET_SINGLE_THREADED_LOCK(l)            \
+do {                                            \
+        LASSERT ((l) == 0);                     \
+        (l) = 1;                                \
+} while (0)
+
+#define LNET_SINGLE_THREADED_UNLOCK(l)          \
+do {                                            \
+        LASSERT ((l) == 1);                     \
+        (l) = 0;                                \
+} while (0)
+
+#define LNET_LOCK()        LNET_SINGLE_THREADED_LOCK(the_lnet.ln_lock)
+#define LNET_UNLOCK()      LNET_SINGLE_THREADED_UNLOCK(the_lnet.ln_lock)
+#define LNET_MUTEX_DOWN(m) LNET_SINGLE_THREADED_LOCK(*(m))
+#define LNET_MUTEX_UP(m)   LNET_SINGLE_THREADED_UNLOCK(*(m))
+# else
+#define LNET_LOCK()        pthread_mutex_lock(&the_lnet.ln_lock)
+#define LNET_UNLOCK()      pthread_mutex_unlock(&the_lnet.ln_lock)
 #define LNET_MUTEX_DOWN(m) pthread_mutex_lock(m)
 #define LNET_MUTEX_UP(m)   pthread_mutex_unlock(m)
+# endif
 #endif
 
 #define MAX_PORTALS     64
@@ -431,8 +446,7 @@ lnet_nid2peerhash (lnet_nid_t nid)
         return &the_lnet.ln_peer_hash[idx];
 }
 
-extern lnd_t      the_lolnd;
-extern lnet_ni_t *lnet_loni;
+extern lnd_t the_lolnd;
 
 #ifndef __KERNEL__
 #define LNET_REGISTER_LND_IF_PRESENT(lnd)                               \
@@ -466,7 +480,8 @@ int lnet_get_route(int idx, __u32 *net, __u32 *hops,
                    lnet_nid_t *gateway, __u32 *alive);
 void lnet_proc_init(void);
 void lnet_proc_fini(void);
-int lnet_alloc_rtrpools(void);
+void lnet_init_rtrpools(void);
+int  lnet_alloc_rtrpools(int im_a_router);
 void lnet_free_rtrpools(void);
 lnet_remotenet_t *lnet_find_net_locked (__u32 net);
 
@@ -577,7 +592,7 @@ int lnet_acceptor_port(void);
 int lnet_acceptor_start(void);
 void lnet_acceptor_stop(void);
 
-int lnet_parse_routes (char *route_str);
+int lnet_parse_routes (char *route_str, int *im_a_router);
 int lnet_parse_networks (struct list_head *nilist, char *networks);
 
 int lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid);
index cfb830e..0041359 100644 (file)
@@ -101,10 +101,10 @@ typedef struct {
  * code in the header's dest_nid, the peer's NID in the src_nid, and
  * LNET_MSG_HELLO in the type field.  All other common fields are zero
  * (including payload_size; i.e. no payload).  
- * This is for use by byte-stream NALs (e.g. TCP/IP) to check the peer is
- * running the same protocol and to find out its NID. These NALs should
+ * This is for use by byte-stream LNDs (e.g. TCP/IP) to check the peer is
+ * running the same protocol and to find out its NID. These LNDs should
  * exchange HELLO messages when a connection is first established.  Individual
- * NALs can put whatever else they fancy in lnet_hdr_t::msg.
+ * LNDs can put whatever else they fancy in lnet_hdr_t::msg.
  */
 typedef struct {
         __u32  magic;                          /* LNET_PROTO_TCP_MAGIC */
@@ -112,7 +112,7 @@ typedef struct {
         __u16   version_minor;                  /* increment on compatible change */
 } WIRE_ATTR lnet_magicversion_t;
 
-/* PROTO MAGIC for NALs that once used their own private acceptor */
+/* PROTO MAGIC for LNDs that once used their own private acceptor */
 #define LNET_PROTO_OPENIB_MAGIC             0x0be91b91
 #define LNET_PROTO_RA_MAGIC                 0x0be91b92
 #define LNET_PROTO_TCP_MAGIC                0xeebc0ded
@@ -259,10 +259,10 @@ struct lnet_ni;                                  /* forward ref */
 typedef struct lnet_lnd
 {
         /* fields managed by portals */
-        struct list_head  lnd_list;             /* stash in the NAL table */
+        struct list_head  lnd_list;             /* stash in the LND table */
         int               lnd_refcount;         /* # active instances */
 
-        /* fields initialised by the NAL */
+        /* fields initialised by the LND */
         unsigned int      lnd_type;
         
         int  (*lnd_startup) (struct lnet_ni *ni);
@@ -275,7 +275,7 @@ typedef struct lnet_lnd
          *    in virtual memory (struct iovec *iov != NULL)
          * OR
          *    in pages (kernel only: plt_kiov_t *kiov != NULL).
-         * The NAL may NOT overwrite these fragment descriptors.
+         * The LND may NOT overwrite these fragment descriptors.
          * An 'offset' and may specify a byte offset within the set of
          * fragments to start from 
          */
@@ -312,6 +312,9 @@ typedef struct lnet_lnd
 #ifdef __KERNEL__
         /* accept a new connection */
         int (*lnd_accept)(struct lnet_ni *ni, struct socket *sock);
+#else
+        /* wait for something to happen */
+        void (*lnd_wait)(struct lnet_ni *ni, int milliseconds);
 #endif
 } lnd_t;
 
@@ -402,7 +405,7 @@ typedef struct
 
         int                ln_ptlcompat;        /* do I support talking to portals? */
         
-        struct list_head   ln_lnds;             /* registered NALs */
+        struct list_head   ln_lnds;             /* registered LNDs */
 
 #ifdef __KERNEL__
         spinlock_t         ln_lock;
@@ -410,10 +413,16 @@ typedef struct
         struct semaphore   ln_api_mutex;
         struct semaphore   ln_lnd_mutex;
 #else
-        pthread_mutex_t    ln_mutex;
+# if LNET_SINGLE_THREADED
+        int                ln_lock;
+        int                ln_api_mutex;
+        int                ln_lnd_mutex;
+# else
         pthread_cond_t     ln_cond;
+        pthread_mutex_t    ln_lock;
         pthread_mutex_t    ln_api_mutex;
         pthread_mutex_t    ln_lnd_mutex;
+# endif
 #endif
 
         /* Stuff initialised at LNetNIInit() */
@@ -424,9 +433,11 @@ typedef struct
 
         lnet_pid_t         ln_pid;              /* requested pid */
 
-        struct list_head   ln_nis;              /* NAL instances */
-        struct list_head   ln_zombie_nis;       /* dying NAL instances */
-        int                ln_nzombie_nis;      /* # of NIS to wait for */
+        struct list_head   ln_nis;              /* LND instances */
+        lnet_ni_t         *ln_loni;             /* the loopback NI */
+        lnet_ni_t         *ln_eqwaitni;         /* NI to wait for events in */
+        struct list_head   ln_zombie_nis;       /* dying LND instances */
+        int                ln_nzombie_nis;      /* # of NIs to wait for */
 
         struct list_head   ln_remote_nets;      /* remote networks with routes to them */
         __u64              ln_remote_nets_version; /* validity stamp */
index 112dc40..b41c1ec 100644 (file)
@@ -51,6 +51,42 @@ lnet_get_networks(void)
         return networks;
 }
 
+int
+lnet_get_portals_compatibility(void)
+{
+        if (!strcmp(portals_compatibility, "none")) {
+                return 0;
+        }
+
+        if (!strcmp(portals_compatibility, "weak")) {
+                return 1;
+                LCONSOLE_WARN("Starting in weak portals-compatible mode\n");
+        }
+
+        if (!strcmp(portals_compatibility, "strong")) {
+                return 2;
+                LCONSOLE_WARN("Starting in strong portals-compatible mode\n");
+        } 
+
+        LCONSOLE_ERROR("portals_compatibility=\"%s\" not supported\n",
+                       portals_compatibility);
+        return -EINVAL;
+}
+
+void
+lnet_init_locks(void)
+{
+        spin_lock_init (&the_lnet.ln_lock);
+        cfs_waitq_init (&the_lnet.ln_waitq);
+        init_mutex(&the_lnet.ln_lnd_mutex);
+        init_mutex(&the_lnet.ln_api_mutex);
+}
+
+void
+lnet_fini_locks(void)
+{
+}
+
 #else
 
 char *
@@ -101,14 +137,47 @@ lnet_get_networks (void)
         return default_networks;
 }
 
-void lnet_proc_init(void)
+int
+lnet_get_portals_compatibility(void)
 {
+        return 0;
+}
+
+# if LNET_SINGLE_THREADED
+
+void lnet_init_locks(void)
+{
+        the_lnet.ln_lock = 0;
+        the_lnet.ln_lnd_mutex = 0;
+        the_lnet.ln_api_mutex = 0;
+}
+
+void lnet_fini_locks(void)
+{
+        LASSERT (the_lnet.ln_api_mutex == 0);
+        LASSERT (the_lnet.ln_lnd_mutex == 0);
+        LASSERT (the_lnet.ln_lock == 0);
+}
+
+# else
+
+void lnet_init_locks(void)
+{
+        pthread_cond_init(&the_lnet.ln_cond, NULL);
+        pthread_mutex_init(&the_lnet.ln_lock, NULL);
+        pthread_mutex_init(&the_lnet.ln_lnd_mutex, NULL);
+        pthread_mutex_init(&the_lnet.ln_api_mutex, NULL);
 }
 
-void lnet_proc_fini(void)
+void lnet_fini_locks(void)
 {
+        pthread_mutex_destroy(&the_lnet.ln_api_mutex);
+        pthread_mutex_destroy(&the_lnet.ln_lnd_mutex);
+        pthread_mutex_destroy(&the_lnet.ln_lock);
+        pthread_cond_destroy(&the_lnet.ln_cond);
 }
 
+# endif
 #endif
 
 void lnet_assert_wire_constants (void)
@@ -464,8 +533,9 @@ lnet_invalidate_handle (lnet_libhandle_t *lh)
 }
 
 int
-lnet_init(lnet_pid_t requested_pid)
+lnet_prepare(lnet_pid_t requested_pid)
 {
+        /* Prepare to bring up the network */
         int               rc = 0;
         int               i;
 
@@ -496,6 +566,8 @@ lnet_init(lnet_pid_t requested_pid)
 
         the_lnet.ln_interface_cookie = lnet_create_interface_cookie();
 
+        lnet_init_rtrpools();
+        
         rc = lnet_setup_handle_hash ();
         if (rc != 0)
                 goto failed0;
@@ -504,17 +576,13 @@ lnet_init(lnet_pid_t requested_pid)
         if (rc != 0)
                 goto failed1;
 
-        rc = lnet_alloc_rtrpools();
-        if (rc != 0)
-                goto failed2;
-        
         the_lnet.ln_nportals = MAX_PORTALS;
         PORTAL_ALLOC(the_lnet.ln_portals, 
                      the_lnet.ln_nportals * 
                      sizeof(*the_lnet.ln_portals));
         if (the_lnet.ln_portals == NULL) {
                 rc = -ENOMEM;
-                goto failed3;
+                goto failed2;
         }
 
         for (i = 0; i < the_lnet.ln_nportals; i++)
@@ -522,8 +590,6 @@ lnet_init(lnet_pid_t requested_pid)
 
         return 0;
         
- failed3:
-        lnet_free_rtrpools();
  failed2:
         lnet_destroy_peer_table();
  failed1:
@@ -534,7 +600,7 @@ lnet_init(lnet_pid_t requested_pid)
 }
 
 int
-lnet_fini (void)
+lnet_unprepare (void)
 {
         int       idx;
         
@@ -728,11 +794,18 @@ lnet_shutdown_lndnis (void)
                 lnet_ni_decref_locked(ni); /* drop apini's ref */
         }
 
+        /* Drop the cached eqwait NI. */
+        if (the_lnet.ln_eqwaitni != NULL) {
+                lnet_ni_decref_locked(the_lnet.ln_eqwaitni); 
+                the_lnet.ln_eqwaitni = NULL;
+        }
+
         /* Drop the cached loopback NI. */
-        if (lnet_loni != NULL) {
-                lnet_ni_decref_locked(lnet_loni);
-                lnet_loni = NULL;
+        if (the_lnet.ln_loni != NULL) {
+                lnet_ni_decref_locked(the_lnet.ln_loni); 
+                the_lnet.ln_loni = NULL;
         }
+
         LNET_UNLOCK();
         /* Clear the peer table and wait for all peers to go (they hold refs on
          * their NIs) */
@@ -798,7 +871,7 @@ lnet_startup_lndnis (void)
         struct list_head   nilist;
         int                rc = 0;
         int                lnd_type;
-        int                retry;
+        int                nicount = 0;
 
         INIT_LIST_HEAD(&nilist);
         rc = lnet_parse_networks(&nilist, lnet_get_networks());
@@ -812,29 +885,31 @@ lnet_startup_lndnis (void)
                 LASSERT (libcfs_isknown_lnd(lnd_type));
 
                 LNET_MUTEX_DOWN(&the_lnet.ln_lnd_mutex);
+                lnd = lnet_find_lnd_by_type(lnd_type);
 
-                for (retry = 0;; retry = 1) {
-                        lnd = lnet_find_lnd_by_type(lnd_type);
-                        if (lnd != NULL) 
-                                break;
-
-                        LNET_MUTEX_UP(&the_lnet.ln_lnd_mutex);
 #ifdef __KERNEL__
-                        if (retry) {
+                if (lnd == NULL) {
+                        LNET_MUTEX_UP(&the_lnet.ln_lnd_mutex);
+                        request_module(libcfs_lnd2modname(lnd_type));
+                        LNET_MUTEX_DOWN(&the_lnet.ln_lnd_mutex);
+
+                        lnd = lnet_find_lnd_by_type(lnd_type);
+                        if (lnd == NULL) {
+                                LNET_MUTEX_UP(&the_lnet.ln_lnd_mutex);
                                 CERROR("Can't load LND %s, module %s\n",
                                        libcfs_lnd2str(lnd_type),
                                        libcfs_lnd2modname(lnd_type));
                                 goto failed;
                         }
-
-                        request_module(libcfs_lnd2modname(lnd_type));
+                }
 #else
+                if (lnd == NULL) {
+                        LNET_MUTEX_UP(&the_lnet.ln_lnd_mutex);
                         CERROR("LND %s not supported\n",
                                libcfs_lnd2str(lnd_type));
                         goto failed;
-#endif
-                        LNET_MUTEX_DOWN(&the_lnet.ln_lnd_mutex);
                 }
+#endif
 
                 ni->ni_refcount = 1;
 
@@ -849,45 +924,70 @@ lnet_startup_lndnis (void)
                 LNET_MUTEX_UP(&the_lnet.ln_lnd_mutex);
 
                 if (rc != 0) {
-                        CERROR("Error %d starting up NI %s\n",
-                               rc, libcfs_lnd2str(lnd->lnd_type));
+                        LCONSOLE_ERROR("Error %d starting up NI %s\n",
+                                       rc, libcfs_lnd2str(lnd->lnd_type));
                         LNET_LOCK();
                         lnd->lnd_refcount--;
                         LNET_UNLOCK();
                         goto failed;
                 }
 
-                if (lnd->lnd_type != LOLND) {
-                        if (ni->ni_peertxcredits == 0 ||
-                            ni->ni_maxtxcredits == 0) {
-                                LCONSOLE_ERROR("NI %s has no %scredits\n",
-                                               libcfs_lnd2str(lnd->lnd_type),
-                                               ni->ni_peertxcredits == 0 ?
-                                               "" : "per-peer ");
-                                goto failed;
-                        }
-
-                        ni->ni_txcredits = 
-                                ni->ni_mintxcredits = ni->ni_maxtxcredits;
-                        
-                        LCONSOLE(0, "Added NI %s [%d/%d]\n", 
-                                 libcfs_nid2str(ni->ni_nid),
-                                 ni->ni_peertxcredits, ni->ni_txcredits);
-
-                        /* Handle nidstrings for network 0 just like this one */
-                        if (the_lnet.ln_ptlcompat > 0)
-                                libcfs_setnet0alias(lnd->lnd_type);
-                }
-                
                 list_del(&ni->ni_list);
                 
                 LNET_LOCK();
                 list_add_tail(&ni->ni_list, &the_lnet.ln_nis);
                 LNET_UNLOCK();
+
+                if (lnd->lnd_type == LOLND) {
+                        lnet_ni_addref(ni);
+                        LASSERT (the_lnet.ln_loni == NULL);
+                        the_lnet.ln_loni = ni;
+                        continue;
+                }
+                
+#ifndef __KERNEL__
+                if (lnd->lnd_wait != NULL) {
+                        if (the_lnet.ln_eqwaitni == NULL) {
+                                lnet_ni_addref(ni);
+                                the_lnet.ln_eqwaitni = ni;
+                        }
+                } else {
+# if LNET_SINGLE_THREADED
+                        LCONSOLE_ERROR("LND %s not supported in a "
+                                       "single-threaded runtime\n",
+                                       libcfs_lnd2str(lnd_type));
+                        goto failed;
+# endif
+                }
+#endif
+                if (ni->ni_peertxcredits == 0 ||
+                    ni->ni_maxtxcredits == 0) {
+                        LCONSOLE_ERROR("NI %s has no %scredits\n",
+                                       libcfs_lnd2str(lnd->lnd_type),
+                                       ni->ni_peertxcredits == 0 ?
+                                       "" : "per-peer ");
+                        goto failed;
+                }
+
+                ni->ni_txcredits = ni->ni_mintxcredits = ni->ni_maxtxcredits;
+                        
+                LCONSOLE(0, "Added NI %s [%d/%d]\n", 
+                         libcfs_nid2str(ni->ni_nid),
+                         ni->ni_peertxcredits, ni->ni_txcredits);
+
+                /* Handle nidstrings for network 0 just like this one */
+                if (the_lnet.ln_ptlcompat > 0)
+                        libcfs_setnet0alias(lnd->lnd_type);
+
+                nicount++;
         }
 
-        lnet_loni = lnet_net2ni(PTL_MKNET(LOLND, 0));
-        LASSERT (lnet_loni != NULL);
+        if (nicount > 1 && the_lnet.ln_eqwaitni != NULL) {
+                lnd_type = the_lnet.ln_eqwaitni->ni_lnd->lnd_type;
+                LCONSOLE_ERROR("LND %s can only run single-network\n",
+                               libcfs_lnd2str(lnd_type));
+                goto failed;
+        }
 
         return 0;
         
@@ -906,39 +1006,19 @@ lnet_startup_lndnis (void)
 int
 LNetInit(void)
 {
-        lnet_assert_wire_constants ();
+        int    rc;
 
+        lnet_assert_wire_constants ();
         LASSERT (!the_lnet.ln_init);
+
+        rc = lnet_get_portals_compatibility();
+        if (rc < 0)
+                return rc;
         
-        the_lnet.ln_refcount = 0;
+        lnet_init_locks();
         CFS_INIT_LIST_HEAD(&the_lnet.ln_lnds);
-
-#ifdef __KERNEL__
-        spin_lock_init (&the_lnet.ln_lock);
-        cfs_waitq_init (&the_lnet.ln_waitq);
-        init_mutex(&the_lnet.ln_lnd_mutex);
-        init_mutex(&the_lnet.ln_api_mutex);
-
-        if (!strcmp(portals_compatibility, "none")) {
-                the_lnet.ln_ptlcompat = 0;
-        } else if (!strcmp(portals_compatibility, "weak")) {
-                the_lnet.ln_ptlcompat = 1;
-                LCONSOLE_WARN("Starting in weak portals-compatible mode\n");
-        } else if (!strcmp(portals_compatibility, "strong")) {
-                the_lnet.ln_ptlcompat = 2;
-                LCONSOLE_WARN("Starting in strong portals-compatible mode\n");
-        } else {
-                LCONSOLE_ERROR("portals_compatibility=\"%s\" not supported\n",
-                               portals_compatibility);
-                return -1;
-        }
-#else
-        pthread_mutex_init(&the_lnet.ln_mutex, NULL);
-        pthread_cond_init(&the_lnet.ln_cond, NULL);
-        pthread_mutex_init(&the_lnet.ln_lnd_mutex, NULL);
-        pthread_mutex_init(&the_lnet.ln_api_mutex, NULL);
-#endif
-
+        the_lnet.ln_ptlcompat = rc;
+        the_lnet.ln_refcount = 0;
         the_lnet.ln_init = 1;
 
 #ifdef __KERNEL__
@@ -948,11 +1028,13 @@ LNetInit(void)
 #else
         /* Register all LNDs that have been loaded
          * NB the order here determines default 'networks=' order */
+# if LNET_SINGLE_THREADED
         LNET_REGISTER_LND_IF_PRESENT(the_ptllnd);
+# else
         LNET_REGISTER_LND_IF_PRESENT(the_tcplnd);
+# endif
 #endif
         lnet_register_lnd(&the_lolnd);
-
         return 0;
 }
 
@@ -962,20 +1044,10 @@ LNetFini(void)
         LASSERT (the_lnet.ln_init);
         LASSERT (the_lnet.ln_refcount == 0);
 
-#ifdef __KERNEL__
-        /* LNDs unregister themselves when their module unloads */
-        lnet_unregister_lnd(&the_lolnd);
-        LASSERT (list_empty(&the_lnet.ln_lnds));
-#else
         while (!list_empty(&the_lnet.ln_lnds))
                 lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
                                                lnd_t, lnd_list));
-
-        pthread_mutex_destroy(&the_lnet.ln_api_mutex);
-        pthread_mutex_destroy(&the_lnet.ln_lnd_mutex);
-        pthread_cond_destroy(&the_lnet.ln_cond);
-        pthread_mutex_destroy(&the_lnet.ln_mutex);
-#endif
+        lnet_fini_locks();
 
         the_lnet.ln_init = 0;
 }
@@ -983,6 +1055,7 @@ LNetFini(void)
 int
 LNetNIInit(lnet_pid_t requested_pid)
 {
+        int         im_a_router = 0;
         int         rc;
 
         LNET_MUTEX_DOWN(&the_lnet.ln_api_mutex);
@@ -995,35 +1068,38 @@ LNetNIInit(lnet_pid_t requested_pid)
                 goto out;
         }
 
-        rc = lnet_init(requested_pid);
+        rc = lnet_prepare(requested_pid);
         if (rc != 0)
-                goto out;
+                goto failed0;
 
         rc = lnet_startup_lndnis();
-        if (rc != 0) {
-                lnet_fini();
-                goto out;
-        }
+        if (rc != 0)
+                goto failed1;
         
-        rc = lnet_parse_routes(lnet_get_routes());
-        if (rc != 0) {
-                lnet_shutdown_lndnis();
-                lnet_fini();
-                goto out;
-        }
+        rc = lnet_parse_routes(lnet_get_routes(), &im_a_router);
+        if (rc != 0)
+                goto failed2;
+
+        rc = lnet_alloc_rtrpools(im_a_router);
+        if (rc != 0)
+                goto failed3;
         
         rc = lnet_acceptor_start();
-        if (rc != 0) {
-                lnet_destroy_routes();
-                lnet_shutdown_lndnis();
-                lnet_fini();
-                goto out;
-        }
+        if (rc != 0)
+                goto failed3;
 
         lnet_proc_init();
-
         the_lnet.ln_refcount = 1;
+        goto out;
 
+ failed3:
+        lnet_destroy_routes();
+ failed2:
+        lnet_shutdown_lndnis();
+ failed1:
+        lnet_unprepare();
+ failed0:
+        LASSERT (rc < 0);
  out:
         LNET_MUTEX_UP(&the_lnet.ln_api_mutex);
         return rc;
@@ -1043,7 +1119,7 @@ LNetNIFini()
                 lnet_acceptor_stop();
                 lnet_destroy_routes();
                 lnet_shutdown_lndnis();
-                lnet_fini();
+                lnet_unprepare();
         }
 
         LNET_MUTEX_UP(&the_lnet.ln_api_mutex);
index 8594305..c0606b2 100644 (file)
@@ -1,7 +1,8 @@
 my_sources =    api-errno.c api-ni.c config.c \
                lib-me.c lib-msg.c lib-eq.c \
                lib-md.c lib-move.c lo.c \
-               router.c acceptor.c peer.c
+               router.c router_proc.c \
+               acceptor.c peer.c
 
 
 if LIBLUSTRE
index 56a5669..4306233 100644 (file)
@@ -541,7 +541,7 @@ lnet_parse_hops (char *str, unsigned int *hops)
 
 
 int
-lnet_parse_route (char *str)
+lnet_parse_route (char *str, int *im_a_router)
 {
        /* static scratch buffer OK (single threaded) */
        static char       cmd[LNET_SINGLE_TEXTBUF_NOB];
@@ -649,6 +649,11 @@ lnet_parse_route (char *str)
                        nid = libcfs_str2nid(ptb->ptb_text);
                        LASSERT (nid != LNET_NID_ANY);
 
+                        if (lnet_islocalnid(nid)) {
+                                *im_a_router = 1;
+                                continue;
+                        }
+                        
                         rc = lnet_add_route (net, hops, nid);
                         if (rc != 0) {
                                 CERROR("Can't create route "
@@ -672,14 +677,14 @@ lnet_parse_route (char *str)
 }
 
 int
-lnet_parse_route_tbs(struct list_head *tbs)
+lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router)
 {
        lnet_text_buf_t   *ptb;
 
        while (!list_empty(tbs)) {
                ptb = list_entry(tbs->next, lnet_text_buf_t, ptb_list);
 
-               if (lnet_parse_route(ptb->ptb_text) < 0) {
+               if (lnet_parse_route(ptb->ptb_text, im_a_router) < 0) {
                        lnet_free_text_bufs(tbs);
                        return -EINVAL;
                }
@@ -692,11 +697,13 @@ lnet_parse_route_tbs(struct list_head *tbs)
 }
 
 int
-lnet_parse_routes (char *routes)
+lnet_parse_routes (char *routes, int *im_a_router)
 {
        struct list_head  tbs;
        int               rc = 0;
 
+        *im_a_router = 0;
+
         if (the_lnet.ln_ptlcompat > 0 && 
             routes[0] != 0) {
                 /* Can't route when running in compatibility mode */
@@ -711,7 +718,7 @@ lnet_parse_routes (char *routes)
                CERROR("Error parsing routes\n");
                rc = -EINVAL;
        } else {
-                rc = lnet_parse_route_tbs(&tbs);
+                rc = lnet_parse_route_tbs(&tbs, im_a_router);
         }
 
        LASSERT (lnet_tbnob == 0);
index 9e3f480..ded9278 100644 (file)
@@ -182,6 +182,7 @@ LNetEQPoll (lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
         struct timeval   then;
         struct timeval   now;
         struct timespec  ts;
+        lnet_ni_t       *ni;
 #endif
         ENTRY;
 
@@ -210,9 +211,6 @@ LNetEQPoll (lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
                         RETURN (0);
                 }
 
-                /* Some architectures force us to do spin locking/unlocking
-                 * in the same stack frame, means we can abstract the
-                 * locking here */
 #ifdef __KERNEL__
                 cfs_waitlink_init(&wl);
                 set_current_state(TASK_INTERRUPTIBLE);
@@ -236,9 +234,23 @@ LNetEQPoll (lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
                 LNET_LOCK();
                 cfs_waitq_del(&the_lnet.ln_waitq, &wl);
 #else
+                ni = the_lnet.ln_eqwaitni;
+                if (ni != NULL) {
+                        lnet_ni_addref_locked(ni);
+                        LNET_UNLOCK();
+                        (ni->ni_lnd->lnd_wait)(ni, timeout_ms);
+                        LNET_LOCK();
+                        lnet_ni_decref_locked(ni);
+                        continue;
+                }
+
+# if LNET_SINGLE_THREADED
+                LNET_UNLOCK();
+                return -ENOENT;
+# else
                 if (timeout_ms < 0) {
                         pthread_cond_wait(&the_lnet.ln_cond, 
-                                          &the_lnet.ln_mutex);
+                                          &the_lnet.ln_lock);
                 } else {
                         gettimeofday(&then, NULL);
                         
@@ -251,7 +263,7 @@ LNetEQPoll (lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
                         }
                         
                         pthread_cond_timedwait(&the_lnet.ln_cond,
-                                               &the_lnet.ln_mutex, &ts);
+                                               &the_lnet.ln_lock, &ts);
                         
                         gettimeofday(&now, NULL);
                         timeout_ms -= (now.tv_sec - then.tv_sec) * 1000 +
@@ -260,6 +272,7 @@ LNetEQPoll (lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
                         if (timeout_ms < 0)
                                 timeout_ms = 0;
                 }
+# endif
 #endif
         }
 }
index fa73aba..35f92e0 100644 (file)
@@ -1187,13 +1187,14 @@ lnet_send(lnet_ni_t *ni, lnet_msg_t *msg)
                 
                         /* send via lo0? */
                         if (implicit_loopback &&
+                            the_lnet.ln_loni != NULL &&
                             lnet_ptlcompat_matchnid(src_ni->ni_nid, dst_nid)) {
                                 lnet_ni_decref_locked(src_ni);
-                                src_ni = lnet_loni;
+                                src_ni = the_lnet.ln_loni;
                                 lnet_ni_addref_locked(src_ni);
                         }
 
-                        if (src_ni == lnet_loni) {
+                        if (src_ni == the_lnet.ln_loni) {
                                 /* No send credit hassles with LOLND */
                                 LNET_UNLOCK();
                                 
@@ -1226,14 +1227,6 @@ lnet_send(lnet_ni_t *ni, lnet_msg_t *msg)
                         CERROR("No route to %s\n", libcfs_id2str(msg->msg_target));
                         return -EHOSTUNREACH;
                 }
-                src_ni = rnet->lrn_ni;
-
-                if (!msg->msg_routing) {
-                        /* I'm the source and now I know which NI to send on */
-                        src_nid = lnet_ptlcompat_srcnid(src_ni->ni_nid, dst_nid);
-                        msg->msg_hdr.src_nid = cpu_to_le64(src_nid);
-                        msg->msg_hdr.src_pid = cpu_to_le32(the_lnet.ln_pid);
-                }
 
                 /* Find the best gateway I can use */
                 lp = NULL;
@@ -1241,13 +1234,8 @@ lnet_send(lnet_ni_t *ni, lnet_msg_t *msg)
                         route = list_entry(tmp, lnet_route_t, lr_list);
                         lp2 = route->lr_gateway;
 
-                        LASSERT (lp2->lp_ni == src_ni);
-                        
-                        if (!lp2->lp_alive)
-                                continue;
-                        
-                        if (lp == NULL ||
-                            lnet_compare_routers(lp2, lp))
+                        if (lp2->lp_alive &&
+                            (lp == NULL || lnet_compare_routers(lp2, lp)))
                                 lp = lp2;
                 }
 
@@ -1259,6 +1247,14 @@ lnet_send(lnet_ni_t *ni, lnet_msg_t *msg)
                 }
 
                 lnet_peer_addref_locked(lp);
+                src_ni = rnet->lrn_ni;
+
+                if (!msg->msg_routing) {
+                        /* I'm the source and now I know which NI to send on */
+                        src_nid = lnet_ptlcompat_srcnid(src_ni->ni_nid, dst_nid);
+                        msg->msg_hdr.src_nid = cpu_to_le64(src_nid);
+                        msg->msg_hdr.src_pid = cpu_to_le32(the_lnet.ln_pid);
+                }
 
                 msg->msg_target_is_router = 1;
                 msg->msg_target.nid = lp->lp_nid;
index ace7f9b..c95464f 100644 (file)
@@ -52,12 +52,17 @@ lnet_enq_event_locked (lnet_eq_t *eq, lnet_event_t *ev)
         if (eq->eq_callback != NULL)
                 eq->eq_callback (eq_slot);
 
-        /* Wake anyone sleeping for an event (see lib-eq.c) */
 #ifdef __KERNEL__
+        /* Wake anyone waiting in LNetEQPoll() */
         if (cfs_waitq_active(&the_lnet.ln_waitq))
                 cfs_waitq_broadcast(&the_lnet.ln_waitq);
 #else
+# if LNET_SINGLE_THREADED
+        /* LNetEQPoll() calls into _the_ LND to wait for action */
+# else
+        /* Wake anyone waiting in LNetEQPoll() */
         pthread_cond_broadcast(&the_lnet.ln_cond);
+# endif
 #endif
 }
 
index b5e2229..43b4f0d 100644 (file)
@@ -102,4 +102,3 @@ lnd_t the_lolnd = {
         .lnd_recv       = lolnd_recv,
 };
 
-lnet_ni_t *lnet_loni;
index 5001d77..bba9844 100644 (file)
@@ -25,9 +25,9 @@
 
 #ifdef __KERNEL__
 
-static int forwarding = 0;
-CFS_MODULE_PARM(forwarding, "i", int, 0444,
-                "Boolean: set non-zero to forward between networks");
+static char *forwarding = "";
+CFS_MODULE_PARM(forwarding, "s", charp, 0444,
+                "Explicitly enable/disable forwarding between networks");
 
 static int tiny_router_buffers = 512;
 CFS_MODULE_PARM(tiny_router_buffers, "i", int, 0444,
@@ -238,21 +238,21 @@ lnet_distance (lnet_nid_t nid, int *orderp)
 int
 lnet_add_route (__u32 net, unsigned int hops, lnet_nid_t gateway)
 {
+        struct list_head     zombies;
        struct list_head    *e;
        lnet_remotenet_t    *rnet;
        lnet_remotenet_t    *rnet2;
        lnet_route_t        *route;
        lnet_route_t        *route2;
         lnet_peer_t         *lp;
-        int                  dup;
-        int                  hops2;
-        __u32                net2;
         int                  rc;
 
         CDEBUG(D_NET, "Add route: net %s hops %u gw %s\n",
                libcfs_net2str(net), hops, libcfs_nid2str(gateway));
 
         if (gateway == LNET_NID_ANY ||
+            net == PTL_NIDNET(LNET_NID_ANY) ||
+            PTL_NIDNET(gateway) == net ||
             hops < 1 || hops > 255)
                 return (-EINVAL);
 
@@ -311,53 +311,55 @@ lnet_add_route (__u32 net, unsigned int hops, lnet_nid_t gateway)
                 return 0;
         }
 
-        hops2 = rnet2->lrn_hops;
-        net2 = PTL_NIDNET(rnet2->lrn_ni->ni_nid);
-
-        if (rnet2->lrn_ni == lp->lp_ni && hops2 == hops) {
-                /* New route consistent with existing routes; search for
-                 * duplicate route (NOOP if this is) */
-                dup = 0;
-                list_for_each (e, &rnet2->lrn_routes) {
-                        route2 = list_entry(e, lnet_route_t, lr_list);
-
-                        if (route2->lr_gateway->lp_nid == gateway) {
-                                dup = 1;
-                                break;
-                        }
-                }
-
-                if (!dup) {
-                        /* New route */
-                        list_add_tail(&route->lr_list, &rnet2->lrn_routes);
-                        the_lnet.ln_remote_nets_version++;
-                } else {
-                        lnet_peer_decref_locked(lp);
-                }
-
+        if (rnet2->lrn_hops < hops) {
+                /* new route is longer than ones we have already: 
+                 * Ignore it silently */
+                LNET_UNLOCK();
+                PORTAL_FREE(route, sizeof(*route));
+                goto out;
+        }
+        
+        if (rnet2->lrn_hops > hops) {
+                /* new route supercedes all currently known routes to this
+                 * net */
+                list_add(&zombies, &rnet2->lrn_routes);
+                list_del_init(&rnet2->lrn_routes);
+                list_add(&route->lr_list, &rnet2->lrn_routes);
+                the_lnet.ln_remote_nets_version++;
                 LNET_UNLOCK();
 
-                PORTAL_FREE(rnet, sizeof(*rnet));
-                if (dup)
+                while (!list_empty(&zombies)) {
+                        route = list_entry(zombies.next, lnet_route_t, lr_list);
+                        list_del(&route->lr_list);
+                        
+                        LNET_LOCK();
+                        lnet_peer_decref_locked(route->lr_gateway);
+                        LNET_UNLOCK();
                         PORTAL_FREE(route, sizeof(*route));
-
-                return 0;
+                }
+                goto out;
         }
+        
+        /* New route has the same hopcount as existing routes; search for
+         * a duplicate route (it's a NOOP if it is) */
+        list_for_each (e, &rnet2->lrn_routes) {
+                route2 = list_entry(e, lnet_route_t, lr_list);
 
-        lnet_peer_decref_locked(lp);
+                if (route2->lr_gateway->lp_nid == gateway) {
+                        LNET_UNLOCK();
+                        PORTAL_FREE(route, sizeof(*route));
+                        goto out;
+                }
+        }
+        
+        /* Add the new route */
+        list_add_tail(&route->lr_list, &rnet2->lrn_routes);
+        the_lnet.ln_remote_nets_version++;
         LNET_UNLOCK();
+
+ out:
         PORTAL_FREE(rnet, sizeof(*rnet));
-        PORTAL_FREE(route, sizeof(*route));
-
-        if (hops != hops2)
-                CERROR("Hopcount not consistent on route: %s %d(%d) %s\n",
-                       libcfs_net2str(net), hops, hops2,
-                       libcfs_nid2str(gateway));
-        else
-                CERROR("Router network not consistent on route: %s %d %s(%s)\n",
-                       libcfs_net2str(net), hops,
-                       libcfs_nid2str(gateway), libcfs_net2str(net2));
-        return -EINVAL;
+        return 0;
 }
 
 int
@@ -534,6 +536,11 @@ lnet_rtrpool_alloc_bufs(lnet_rtrbufpool_t *rbp, int nbufs)
         lnet_rtrbuf_t *rb;
         int            i;
 
+        if (rbp->rbp_nbuffers != 0) {
+                LASSERT (rbp->rbp_nbuffers == nbufs);
+                return 0;
+        }
+        
         for (i = 0; i < nbufs; i++) {
                 rb = lnet_new_rtrbuf(rbp);
 
@@ -547,8 +554,9 @@ lnet_rtrpool_alloc_bufs(lnet_rtrbufpool_t *rbp, int nbufs)
                 rbp->rbp_credits++;
                 list_add(&rb->rb_list, &rbp->rbp_bufs);
 
-                /* NB if this is live there need to be code to schedule blocked
-                 * msgs */
+                /* No allocation "under fire" */
+                /* Otherwise we'd need code to schedule blocked msgs etc */
+                LASSERT (!the_lnet.ln_routing);
         }
 
         LASSERT (rbp->rbp_credits == nbufs);
@@ -574,8 +582,8 @@ lnet_free_rtrpools(void)
         lnet_rtrpool_free_bufs(&the_lnet.ln_rtrpools[2]);
 }
 
-int
-lnet_alloc_rtrpools(void)
+void
+lnet_init_rtrpools(void)
 {
         int small_pages = 1;
         int large_pages = (PTL_MTU + PAGE_SIZE - 1) / PAGE_SIZE;
@@ -584,15 +592,29 @@ lnet_alloc_rtrpools(void)
         lnet_rtrpool_init(&the_lnet.ln_rtrpools[0], 0);
         lnet_rtrpool_init(&the_lnet.ln_rtrpools[1], small_pages);
         lnet_rtrpool_init(&the_lnet.ln_rtrpools[2], large_pages);
+}
 
-        for (rc = 0; rc < LNET_NRBPOOLS; rc++)
-                CDEBUG(D_NET, "Pages[%d]: %d\n", rc,
-                       the_lnet.ln_rtrpools[rc].rbp_npages);
 
-        the_lnet.ln_routing = forwarding;
-        if (!forwarding)
+int
+lnet_alloc_rtrpools(int im_a_router)
+{
+        int       rc;
+        
+        if (!strcmp(forwarding, "")) {
+                /* not set either way */
+                if (!im_a_router)
+                        return 0;
+        } else if (!strcmp(forwarding, "disabled")) {
+                /* explicitly disabled */
                 return 0;
-
+        } else if (!strcmp(forwarding, "enabled")) {
+                /* explicitly enabled */
+        } else {
+                LCONSOLE_ERROR("'forwarding' not set to either "
+                               "'enabled' or 'disabled'\n");
+                return -EINVAL;
+        }
+        
         if (tiny_router_buffers <= 0) {
                 LCONSOLE_ERROR("tiny_router_buffers=%d invalid when "
                                "routing enabled\n", tiny_router_buffers);
@@ -629,6 +651,10 @@ lnet_alloc_rtrpools(void)
         if (rc != 0)
                 goto failed;
 
+        LNET_LOCK();
+        the_lnet.ln_routing = 1;
+        LNET_UNLOCK();
+        
         return 0;
 
  failed:
@@ -643,12 +669,15 @@ lnet_free_rtrpools (void)
 {
 }
 
+void
+lnet_init_rtrpools (void)
+{
+}
+
 int
-lnet_alloc_rtrpools (void)
+lnet_alloc_rtrpools (int im_a_arouter)
 {
-        /* No userspace routing */
-        the_lnet.ln_routing = 0;
-        return 0;
+        return -EOPNOTSUPP;
 }
 
 #endif
index a1ca3c7..e1cbcdc 100644 (file)
@@ -22,6 +22,9 @@
  */
 
 #include <lnet/lib-lnet.h>
+
+#ifdef __KERNEL__
+
 #include <linux/seq_file.h>
 #include <linux/lustre_compat25.h>
 
@@ -820,3 +823,17 @@ lnet_proc_fini(void)
         remove_proc_entry(LNET_PROC_BUFFERS, 0);
         remove_proc_entry(LNET_PROC_NIS, 0);
 }
+
+#else
+
+void 
+lnet_proc_init(void)
+{
+}
+
+void 
+lnet_proc_fini(void)
+{
+}
+
+#endif
index 54e6c05..af64fef 100644 (file)
 
 #include <portals/p30.h>
 
+typedef struct
+{
+        ptl_handle_ni_t            pls_ni;
+        ptl_handle_eq_t            pls_eq;
+
+} ptllnd_state;
+
 extern int ptllnd_startup(struct lnet_ni *ni);
 extern void ptllnd_shutdown(struct lnet_ni *ni);
 extern int ptllnd_send(struct lnet_ni *ni, void *private, lnet_msg_t *msg);
index 817049b..7397da1 100644 (file)
 # include <sys/utsname.h>
 #endif
 
+#if LNET_SINGLE_THREADED
+# error "This LND requires a multi-threaded runtime"
+#endif
+
 /* XXX CFS workaround, to give a chance to let nal thread wake up
  * from waiting in select
  */
diff --git a/lnet/ulnds/socklnd/utypes.h b/lnet/ulnds/socklnd/utypes.h
deleted file mode 100644 (file)
index 7eca959..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- *  Copyright (c) 2002 Cray Inc.
- *
- *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
- */
-
-typedef unsigned short uint16;
-typedef unsigned long uint32;
-typedef unsigned long long uint64;
-typedef unsigned char uint8;