X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lnet%2Flnet%2Fconfig.c;h=b18c103ccd2b5277b7c9116e83faf4ab01bbd7cd;hb=ad32c0736a971f74cbf5e750c6cae90320ec2589;hp=a20044b29aaa2fb536a01f4e939ddc0f606c80ce;hpb=a07e9d350b3e500c7be877f6dcf54380b86a9cbe;p=fs%2Flustre-release.git diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c index a20044b..b18c103 100644 --- a/lnet/lnet/config.c +++ b/lnet/lnet/config.c @@ -26,6 +26,8 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -100,6 +102,9 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_tx_queues != NULL) cfs_percpt_free(ni->ni_tx_queues); + if (ni->ni_cpts != NULL) + cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts); + #ifndef __KERNEL__ # ifdef HAVE_LIBPTHREAD pthread_mutex_destroy(&ni->ni_lock); @@ -109,10 +114,11 @@ lnet_ni_free(struct lnet_ni *ni) } lnet_ni_t * -lnet_ni_alloc(__u32 net, cfs_list_t *nilist) +lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, cfs_list_t *nilist) { struct lnet_tx_queue *tq; struct lnet_ni *ni; + int rc; int i; if (!lnet_net_unique(net, nilist)) { @@ -129,12 +135,13 @@ lnet_ni_alloc(__u32 net, cfs_list_t *nilist) } #ifdef __KERNEL__ - cfs_spin_lock_init(&ni->ni_lock); + spin_lock_init(&ni->ni_lock); #else # ifdef HAVE_LIBPTHREAD pthread_mutex_init(&ni->ni_lock, NULL); # endif #endif + CFS_INIT_LIST_HEAD(&ni->ni_cptlist); ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*ni->ni_refs[0])); if (ni->ni_refs == NULL) @@ -148,11 +155,31 @@ lnet_ni_alloc(__u32 net, cfs_list_t *nilist) cfs_percpt_for_each(tq, i, ni->ni_tx_queues) CFS_INIT_LIST_HEAD(&tq->tq_delayed); - /* LND will fill in the address part of the NID */ - ni->ni_nid = LNET_MKNID(net, 0); - ni->ni_last_alive = cfs_time_current(); - cfs_list_add_tail(&ni->ni_list, nilist); - return ni; + if (el == NULL) { + ni->ni_cpts = NULL; + ni->ni_ncpts = LNET_CPT_NUMBER; + } else { + rc = cfs_expr_list_values(el, LNET_CPT_NUMBER, &ni->ni_cpts); + if (rc <= 0) { + CERROR("Failed to set CPTs for NI %s: %d\n", + libcfs_net2str(net), rc); + goto failed; + } + + LASSERT(rc <= LNET_CPT_NUMBER); + if (rc == LNET_CPT_NUMBER) { + LIBCFS_FREE(ni->ni_cpts, rc * sizeof(ni->ni_cpts[0])); + ni->ni_cpts = NULL; + } + + ni->ni_ncpts = rc; + } + + /* LND will fill in the address part of the NID */ + ni->ni_nid = LNET_MKNID(net, 0); + ni->ni_last_alive = cfs_time_current_sec(); + cfs_list_add_tail(&ni->ni_list, nilist); + return ni; failed: lnet_ni_free(ni); return NULL; @@ -161,12 +188,14 @@ lnet_ni_alloc(__u32 net, cfs_list_t *nilist) int lnet_parse_networks(cfs_list_t *nilist, char *networks) { - int tokensize = strlen(networks) + 1; - char *tokens; - char *str; - lnet_ni_t *ni; - __u32 net; - int nnets = 0; + struct cfs_expr_list *el = NULL; + int tokensize = strlen(networks) + 1; + char *tokens; + char *str; + char *tmp; + struct lnet_ni *ni; + __u32 net; + int nnets = 0; if (strlen(networks) > LNET_SINGLE_TEXTBUF_NOB) { /* _WAY_ conservative */ @@ -184,21 +213,48 @@ lnet_parse_networks(cfs_list_t *nilist, char *networks) the_lnet.ln_network_tokens = tokens; the_lnet.ln_network_tokens_nob = tokensize; memcpy (tokens, networks, tokensize); - str = tokens; + str = tmp = tokens; /* Add in the loopback network */ - ni = lnet_ni_alloc(LNET_MKNET(LOLND, 0), nilist); + ni = lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, nilist); if (ni == NULL) goto failed; - while (str != NULL && *str != 0) { - char *comma = strchr(str, ','); - char *bracket = strchr(str, '('); - int niface; - char *iface; + while (str != NULL && *str != 0) { + char *comma = strchr(str, ','); + char *bracket = strchr(str, '('); + char *square = strchr(str, '['); + char *iface; + int niface; + int rc; + + /* NB we don't check interface conflicts here; it's the LNDs + * responsibility (if it cares at all) */ + + if (square != NULL && (comma == NULL || square < comma)) { + /* i.e: o2ib0(ib0)[1,2], number between square + * brackets are CPTs this NI needs to be bond */ + if (bracket != NULL && bracket > square) { + tmp = square; + goto failed_syntax; + } + + tmp = strchr(square, ']'); + if (tmp == NULL) { + tmp = square; + goto failed_syntax; + } + + rc = cfs_expr_list_parse(square, tmp - square + 1, + 0, LNET_CPT_NUMBER - 1, &el); + if (rc != 0) { + tmp = square; + goto failed_syntax; + } - /* NB we don't check interface conflicts here; it's the LNDs - * responsibility (if it cares at all) */ + while (square <= tmp) + *square++ = ' '; + } if (bracket == NULL || (comma != NULL && comma < bracket)) { @@ -210,16 +266,20 @@ lnet_parse_networks(cfs_list_t *nilist, char *networks) net = libcfs_str2net(cfs_trimwhite(str)); if (net == LNET_NIDNET(LNET_NID_ANY)) { - lnet_syntax("networks", networks, - (int)(str - tokens), strlen(str)); LCONSOLE_ERROR_MSG(0x113, "Unrecognised network" " type\n"); - goto failed; + tmp = str; + goto failed_syntax; } if (LNET_NETTYP(net) != LOLND && /* LO is implicit */ - lnet_ni_alloc(net, nilist) == NULL) - goto failed; + lnet_ni_alloc(net, el, nilist) == NULL) + goto failed; + + if (el != NULL) { + cfs_expr_list_free(el); + el = NULL; + } str = comma; continue; @@ -228,24 +288,27 @@ lnet_parse_networks(cfs_list_t *nilist, char *networks) *bracket = 0; net = libcfs_str2net(cfs_trimwhite(str)); if (net == LNET_NIDNET(LNET_NID_ANY)) { - lnet_syntax("networks", networks, - (int)(str - tokens), strlen(str)); - goto failed; + tmp = str; + goto failed_syntax; } - nnets++; - ni = lnet_ni_alloc(net, nilist); - if (ni == NULL) - goto failed; + nnets++; + ni = lnet_ni_alloc(net, el, nilist); + if (ni == NULL) + goto failed; + + if (el != NULL) { + cfs_expr_list_free(el); + el = NULL; + } - niface = 0; + niface = 0; iface = bracket + 1; bracket = strchr(iface, ')'); if (bracket == NULL) { - lnet_syntax("networks", networks, - (int)(iface - tokens), strlen(iface)); - goto failed; + tmp = iface; + goto failed_syntax; } *bracket = 0; @@ -256,10 +319,8 @@ lnet_parse_networks(cfs_list_t *nilist, char *networks) iface = cfs_trimwhite(iface); if (*iface == 0) { - lnet_syntax("networks", networks, - (int)(iface - tokens), - strlen(iface)); - goto failed; + tmp = iface; + goto failed_syntax; } if (niface == LNET_MAX_INTERFACES) { @@ -279,9 +340,8 @@ lnet_parse_networks(cfs_list_t *nilist, char *networks) *comma = 0; str = cfs_trimwhite(str); if (*str != 0) { - lnet_syntax("networks", networks, - (int)(str - tokens), strlen(str)); - goto failed; + tmp = str; + goto failed_syntax; } str = comma + 1; continue; @@ -289,22 +349,27 @@ lnet_parse_networks(cfs_list_t *nilist, char *networks) str = cfs_trimwhite(str); if (*str != 0) { - lnet_syntax("networks", networks, - (int)(str - tokens), strlen(str)); - goto failed; - } + tmp = str; + goto failed_syntax; + } } - LASSERT (!cfs_list_empty(nilist)); - return 0; + LASSERT(!cfs_list_empty(nilist)); + return 0; + failed_syntax: + lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp)); failed: - while (!cfs_list_empty(nilist)) { - ni = cfs_list_entry(nilist->next, lnet_ni_t, ni_list); + while (!cfs_list_empty(nilist)) { + ni = cfs_list_entry(nilist->next, lnet_ni_t, ni_list); cfs_list_del(&ni->ni_list); lnet_ni_free(ni); } + + if (el != NULL) + cfs_expr_list_free(el); + LIBCFS_FREE(tokens, tokensize); the_lnet.ln_network_tokens = NULL;