From b57a1a885d6a327b13f75d7455f7d4920769d294 Mon Sep 17 00:00:00 2001 From: eeb Date: Fri, 23 Sep 2005 14:30:47 +0000 Subject: [PATCH] * Changed parsing of 'routes=' to allow routes via different networks with 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. --- lnet/include/lnet/lib-lnet.h | 41 ++++-- lnet/include/lnet/lib-types.h | 35 +++-- lnet/lnet/api-ni.c | 302 ++++++++++++++++++++++++++---------------- lnet/lnet/autoMakefile.am | 3 +- lnet/lnet/config.c | 17 ++- lnet/lnet/lib-eq.c | 23 +++- lnet/lnet/lib-move.c | 30 ++--- lnet/lnet/lib-msg.c | 7 +- lnet/lnet/lo.c | 1 - lnet/lnet/router.c | 149 ++++++++++++--------- lnet/lnet/router_proc.c | 17 +++ lnet/ulnds/ptllnd/ptllnd.h | 7 + lnet/ulnds/socklnd/procapi.c | 4 + lnet/ulnds/socklnd/utypes.h | 12 -- 14 files changed, 408 insertions(+), 240 deletions(-) delete mode 100644 lnet/ulnds/socklnd/utypes.h diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h index 6ad03f0..36226ae 100644 --- a/lnet/include/lnet/lib-lnet.h +++ b/lnet/include/lnet/lib-lnet.h @@ -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); diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h index cfb830e..0041359 100644 --- a/lnet/include/lnet/lib-types.h +++ b/lnet/include/lnet/lib-types.h @@ -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 */ diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index 112dc40..b41c1ec 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -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); diff --git a/lnet/lnet/autoMakefile.am b/lnet/lnet/autoMakefile.am index 8594305..c0606b2 100644 --- a/lnet/lnet/autoMakefile.am +++ b/lnet/lnet/autoMakefile.am @@ -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 diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c index 56a5669..4306233 100644 --- a/lnet/lnet/config.c +++ b/lnet/lnet/config.c @@ -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); diff --git a/lnet/lnet/lib-eq.c b/lnet/lnet/lib-eq.c index 9e3f480..ded9278 100644 --- a/lnet/lnet/lib-eq.c +++ b/lnet/lnet/lib-eq.c @@ -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 } } diff --git a/lnet/lnet/lib-move.c b/lnet/lnet/lib-move.c index fa73aba..35f92e0 100644 --- a/lnet/lnet/lib-move.c +++ b/lnet/lnet/lib-move.c @@ -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; diff --git a/lnet/lnet/lib-msg.c b/lnet/lnet/lib-msg.c index ace7f9b..c95464f 100644 --- a/lnet/lnet/lib-msg.c +++ b/lnet/lnet/lib-msg.c @@ -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 } diff --git a/lnet/lnet/lo.c b/lnet/lnet/lo.c index b5e2229..43b4f0d 100644 --- a/lnet/lnet/lo.c +++ b/lnet/lnet/lo.c @@ -102,4 +102,3 @@ lnd_t the_lolnd = { .lnd_recv = lolnd_recv, }; -lnet_ni_t *lnet_loni; diff --git a/lnet/lnet/router.c b/lnet/lnet/router.c index 5001d77..bba9844 100644 --- a/lnet/lnet/router.c +++ b/lnet/lnet/router.c @@ -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 diff --git a/lnet/lnet/router_proc.c b/lnet/lnet/router_proc.c index a1ca3c7..e1cbcdc 100644 --- a/lnet/lnet/router_proc.c +++ b/lnet/lnet/router_proc.c @@ -22,6 +22,9 @@ */ #include + +#ifdef __KERNEL__ + #include #include @@ -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 diff --git a/lnet/ulnds/ptllnd/ptllnd.h b/lnet/ulnds/ptllnd/ptllnd.h index 54e6c05..af64fef 100644 --- a/lnet/ulnds/ptllnd/ptllnd.h +++ b/lnet/ulnds/ptllnd/ptllnd.h @@ -28,6 +28,13 @@ #include +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); diff --git a/lnet/ulnds/socklnd/procapi.c b/lnet/ulnds/socklnd/procapi.c index 817049b..7397da1 100644 --- a/lnet/ulnds/socklnd/procapi.c +++ b/lnet/ulnds/socklnd/procapi.c @@ -46,6 +46,10 @@ # include #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 index 7eca959..0000000 --- a/lnet/ulnds/socklnd/utypes.h +++ /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; -- 1.8.3.1