From jsimmons at infradead.org Tue Sep 4 18:35:10 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 4 Sep 2018 19:35:10 +0100 (BST) Subject: [lustre-devel] fixing last lctl set_param -P problem Message-ID: I originally posted this in the LU-7004 jira ticket : https://jira.whamcloud.com/browse/LU-7004 but no one has replied so I thought it would be good to post here. So this is last regression with lctl set_param -P. Some test use the form get the parameter value: lctl set_param osc.lustre-OST0001-osc-[^M]*.active=1 The shell seems to expand this properly or the get_param routine parses this correctly. Now if I run on the MGS lctl set_param -P osc.lustre-OST0001-osc[^M]*.active=1 then the [^M] is actually cached in the config logs. The function obdname2fsname() chokes on this wildcard. So the question is how to handle this. I see the following option: 1) Make the shell expand the [^M] to some value before passing the string to lctl itself. Have to look at this. 2) Use regex or something in the C code of lctl to expand this out before packing the data for the ioctl on the MGS. 3) Change the test scripts to drop the [^M] for lctl set_param -P. Which is the best option? From neilb at suse.com Tue Sep 4 22:02:10 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 05 Sep 2018 08:02:10 +1000 Subject: [lustre-devel] fixing last lctl set_param -P problem In-Reply-To: References: Message-ID: <87tvn4vs4d.fsf@notabene.neil.brown.name> On Tue, Sep 04 2018, James Simmons wrote: > I originally posted this in the LU-7004 jira ticket : > > https://jira.whamcloud.com/browse/LU-7004 > > but no one has replied so I thought it would be good to post here. > > So this is last regression with lctl set_param -P. Some test use the form > get the parameter value: > > lctl set_param osc.lustre-OST0001-osc-[^M]*.active=1 > > The shell seems to expand this properly or the get_param routine parses > this correctly. It isn't "The shell" that does the expansion, it is the glob() library function. According to "man 7 glob", the correct syntax for an inverted character set is [!M] not [^M] ([^M] is for regexp, [!M] is for glob. Bash confused people by accepting both for glob). > > Now if I run on the MGS lctl set_param -P osc.lustre-OST0001-osc[^M]*.active=1 > then the [^M] is actually cached in the config logs. The function > obdname2fsname() chokes on this wildcard. So the question is how to handle this. > I see the following option: > > 1) Make the shell expand the [^M] to some value before passing the string > to lctl itself. Have to look at this. > > 2) Use regex or something in the C code of lctl to expand this out before > packing the data for the ioctl on the MGS. > > 3) Change the test scripts to drop the [^M] for lctl set_param -P. 4) Change the test script to use the correct syntax: [!M] NeilBrown > > Which is the best option? > > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 00/34] Beginning of multi-rail support for drivers/staging/lustre Message-ID: <153628058697.8267.6056114844033479774.stgit@noble> The following series implements the first patch in the multi-rail series: Commit: 8cbb8cd3e771 ("LU-7734 lnet: Multi-Rail local NI split") I split that commit up into 40 individual commits which can be found at https://github.com/neilbrown/lustre/commits/multirail though you need to scroll down a bit, as that contains all the multi-rail series. I then ported most of these patches to my mainline tree. Some that I haven't included are: - lnet: Move lnet_msg_alloc/free down a bit. lnet_msg_alloc/free don't exist any more - lnet: lib-types: change some tabs to spaces - lnet - assorted whitespace changes. - lnet: change ni_last_alive from time64_t to long - lnet: add lnet_net_state net_state is never used. - lnet: remove 'static' from lnet_get_net_config() I've also made a couple of minor changes to individual patches not strictly related to porting (the net_prio field is never used, so I never added it - I should have made that a separate patch). This series compiles, but doesn't work. I get a NULL pointer reference, then an assertion failure. If I fix those, it hangs. The NULL pointer ref and the failing assertion are gone with later patches, so I hope the other problems are too. Some of these patches have very poor descriptions, such as "I have no idea what this does". If someone would like to explain - or maybe say "Oh, we really shouldn't have done that", I'd be very happy to receive that, and update the description or patch accordingly. These will all appear in my lustre-testing branch, but won't migrate to 'lustre' until I, at least, have enough other patches that I can get a successful test run. Review and comments always welcome. Thanks, NeilBrown --- Amir Shehata (1): Completely re-write lnet_parse_networks(). NeilBrown (33): struct lnet_ni - reformat comments. lnet: Create struct lnet_net lnet: struct lnet_ni: move ni_lnd to lnet_net lnet: embed lnd_tunables in lnet_ni lnet: begin separating "networks" from "network interfaces". lnet: store separate xmit/recv net-interface in each message. lnet: change lnet_peer to reference the net, rather than ni. lnet: add cpt to lnet_match_info. lnet: add list of cpts to lnet_net. lnet: add ni arg to lnet_cpt_of_nid() lnet: pass tun to lnet_startup_lndni, instead of full conf lnet: split lnet_startup_lndni lnet: reverse order of lnet_startup_lnd{net,ni} lnet: rename lnet_find_net_locked to lnet_find_rnet_locked lnet: extend zombie handling to nets and nis lnet: lnet_shutdown_lndnets - remove some cleanup code. lnet: move lnet_shutdown_lndnets down to after first use lnet: add ni_state lnet: simplify lnet_islocalnet() lnet: discard ni_cpt_list lnet: add net_ni_added lnet: don't take reference in lnet_XX2ni_locked() lnet: don't need lock to test ln_shutdown. lnet: don't take lock over lnet_net_unique() lnet: swap 'then' and 'else' branches in lnet_startup_lndnet lnet: only valid lnd_type when net_id is unique. lnet: make it possible to add a new interface to a network lnet: add checks to ensure network interface names are unique. lnet: track tunables in lnet_startup_lndnet() lnet: fix typo lnet: lnet_dyn_add_ni: fix ping_info count lnet: lnet_dyn_del_ni: fix ping_info count lnet: introduce use_tcp_bonding mod param .../staging/lustre/include/linux/lnet/lib-lnet.h | 31 - .../staging/lustre/include/linux/lnet/lib-types.h | 142 ++- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 18 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 10 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 6 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 12 .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 74 +- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 25 - drivers/staging/lustre/lnet/lnet/acceptor.c | 8 drivers/staging/lustre/lnet/lnet/api-ni.c | 939 +++++++++++++------- drivers/staging/lustre/lnet/lnet/config.c | 688 +++++++++++---- drivers/staging/lustre/lnet/lnet/lib-move.c | 132 ++- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 6 drivers/staging/lustre/lnet/lnet/lo.c | 2 drivers/staging/lustre/lnet/lnet/net_fault.c | 3 drivers/staging/lustre/lnet/lnet/peer.c | 31 - drivers/staging/lustre/lnet/lnet/router.c | 51 + drivers/staging/lustre/lnet/lnet/router_proc.c | 24 - drivers/staging/lustre/lnet/selftest/brw_test.c | 2 drivers/staging/lustre/lnet/selftest/framework.c | 3 drivers/staging/lustre/lnet/selftest/selftest.h | 2 21 files changed, 1507 insertions(+), 702 deletions(-) -- Signature From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 01/34] struct lnet_ni - reformat comments. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137125.8267.7825080417267355121.stgit@noble> This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split --- .../staging/lustre/include/linux/lnet/lib-types.h | 38 +++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 6d4106fd9039..078bc97a9ebf 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -263,18 +263,38 @@ struct lnet_ni { int ni_peerrtrcredits; /* seconds to consider peer dead */ int ni_peertimeout; - int ni_ncpts; /* number of CPTs */ - __u32 *ni_cpts; /* bond NI on some CPTs */ - lnet_nid_t ni_nid; /* interface's NID */ - void *ni_data; /* instance-specific data */ + /* number of CPTs */ + int ni_ncpts; + + /* bond NI on some CPTs */ + __u32 *ni_cpts; + + /* interface's NID */ + lnet_nid_t ni_nid; + + /* instance-specific data */ + void *ni_data; + struct lnet_lnd *ni_lnd; /* procedural interface */ - struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */ - int **ni_refs; /* percpt reference count */ - time64_t ni_last_alive;/* when I was last alive */ - struct lnet_ni_status *ni_status; /* my health status */ + + /* percpt TX queues */ + struct lnet_tx_queue **ni_tx_queues; + + /* percpt reference count */ + int **ni_refs; + + /* when I was last alive */ + time64_t ni_last_alive; + + /* my health status */ + struct lnet_ni_status *ni_status; + /* per NI LND tunables */ struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables; - /* equivalent interfaces to use */ + /* + * equivalent interfaces to use + * This is an array because socklnd bonding can still be configured + */ char *ni_interfaces[LNET_MAX_INTERFACES]; /* original net namespace */ struct net *ni_net_ns; From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 02/34] lnet: Create struct lnet_net In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137129.8267.345070695068208597.stgit@noble> This will contain some fields from lnet_ni, to be shared between multiple ni on the one network. For now, only tunables are moved across, using struct lnet_ioctl_config_lnd_cmn_tunables which is changed to use signed values so -1 can be stored. -1 means "no value" If the tunables haven't been initialised, then net_tunables_set is false. Previously a NULL pointer had this meaning. A 'struct lnet_net' is allocated as part of lnet_ni_alloc(), and freed by lnet_ni_free(). This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 25 ++++++-- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 8 +-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 - .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 61 +++++++++++--------- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 19 ++++-- drivers/staging/lustre/lnet/lnet/api-ni.c | 45 +++++++++------ drivers/staging/lustre/lnet/lnet/config.c | 24 ++++++-- drivers/staging/lustre/lnet/lnet/lib-move.c | 5 +- drivers/staging/lustre/lnet/lnet/peer.c | 9 ++- drivers/staging/lustre/lnet/lnet/router.c | 8 ++- drivers/staging/lustre/lnet/lnet/router_proc.c | 6 +- 11 files changed, 129 insertions(+), 83 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 078bc97a9ebf..ead8a4e1125a 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -43,6 +43,7 @@ #include #include +#include /* Max payload size */ #define LNET_MAX_PAYLOAD CONFIG_LNET_MAX_PAYLOAD @@ -252,17 +253,22 @@ struct lnet_tx_queue { struct list_head tq_delayed; /* delayed TXs */ }; +struct lnet_net { + /* network tunables */ + struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; + + /* + * boolean to indicate that the tunables have been set and + * shouldn't be reset + */ + bool net_tunables_set; +}; + struct lnet_ni { spinlock_t ni_lock; struct list_head ni_list; /* chain on ln_nis */ struct list_head ni_cptlist; /* chain on ln_nis_cpt */ - int ni_maxtxcredits; /* # tx credits */ - /* # per-peer send credits */ - int ni_peertxcredits; - /* # per-peer router buffer credits */ - int ni_peerrtrcredits; - /* seconds to consider peer dead */ - int ni_peertimeout; + /* number of CPTs */ int ni_ncpts; @@ -286,6 +292,9 @@ struct lnet_ni { /* when I was last alive */ time64_t ni_last_alive; + /* pointer to parent network */ + struct lnet_net *ni_net; + /* my health status */ struct lnet_ni_status *ni_status; @@ -397,7 +406,7 @@ struct lnet_peer_table { * lnet_ni::ni_peertimeout has been set to a positive value */ #define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing && \ - (lp)->lp_ni->ni_peertimeout > 0) + (lp)->lp_ni->ni_net->net_tunables.lct_peer_timeout > 0) struct lnet_route { struct list_head lr_list; /* chain on net */ diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index c1619f411d81..a8eb3b8f9fd7 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -39,10 +39,10 @@ struct lnet_ioctl_config_lnd_cmn_tunables { __u32 lct_version; - __u32 lct_peer_timeout; - __u32 lct_peer_tx_credits; - __u32 lct_peer_rtr_credits; - __u32 lct_max_tx_credits; + __s32 lct_peer_timeout; + __s32 lct_peer_tx_credits; + __s32 lct_peer_rtr_credits; + __s32 lct_max_tx_credits; }; struct lnet_ioctl_config_o2iblnd_tunables { diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index f496e6fcc416..0d17e22c4401 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -337,7 +337,7 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, peer->ibp_error = 0; peer->ibp_last_alive = 0; peer->ibp_max_frags = kiblnd_cfg_rdma_frags(peer->ibp_ni); - peer->ibp_queue_depth = ni->ni_peertxcredits; + peer->ibp_queue_depth = ni->ni_net->net_tunables.lct_peer_tx_credits; atomic_set(&peer->ibp_refcount, 1); /* 1 ref for caller */ INIT_LIST_HEAD(&peer->ibp_list); /* not in the peer table yet */ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index 39d07926d603..a1aca4dda38f 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -171,7 +171,7 @@ int kiblnd_msg_queue_size(int version, struct lnet_ni *ni) if (version == IBLND_MSG_VERSION_1) return IBLND_MSG_QUEUE_SIZE_V1; else if (ni) - return ni->ni_peertxcredits; + return ni->ni_net->net_tunables.lct_peer_tx_credits; else return peer_credits; } @@ -179,6 +179,7 @@ int kiblnd_msg_queue_size(int version, struct lnet_ni *ni) int kiblnd_tunables_setup(struct lnet_ni *ni) { struct lnet_ioctl_config_o2iblnd_tunables *tunables; + struct lnet_ioctl_config_lnd_cmn_tunables *net_tunables; /* * if there was no tunables specified, setup the tunables to be @@ -204,35 +205,39 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) return -EINVAL; } - if (!ni->ni_peertimeout) - ni->ni_peertimeout = peer_timeout; + net_tunables = &ni->ni_net->net_tunables; - if (!ni->ni_maxtxcredits) - ni->ni_maxtxcredits = credits; + if (net_tunables->lct_peer_timeout == -1) + net_tunables->lct_peer_timeout = peer_timeout; - if (!ni->ni_peertxcredits) - ni->ni_peertxcredits = peer_credits; + if (net_tunables->lct_max_tx_credits == -1) + net_tunables->lct_max_tx_credits = credits; - if (!ni->ni_peerrtrcredits) - ni->ni_peerrtrcredits = peer_buffer_credits; + if (net_tunables->lct_peer_tx_credits == -1) + net_tunables->lct_peer_tx_credits = peer_credits; - if (ni->ni_peertxcredits < IBLND_CREDITS_DEFAULT) - ni->ni_peertxcredits = IBLND_CREDITS_DEFAULT; + if (net_tunables->lct_peer_rtr_credits == -1) + net_tunables->lct_peer_rtr_credits = peer_buffer_credits; - if (ni->ni_peertxcredits > IBLND_CREDITS_MAX) - ni->ni_peertxcredits = IBLND_CREDITS_MAX; + if (net_tunables->lct_peer_tx_credits < IBLND_CREDITS_DEFAULT) + net_tunables->lct_peer_tx_credits = IBLND_CREDITS_DEFAULT; - if (ni->ni_peertxcredits > credits) - ni->ni_peertxcredits = credits; + if (net_tunables->lct_peer_tx_credits > IBLND_CREDITS_MAX) + net_tunables->lct_peer_tx_credits = IBLND_CREDITS_MAX; + + if (net_tunables->lct_peer_tx_credits > + net_tunables->lct_max_tx_credits) + net_tunables->lct_peer_tx_credits = + net_tunables->lct_max_tx_credits; if (!tunables->lnd_peercredits_hiw) tunables->lnd_peercredits_hiw = peer_credits_hiw; - if (tunables->lnd_peercredits_hiw < ni->ni_peertxcredits / 2) - tunables->lnd_peercredits_hiw = ni->ni_peertxcredits / 2; + if (tunables->lnd_peercredits_hiw < net_tunables->lct_peer_tx_credits / 2) + tunables->lnd_peercredits_hiw = net_tunables->lct_peer_tx_credits / 2; - if (tunables->lnd_peercredits_hiw >= ni->ni_peertxcredits) - tunables->lnd_peercredits_hiw = ni->ni_peertxcredits - 1; + if (tunables->lnd_peercredits_hiw >= net_tunables->lct_peer_tx_credits) + tunables->lnd_peercredits_hiw = net_tunables->lct_peer_tx_credits - 1; if (tunables->lnd_map_on_demand <= 0 || tunables->lnd_map_on_demand > IBLND_MAX_RDMA_FRAGS) { @@ -252,21 +257,23 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) if (tunables->lnd_map_on_demand > 0 && tunables->lnd_map_on_demand <= IBLND_MAX_RDMA_FRAGS / 8) { tunables->lnd_concurrent_sends = - ni->ni_peertxcredits * 2; + net_tunables->lct_peer_tx_credits * 2; } else { - tunables->lnd_concurrent_sends = ni->ni_peertxcredits; + tunables->lnd_concurrent_sends = + net_tunables->lct_peer_tx_credits; } } - if (tunables->lnd_concurrent_sends > ni->ni_peertxcredits * 2) - tunables->lnd_concurrent_sends = ni->ni_peertxcredits * 2; + if (tunables->lnd_concurrent_sends > net_tunables->lct_peer_tx_credits * 2) + tunables->lnd_concurrent_sends = net_tunables->lct_peer_tx_credits * 2; - if (tunables->lnd_concurrent_sends < ni->ni_peertxcredits / 2) - tunables->lnd_concurrent_sends = ni->ni_peertxcredits / 2; + if (tunables->lnd_concurrent_sends < net_tunables->lct_peer_tx_credits / 2) + tunables->lnd_concurrent_sends = net_tunables->lct_peer_tx_credits / 2; - if (tunables->lnd_concurrent_sends < ni->ni_peertxcredits) { + if (tunables->lnd_concurrent_sends < net_tunables->lct_peer_tx_credits) { CWARN("Concurrent sends %d is lower than message queue size: %d, performance may drop slightly.\n", - tunables->lnd_concurrent_sends, ni->ni_peertxcredits); + tunables->lnd_concurrent_sends, + net_tunables->lct_peer_tx_credits); } if (!tunables->lnd_fmr_pool_size) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 4dde158451ea..4ad885f10235 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2739,12 +2739,19 @@ ksocknal_startup(struct lnet_ni *ni) goto fail_0; spin_lock_init(&net->ksnn_lock); - net->ksnn_incarnation = ktime_get_real_ns(); - ni->ni_data = net; - ni->ni_peertimeout = *ksocknal_tunables.ksnd_peertimeout; - ni->ni_maxtxcredits = *ksocknal_tunables.ksnd_credits; - ni->ni_peertxcredits = *ksocknal_tunables.ksnd_peertxcredits; - ni->ni_peerrtrcredits = *ksocknal_tunables.ksnd_peerrtrcredits; + net->ksnn_incarnation = ktime_get_real_ns(); + ni->ni_data = net; + if (!ni->ni_net->net_tunables_set) { + ni->ni_net->net_tunables.lct_peer_timeout = + *ksocknal_tunables.ksnd_peertimeout; + ni->ni_net->net_tunables.lct_max_tx_credits = + *ksocknal_tunables.ksnd_credits; + ni->ni_net->net_tunables.lct_peer_tx_credits = + *ksocknal_tunables.ksnd_peertxcredits; + ni->ni_net->net_tunables.lct_peer_rtr_credits = + *ksocknal_tunables.ksnd_peerrtrcredits; + ni->ni_net->net_tunables_set = true; + } net->ksnn_ninterfaces = 0; if (!ni->ni_interfaces[0]) { diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index f9fcce2a5643..cd4189fa7acb 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1036,11 +1036,11 @@ lnet_ni_tq_credits(struct lnet_ni *ni) LASSERT(ni->ni_ncpts >= 1); if (ni->ni_ncpts == 1) - return ni->ni_maxtxcredits; + return ni->ni_net->net_tunables.lct_max_tx_credits; - credits = ni->ni_maxtxcredits / ni->ni_ncpts; - credits = max(credits, 8 * ni->ni_peertxcredits); - credits = min(credits, ni->ni_maxtxcredits); + credits = ni->ni_net->net_tunables.lct_max_tx_credits / ni->ni_ncpts; + credits = max(credits, 8 * ni->ni_net->net_tunables.lct_peer_tx_credits); + credits = min(credits, ni->ni_net->net_tunables.lct_max_tx_credits); return credits; } @@ -1271,16 +1271,16 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) */ if (conf) { if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) - ni->ni_peerrtrcredits = + ni->ni_net->net_tunables.lct_peer_rtr_credits = conf->cfg_config_u.cfg_net.net_peer_rtr_credits; if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) - ni->ni_peertimeout = + ni->ni_net->net_tunables.lct_peer_timeout = conf->cfg_config_u.cfg_net.net_peer_timeout; if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) - ni->ni_peertxcredits = + ni->ni_net->net_tunables.lct_peer_tx_credits = conf->cfg_config_u.cfg_net.net_peer_tx_credits; if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) - ni->ni_maxtxcredits = + ni->ni_net->net_tunables.lct_max_tx_credits = conf->cfg_config_u.cfg_net.net_max_tx_credits; } @@ -1297,8 +1297,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) goto failed0; } - LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query); - lnet_net_lock(LNET_LOCK_EX); /* refcount for ln_nis */ lnet_ni_addref_locked(ni, 0); @@ -1314,13 +1312,18 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); the_lnet.ln_loni = ni; + ni->ni_net->net_tunables.lct_peer_tx_credits = 0; + ni->ni_net->net_tunables.lct_peer_rtr_credits = 0; + ni->ni_net->net_tunables.lct_max_tx_credits = 0; + ni->ni_net->net_tunables.lct_peer_timeout = 0; return 0; } - if (!ni->ni_peertxcredits || !ni->ni_maxtxcredits) { + if (!ni->ni_net->net_tunables.lct_peer_tx_credits || + !ni->ni_net->net_tunables.lct_max_tx_credits) { LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n", libcfs_lnd2str(lnd->lnd_type), - !ni->ni_peertxcredits ? + !ni->ni_net->net_tunables.lct_peer_tx_credits ? "" : "per-peer "); /* * shutdown the NI since if we get here then it must've already @@ -1343,9 +1346,11 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) add_device_randomness(&seed, sizeof(seed)); CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n", - libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits, + libcfs_nid2str(ni->ni_nid), + ni->ni_net->net_tunables.lct_peer_tx_credits, lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER, - ni->ni_peerrtrcredits, ni->ni_peertimeout); + ni->ni_net->net_tunables.lct_peer_rtr_credits, + ni->ni_net->net_tunables.lct_peer_timeout); return 0; failed0: @@ -1667,10 +1672,14 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) } config->cfg_nid = ni->ni_nid; - config->cfg_config_u.cfg_net.net_peer_timeout = ni->ni_peertimeout; - config->cfg_config_u.cfg_net.net_max_tx_credits = ni->ni_maxtxcredits; - config->cfg_config_u.cfg_net.net_peer_tx_credits = ni->ni_peertxcredits; - config->cfg_config_u.cfg_net.net_peer_rtr_credits = ni->ni_peerrtrcredits; + config->cfg_config_u.cfg_net.net_peer_timeout = + ni->ni_net->net_tunables.lct_peer_timeout; + config->cfg_config_u.cfg_net.net_max_tx_credits = + ni->ni_net->net_tunables.lct_max_tx_credits; + config->cfg_config_u.cfg_net.net_peer_tx_credits = + ni->ni_net->net_tunables.lct_peer_tx_credits; + config->cfg_config_u.cfg_net.net_peer_rtr_credits = + ni->ni_net->net_tunables.lct_peer_rtr_credits; net_config->ni_status = ni->ni_status->ns_status; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 091c4f714e84..86a53854e427 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -114,29 +114,38 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_net_ns) put_net(ni->ni_net_ns); + kvfree(ni->ni_net); kfree(ni); } struct lnet_ni * -lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) +lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) { struct lnet_tx_queue *tq; struct lnet_ni *ni; int rc; int i; + struct lnet_net *net; - if (!lnet_net_unique(net, nilist)) { + if (!lnet_net_unique(net_id, nilist)) { LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", - libcfs_net2str(net)); + libcfs_net2str(net_id)); return NULL; } ni = kzalloc(sizeof(*ni), GFP_NOFS); - if (!ni) { + net = kzalloc(sizeof(*net), GFP_NOFS); + if (!ni || !net) { + kfree(ni); kfree(net); CERROR("Out of memory creating network %s\n", - libcfs_net2str(net)); + libcfs_net2str(net_id)); return NULL; } + /* initialize global paramters to undefiend */ + net->net_tunables.lct_peer_timeout = -1; + net->net_tunables.lct_max_tx_credits = -1; + net->net_tunables.lct_peer_tx_credits = -1; + net->net_tunables.lct_peer_rtr_credits = -1; spin_lock_init(&ni->ni_lock); INIT_LIST_HEAD(&ni->ni_cptlist); @@ -160,7 +169,7 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) 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); + libcfs_net2str(net_id), rc); goto failed; } @@ -173,8 +182,9 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) ni->ni_ncpts = rc; } + ni->ni_net = net; /* LND will fill in the address part of the NID */ - ni->ni_nid = LNET_MKNID(net, 0); + ni->ni_nid = LNET_MKNID(net_id, 0); /* Store net namespace in which current ni is being created */ if (current->nsproxy->net_ns) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index edcafac055ed..f186e6a16d34 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -524,7 +524,8 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) lp->lp_timestamp >= lp->lp_last_alive) return 0; - deadline = lp->lp_last_alive + lp->lp_ni->ni_peertimeout; + deadline = lp->lp_last_alive + + lp->lp_ni->ni_net->net_tunables.lct_peer_timeout; alive = deadline > now; /* Update obsolete lp_alive except for routers assumed to be dead @@ -569,7 +570,7 @@ lnet_peer_alive_locked(struct lnet_peer *lp) libcfs_nid2str(lp->lp_nid), now, next_query, lnet_queryinterval, - lp->lp_ni->ni_peertimeout); + lp->lp_ni->ni_net->net_tunables.lct_peer_timeout); return 0; } } diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index d9452c322e4d..b76ac3e051d9 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -342,8 +342,8 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) goto out; } - lp->lp_txcredits = lp->lp_ni->ni_peertxcredits; - lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits; + lp->lp_txcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; + lp->lp_mintxcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; lp->lp_rtrcredits = lnet_peer_buffer_credits(lp->lp_ni); lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni); @@ -383,7 +383,7 @@ lnet_debug_peer(lnet_nid_t nid) CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", libcfs_nid2str(lp->lp_nid), lp->lp_refcount, - aliveness, lp->lp_ni->ni_peertxcredits, + aliveness, lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits, lp->lp_rtrcredits, lp->lp_minrtrcredits, lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob); @@ -438,7 +438,8 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, *nid = lp->lp_nid; *refcount = lp->lp_refcount; - *ni_peer_tx_credits = lp->lp_ni->ni_peertxcredits; + *ni_peer_tx_credits = + lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; *peer_tx_credits = lp->lp_txcredits; *peer_rtr_credits = lp->lp_rtrcredits; *peer_min_rtr_credits = lp->lp_mintxcredits; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 02241fbc9eaa..7d61c5d71426 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -57,9 +57,11 @@ MODULE_PARM_DESC(auto_down, "Automatically mark peers down on comms error"); int lnet_peer_buffer_credits(struct lnet_ni *ni) { + struct lnet_net *net = ni->ni_net; + /* NI option overrides LNet default */ - if (ni->ni_peerrtrcredits > 0) - return ni->ni_peerrtrcredits; + if (net->net_tunables.lct_peer_rtr_credits > 0) + return net->net_tunables.lct_peer_rtr_credits; if (peer_buffer_credits > 0) return peer_buffer_credits; @@ -67,7 +69,7 @@ lnet_peer_buffer_credits(struct lnet_ni *ni) * As an approximation, allow this peer the same number of router * buffers as it is allowed outstanding sends */ - return ni->ni_peertxcredits; + return net->net_tunables.lct_peer_tx_credits; } /* forward ref's */ diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 31f4982f7f17..19cea7076057 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -489,7 +489,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, int nrefs = peer->lp_refcount; time64_t lastalive = -1; char *aliveness = "NA"; - int maxcr = peer->lp_ni->ni_peertxcredits; + int maxcr = peer->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; int txcr = peer->lp_txcredits; int mintxcr = peer->lp_mintxcredits; int rtrcr = peer->lp_rtrcredits; @@ -704,8 +704,8 @@ static int proc_lnet_nis(struct ctl_table *table, int write, "%-24s %6s %5lld %4d %4d %4d %5d %5d %5d\n", libcfs_nid2str(ni->ni_nid), stat, last_alive, *ni->ni_refs[i], - ni->ni_peertxcredits, - ni->ni_peerrtrcredits, + ni->ni_net->net_tunables.lct_peer_tx_credits, + ni->ni_net->net_tunables.lct_peer_rtr_credits, tq->tq_credits_max, tq->tq_credits, tq->tq_credits_min); From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 03/34] lnet: struct lnet_ni: move ni_lnd to lnet_net In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137133.8267.15885218437939976879.stgit@noble> Also make some other minor changes to the structures. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 13 ++++++++----- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- drivers/staging/lustre/lnet/lnet/acceptor.c | 4 ++-- drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++-------- drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- drivers/staging/lustre/lnet/lnet/lo.c | 2 +- drivers/staging/lustre/lnet/lnet/router.c | 10 +++++----- drivers/staging/lustre/lnet/lnet/router_proc.c | 2 +- 9 files changed, 35 insertions(+), 32 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index ead8a4e1125a..e170eb07a5bf 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -262,12 +262,17 @@ struct lnet_net { * shouldn't be reset */ bool net_tunables_set; + /* procedural interface */ + struct lnet_lnd *net_lnd; }; struct lnet_ni { - spinlock_t ni_lock; - struct list_head ni_list; /* chain on ln_nis */ - struct list_head ni_cptlist; /* chain on ln_nis_cpt */ + /* chain on ln_nis */ + struct list_head ni_list; + /* chain on ln_nis_cpt */ + struct list_head ni_cptlist; + + spinlock_t ni_lock; /* number of CPTs */ int ni_ncpts; @@ -281,8 +286,6 @@ struct lnet_ni { /* instance-specific data */ void *ni_data; - struct lnet_lnd *ni_lnd; /* procedural interface */ - /* percpt TX queues */ struct lnet_tx_queue **ni_tx_queues; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 0d17e22c4401..5e1592b398c1 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2830,7 +2830,7 @@ static int kiblnd_startup(struct lnet_ni *ni) int rc; int newdev; - LASSERT(ni->ni_lnd == &the_o2iblnd); + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { rc = kiblnd_base_startup(); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 4ad885f10235..2036a0ae5917 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2726,7 +2726,7 @@ ksocknal_startup(struct lnet_ni *ni) int rc; int i; - LASSERT(ni->ni_lnd == &the_ksocklnd); + LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) { rc = ksocknal_base_startup(); diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index 3ae3ca1311a1..f8c921f0221c 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -306,7 +306,7 @@ lnet_accept(struct socket *sock, __u32 magic) return -EPERM; } - if (!ni->ni_lnd->lnd_accept) { + if (!ni->ni_net->net_lnd->lnd_accept) { /* This catches a request for the loopback LND */ lnet_ni_decref(ni); LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", @@ -317,7 +317,7 @@ lnet_accept(struct socket *sock, __u32 magic) CDEBUG(D_NET, "Accept %s from %pI4h\n", libcfs_nid2str(cr.acr_nid), &peer_ip); - rc = ni->ni_lnd->lnd_accept(ni, sock); + rc = ni->ni_net->net_lnd->lnd_accept(ni, sock); lnet_ni_decref(ni); return rc; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index cd4189fa7acb..0896e75bc3d7 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -799,7 +799,7 @@ lnet_count_acceptor_nis(void) cpt = lnet_net_lock_current(); list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (ni->ni_lnd->lnd_accept) + if (ni->ni_net->net_lnd->lnd_accept) count++; } @@ -1098,13 +1098,13 @@ lnet_clear_zombies_nis_locked(void) continue; } - ni->ni_lnd->lnd_refcount--; + ni->ni_net->net_lnd->lnd_refcount--; lnet_net_unlock(LNET_LOCK_EX); - islo = ni->ni_lnd->lnd_type == LOLND; + islo = ni->ni_net->net_lnd->lnd_type == LOLND; LASSERT(!in_interrupt()); - ni->ni_lnd->lnd_shutdown(ni); + ni->ni_net->net_lnd->lnd_shutdown(ni); /* * can't deref lnd anymore now; it might have unregistered @@ -1248,7 +1248,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) lnd->lnd_refcount++; lnet_net_unlock(LNET_LOCK_EX); - ni->ni_lnd = lnd; + ni->ni_net->net_lnd = lnd; if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; @@ -1794,7 +1794,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) if (rc) goto failed1; - if (ni->ni_lnd->lnd_accept) { + if (ni->ni_net->net_lnd->lnd_accept) { rc = lnet_acceptor_start(); if (rc < 0) { /* shutdown the ni that we just started */ @@ -2074,10 +2074,10 @@ LNetCtl(unsigned int cmd, void *arg) if (!ni) return -EINVAL; - if (!ni->ni_lnd->lnd_ctl) + if (!ni->ni_net->net_lnd->lnd_ctl) rc = -EINVAL; else - rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); + rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); lnet_ni_decref(ni); return rc; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index f186e6a16d34..1bf12af87a20 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -406,7 +406,7 @@ lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset); iov_iter_advance(&to, offset); } - rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); + rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); if (rc < 0) lnet_finalize(ni, msg, rc); } @@ -461,7 +461,7 @@ lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || (msg->msg_txcredit && msg->msg_peertxcredit)); - rc = ni->ni_lnd->lnd_send(ni, priv, msg); + rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); if (rc < 0) lnet_finalize(ni, msg, rc); } @@ -474,10 +474,10 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) LASSERT(!msg->msg_sending); LASSERT(msg->msg_receiving); LASSERT(!msg->msg_rx_ready_delay); - LASSERT(ni->ni_lnd->lnd_eager_recv); + LASSERT(ni->ni_net->net_lnd->lnd_eager_recv); msg->msg_rx_ready_delay = 1; - rc = ni->ni_lnd->lnd_eager_recv(ni, msg->msg_private, msg, + rc = ni->ni_net->net_lnd->lnd_eager_recv(ni, msg->msg_private, msg, &msg->msg_private); if (rc) { CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", @@ -496,10 +496,10 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) time64_t last_alive = 0; LASSERT(lnet_peer_aliveness_enabled(lp)); - LASSERT(ni->ni_lnd->lnd_query); + LASSERT(ni->ni_net->net_lnd->lnd_query); lnet_net_unlock(lp->lp_cpt); - ni->ni_lnd->lnd_query(ni, lp->lp_nid, &last_alive); + ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); lnet_net_lock(lp->lp_cpt); lp->lp_last_query = ktime_get_seconds(); @@ -1287,7 +1287,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) info.mi_roffset = hdr->msg.put.offset; info.mi_mbits = hdr->msg.put.match_bits; - msg->msg_rx_ready_delay = !ni->ni_lnd->lnd_eager_recv; + msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; ready_delay = msg->msg_rx_ready_delay; again: @@ -1518,7 +1518,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) if (msg->msg_rxpeer->lp_rtrcredits <= 0 || lnet_msg2bufpool(msg)->rbp_credits <= 0) { - if (!ni->ni_lnd->lnd_eager_recv) { + if (!ni->ni_net->net_lnd->lnd_eager_recv) { msg->msg_rx_ready_delay = 1; } else { lnet_net_unlock(msg->msg_rx_cpt); diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c index eb14146bd879..8167980c2323 100644 --- a/drivers/staging/lustre/lnet/lnet/lo.c +++ b/drivers/staging/lustre/lnet/lnet/lo.c @@ -83,7 +83,7 @@ lolnd_shutdown(struct lnet_ni *ni) static int lolnd_startup(struct lnet_ni *ni) { - LASSERT(ni->ni_lnd == &the_lolnd); + LASSERT(ni->ni_net->net_lnd == &the_lolnd); LASSERT(!lolnd_instanced); lolnd_instanced = 1; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 7d61c5d71426..0c0ec0b27982 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -154,14 +154,14 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) lp->lp_notifylnd = 0; lp->lp_notify = 0; - if (notifylnd && ni->ni_lnd->lnd_notify) { + if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { lnet_net_unlock(lp->lp_cpt); /* * A new notification could happen now; I'll handle it * when control returns to me */ - ni->ni_lnd->lnd_notify(ni, lp->lp_nid, alive); + ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); lnet_net_lock(lp->lp_cpt); } @@ -380,8 +380,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, lnet_net_unlock(LNET_LOCK_EX); /* XXX Assume alive */ - if (ni->ni_lnd->lnd_notify) - ni->ni_lnd->lnd_notify(ni, gateway, 1); + if (ni->ni_net->net_lnd->lnd_notify) + ni->ni_net->net_lnd->lnd_notify(ni, gateway, 1); lnet_net_lock(LNET_LOCK_EX); } @@ -818,7 +818,7 @@ lnet_update_ni_status_locked(void) now = ktime_get_real_seconds(); list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (ni->ni_lnd->lnd_type == LOLND) + if (ni->ni_net->net_lnd->lnd_type == LOLND) continue; if (now < ni->ni_last_alive + timeout) diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 19cea7076057..f3ccd6a2b70e 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -674,7 +674,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, last_alive = now - ni->ni_last_alive; /* @lo forever alive */ - if (ni->ni_lnd->lnd_type == LOLND) + if (ni->ni_net->net_lnd->lnd_type == LOLND) last_alive = 0; lnet_ni_lock(ni); From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 04/34] lnet: embed lnd_tunables in lnet_ni In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137138.8267.11270892110905717079.stgit@noble> Instead of a pointer, embed the data struct. Also other related changes. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 6 ++++ .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 10 +++++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 + .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 6 ++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 8 +++--- .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 13 +++------- drivers/staging/lustre/lnet/lnet/api-ni.c | 27 +++++++++----------- drivers/staging/lustre/lnet/lnet/config.c | 2 - 8 files changed, 36 insertions(+), 38 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index e170eb07a5bf..c5e3363de727 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -302,7 +302,11 @@ struct lnet_ni { struct lnet_ni_status *ni_status; /* per NI LND tunables */ - struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables; + struct lnet_lnd_tunables ni_lnd_tunables; + + /* lnd tunables set explicitly */ + bool ni_lnd_tunables_set; + /* * equivalent interfaces to use * This is an array because socklnd bonding can still be configured diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index a8eb3b8f9fd7..ac29f9d24d5d 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -57,11 +57,15 @@ struct lnet_ioctl_config_o2iblnd_tunables { __u16 pad; }; +struct lnet_lnd_tunables { + union { + struct lnet_ioctl_config_o2iblnd_tunables lnd_o2ib; + } lnd_tun_u; +}; + struct lnet_ioctl_config_lnd_tunables { struct lnet_ioctl_config_lnd_cmn_tunables lt_cmn; - union { - struct lnet_ioctl_config_o2iblnd_tunables lt_o2ib; - } lt_tun_u; + struct lnet_lnd_tunables lt_tun; }; struct lnet_ioctl_net_config { diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 5e1592b398c1..ade566d20c69 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2122,7 +2122,7 @@ static int kiblnd_net_init_pools(struct kib_net *net, struct lnet_ni *ni, int rc; int i; - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; if (tunables->lnd_fmr_pool_size < *kiblnd_tunables.kib_ntx / 4) { CERROR("Can't set fmr pool size (%d) < ntx / 4(%d)\n", diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 42dc15cef194..522eb150d9a6 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -608,7 +608,7 @@ kiblnd_cfg_rdma_frags(struct lnet_ni *ni) struct lnet_ioctl_config_o2iblnd_tunables *tunables; int mod; - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; mod = tunables->lnd_map_on_demand; return mod ? mod : IBLND_MAX_RDMA_FRAGS >> IBLND_FRAG_SHIFT; } @@ -627,7 +627,7 @@ kiblnd_concurrent_sends(int version, struct lnet_ni *ni) struct lnet_ioctl_config_o2iblnd_tunables *tunables; int concurrent_sends; - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; concurrent_sends = tunables->lnd_concurrent_sends; if (version == IBLND_MSG_VERSION_1) { @@ -777,7 +777,7 @@ kiblnd_need_noop(struct kib_conn *conn) struct lnet_ni *ni = conn->ibc_peer->ibp_ni; LASSERT(conn->ibc_state >= IBLND_CONN_ESTABLISHED); - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; if (conn->ibc_outstanding_credits < IBLND_CREDITS_HIGHWATER(tunables, conn->ibc_version) && diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index a8d2b4911dab..c266940cb2ae 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1452,7 +1452,7 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) /* Brand new peer */ LASSERT(!peer->ibp_connecting); - tunables = &peer->ibp_ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &peer->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; peer->ibp_connecting = tunables->lnd_conns_per_peer; /* always called with a ref on ni, which prevents ni being shutdown */ @@ -2592,14 +2592,14 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, break; case IBLND_REJECT_RDMA_FRAGS: { - struct lnet_ioctl_config_lnd_tunables *tunables; + struct lnet_ioctl_config_o2iblnd_tunables *tunables; if (!cp) { reason = "can't negotiate max frags"; goto out; } - tunables = peer->ibp_ni->ni_lnd_tunables; - if (!tunables->lt_tun_u.lt_o2ib.lnd_map_on_demand) { + tunables = &peer->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; + if (!tunables->lnd_map_on_demand) { reason = "map_on_demand must be enabled"; goto out; } diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index a1aca4dda38f..5117594f38fb 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -185,16 +185,11 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) * if there was no tunables specified, setup the tunables to be * defaulted */ - if (!ni->ni_lnd_tunables) { - ni->ni_lnd_tunables = kzalloc(sizeof(*ni->ni_lnd_tunables), - GFP_NOFS); - if (!ni->ni_lnd_tunables) - return -ENOMEM; - - memcpy(&ni->ni_lnd_tunables->lt_tun_u.lt_o2ib, + if (!ni->ni_lnd_tunables_set) + memcpy(&ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib, &default_tunables, sizeof(*tunables)); - } - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; /* Current API version */ tunables->lnd_version = 0; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 0896e75bc3d7..c944fbb155c8 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1198,6 +1198,7 @@ static int lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) { struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; + struct lnet_lnd_tunables *tun = NULL; int rc = -EINVAL; int lnd_type; struct lnet_lnd *lnd; @@ -1250,19 +1251,15 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) ni->ni_net->net_lnd = lnd; - if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) + if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) { lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; + tun = &lnd_tunables->lt_tun; + } - if (lnd_tunables) { - ni->ni_lnd_tunables = kzalloc(sizeof(*ni->ni_lnd_tunables), - GFP_NOFS); - if (!ni->ni_lnd_tunables) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - rc = -ENOMEM; - goto failed0; - } - memcpy(ni->ni_lnd_tunables, lnd_tunables, - sizeof(*ni->ni_lnd_tunables)); + if (tun) { + memcpy(&ni->ni_lnd_tunables, tun, + sizeof(*tun)); + ni->ni_lnd_tunables_set = true; } /* @@ -1702,15 +1699,15 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) tunable_size = config->cfg_hdr.ioc_len - min_size; /* Don't copy to much data to user space */ - min_size = min(tunable_size, sizeof(*ni->ni_lnd_tunables)); + min_size = min(tunable_size, sizeof(ni->ni_lnd_tunables)); lnd_cfg = (struct lnet_ioctl_config_lnd_tunables *)net_config->cfg_bulk; - if (ni->ni_lnd_tunables && lnd_cfg && min_size) { - memcpy(lnd_cfg, ni->ni_lnd_tunables, min_size); + if (lnd_cfg && min_size) { + memcpy(&lnd_cfg->lt_tun, &ni->ni_lnd_tunables, min_size); config->cfg_config_u.cfg_net.net_interface_count = 1; /* Tell user land that kernel side has less data */ - if (tunable_size > sizeof(*ni->ni_lnd_tunables)) { + if (tunable_size > sizeof(ni->ni_lnd_tunables)) { min_size = tunable_size - sizeof(ni->ni_lnd_tunables); config->cfg_hdr.ioc_len -= min_size; } diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 86a53854e427..5646feeb433e 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -105,8 +105,6 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_cpts) cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts); - kfree(ni->ni_lnd_tunables); - for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) kfree(ni->ni_interfaces[i]); From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 05/34] lnet: begin separating "networks" from "network interfaces". In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137142.8267.15402125903541546660.stgit@noble> We already have "struct lnet_net" separate from "struct lnet_ni", but they are currently allocated together and freed together and it is assumed that they are 1-to-1. This patch starts breaking that assumption. We have separate lnet_net_alloc() and lnet_net_free() to alloc/free the new lnet_net, though they is currently called only when lnet_ni_alloc/free are called. The netid is now stored in the lnet_net and fetched directly from there, rather than extracting it from the net-interface-id ni_nid. The linkage between these two structures is now richer, lnet_net can link to a list of lnet_ni. lnet_net now has a list of lnet_net, so to find all the lnet_ni, we need to walk a list of lists. This need to walk a list-of-lists occurs in several places, and new helpers like lnet_get_ni_idx_locked() and lnet_get_next_ni_locked are introduced. Previously a list_head was passed to lnet_ni_alloc() for the new lnet_ni to be attached to. Now a list is passed to lnet_net_alloc() for the net to be attached to, and a lnet_net is passed to lnet_ni_alloc() for the ni to attach to. lnet_ni_alloc() also receives an interface name, but this is currently unused. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 15 + .../staging/lustre/include/linux/lnet/lib-types.h | 23 +- drivers/staging/lustre/lnet/lnet/acceptor.c | 2 drivers/staging/lustre/lnet/lnet/api-ni.c | 255 ++++++++++++++------ drivers/staging/lustre/lnet/lnet/config.c | 135 +++++++---- drivers/staging/lustre/lnet/lnet/lib-move.c | 6 drivers/staging/lustre/lnet/lnet/router.c | 15 - drivers/staging/lustre/lnet/lnet/router_proc.c | 16 - 8 files changed, 308 insertions(+), 159 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 0fecf0d32c58..4440b87299c4 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -369,8 +369,14 @@ lnet_ni_decref(struct lnet_ni *ni) } void lnet_ni_free(struct lnet_ni *ni); +void lnet_net_free(struct lnet_net *net); + +struct lnet_net * +lnet_net_alloc(__u32 net_type, struct list_head *netlist); + struct lnet_ni * -lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist); +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, + char *iface); static inline int lnet_nid2peerhash(lnet_nid_t nid) @@ -412,6 +418,9 @@ void lnet_destroy_routes(void); int lnet_get_route(int idx, __u32 *net, __u32 *hops, lnet_nid_t *gateway, __u32 *alive, __u32 *priority); int lnet_get_rtr_pool_cfg(int idx, struct lnet_ioctl_pool_cfg *pool_cfg); +struct lnet_ni *lnet_get_next_ni_locked(struct lnet_net *mynet, + struct lnet_ni *prev); +struct lnet_ni *lnet_get_ni_idx_locked(int idx); void lnet_router_debugfs_init(void); void lnet_router_debugfs_fini(void); @@ -584,7 +593,7 @@ int lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, __u32 local_ip, __u32 peer_ip, int peer_port); void lnet_connect_console_error(int rc, lnet_nid_t peer_nid, __u32 peer_ip, int port); -int lnet_count_acceptor_nis(void); +int lnet_count_acceptor_nets(void); int lnet_acceptor_timeout(void); int lnet_acceptor_port(void); @@ -618,7 +627,7 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); int lnet_parse_routes(char *route_str, int *im_a_router); int lnet_parse_networks(struct list_head *nilist, char *networks); -int lnet_net_unique(__u32 net, struct list_head *nilist); +bool lnet_net_unique(__u32 net, struct list_head *nilist); int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index c5e3363de727..5f0d4703bf86 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -254,6 +254,15 @@ struct lnet_tx_queue { }; struct lnet_net { + /* chain on the ln_nets */ + struct list_head net_list; + + /* net ID, which is compoed of + * (net_type << 16) | net_num. + * net_type can be one of the enumarated types defined in + * lnet/include/lnet/nidstr.h */ + __u32 net_id; + /* network tunables */ struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; @@ -264,11 +273,13 @@ struct lnet_net { bool net_tunables_set; /* procedural interface */ struct lnet_lnd *net_lnd; + /* list of NIs on this net */ + struct list_head net_ni_list; }; struct lnet_ni { - /* chain on ln_nis */ - struct list_head ni_list; + /* chain on the lnet_net structure */ + struct list_head ni_netlist; /* chain on ln_nis_cpt */ struct list_head ni_cptlist; @@ -626,14 +637,16 @@ struct lnet { /* failure simulation */ struct list_head ln_test_peers; struct list_head ln_drop_rules; - struct list_head ln_delay_rules; + struct list_head ln_delay_rules; - struct list_head ln_nis; /* LND instances */ + /* LND instances */ + struct list_head ln_nets; /* NIs bond on specific CPT(s) */ struct list_head ln_nis_cpt; /* dying LND instances */ struct list_head ln_nis_zombie; - struct lnet_ni *ln_loni; /* the loopback NI */ + /* the loopback NI */ + struct lnet_ni *ln_loni; /* remote networks with routes to them */ struct list_head *ln_remote_nets_hash; diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index f8c921f0221c..88b90c1fdbaf 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -454,7 +454,7 @@ lnet_acceptor_start(void) if (rc <= 0) return rc; - if (!lnet_count_acceptor_nis()) /* not required */ + if (lnet_count_acceptor_nets() == 0) /* not required */ return 0; task = kthread_run(lnet_acceptor, (void *)(uintptr_t)secure, diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index c944fbb155c8..05687278334a 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -537,7 +537,7 @@ lnet_prepare(lnet_pid_t requested_pid) the_lnet.ln_pid = requested_pid; INIT_LIST_HEAD(&the_lnet.ln_test_peers); - INIT_LIST_HEAD(&the_lnet.ln_nis); + INIT_LIST_HEAD(&the_lnet.ln_nets); INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); INIT_LIST_HEAD(&the_lnet.ln_routers); @@ -616,7 +616,7 @@ lnet_unprepare(void) LASSERT(!the_lnet.ln_refcount); LASSERT(list_empty(&the_lnet.ln_test_peers)); - LASSERT(list_empty(&the_lnet.ln_nis)); + LASSERT(list_empty(&the_lnet.ln_nets)); LASSERT(list_empty(&the_lnet.ln_nis_cpt)); LASSERT(list_empty(&the_lnet.ln_nis_zombie)); @@ -648,14 +648,17 @@ lnet_unprepare(void) } struct lnet_ni * -lnet_net2ni_locked(__u32 net, int cpt) +lnet_net2ni_locked(__u32 net_id, int cpt) { - struct lnet_ni *ni; + struct lnet_ni *ni; + struct lnet_net *net; LASSERT(cpt != LNET_LOCK_EX); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (LNET_NIDNET(ni->ni_nid) == net) { + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + if (net->net_id == net_id) { + ni = list_entry(net->net_ni_list.next, struct lnet_ni, + ni_netlist); lnet_ni_addref_locked(ni, cpt); return ni; } @@ -760,14 +763,17 @@ lnet_islocalnet(__u32 net) struct lnet_ni * lnet_nid2ni_locked(lnet_nid_t nid, int cpt) { - struct lnet_ni *ni; + struct lnet_net *net; + struct lnet_ni *ni; LASSERT(cpt != LNET_LOCK_EX); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (ni->ni_nid == nid) { - lnet_ni_addref_locked(ni, cpt); - return ni; + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (ni->ni_nid == nid) { + lnet_ni_addref_locked(ni, cpt); + return ni; + } } } @@ -790,16 +796,18 @@ lnet_islocalnid(lnet_nid_t nid) } int -lnet_count_acceptor_nis(void) +lnet_count_acceptor_nets(void) { /* Return the # of NIs that need the acceptor. */ - int count = 0; - struct lnet_ni *ni; - int cpt; + int count = 0; + struct lnet_net *net; + int cpt; cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (ni->ni_net->net_lnd->lnd_accept) + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + /* all socklnd type networks should have the acceptor + * thread started */ + if (net->net_lnd->lnd_accept) count++; } @@ -832,13 +840,16 @@ lnet_ping_info_create(int num_ni) static inline int lnet_get_ni_count(void) { - struct lnet_ni *ni; - int count = 0; + struct lnet_ni *ni; + struct lnet_net *net; + int count = 0; lnet_net_lock(0); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) - count++; + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) + count++; + } lnet_net_unlock(0); @@ -854,14 +865,17 @@ lnet_ping_info_free(struct lnet_ping_info *pinfo) static void lnet_ping_info_destroy(void) { + struct lnet_net *net; struct lnet_ni *ni; lnet_net_lock(LNET_LOCK_EX); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - lnet_ni_lock(ni); - ni->ni_status = NULL; - lnet_ni_unlock(ni); + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + lnet_ni_lock(ni); + ni->ni_status = NULL; + lnet_ni_unlock(ni); + } } lnet_ping_info_free(the_lnet.ln_ping_info); @@ -963,24 +977,28 @@ lnet_ping_md_unlink(struct lnet_ping_info *pinfo, static void lnet_ping_info_install_locked(struct lnet_ping_info *ping_info) { + int i = 0; struct lnet_ni_status *ns; struct lnet_ni *ni; - int i = 0; + struct lnet_net *net; - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - LASSERT(i < ping_info->pi_nnis); + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + LASSERT(i < ping_info->pi_nnis); - ns = &ping_info->pi_ni[i]; + ns = &ping_info->pi_ni[i]; - ns->ns_nid = ni->ni_nid; + ns->ns_nid = ni->ni_nid; - lnet_ni_lock(ni); - ns->ns_status = (ni->ni_status) ? - ni->ni_status->ns_status : LNET_NI_STATUS_UP; - ni->ni_status = ns; - lnet_ni_unlock(ni); + lnet_ni_lock(ni); + ns->ns_status = ni->ni_status ? + ni->ni_status->ns_status : + LNET_NI_STATUS_UP; + ni->ni_status = ns; + lnet_ni_unlock(ni); - i++; + i++; + } } } @@ -1054,9 +1072,9 @@ lnet_ni_unlink_locked(struct lnet_ni *ni) } /* move it to zombie list and nobody can find it anymore */ - LASSERT(!list_empty(&ni->ni_list)); - list_move(&ni->ni_list, &the_lnet.ln_nis_zombie); - lnet_ni_decref_locked(ni, 0); /* drop ln_nis' ref */ + LASSERT(!list_empty(&ni->ni_netlist)); + list_move(&ni->ni_netlist, &the_lnet.ln_nis_zombie); + lnet_ni_decref_locked(ni, 0); } static void @@ -1076,17 +1094,17 @@ lnet_clear_zombies_nis_locked(void) int j; ni = list_entry(the_lnet.ln_nis_zombie.next, - struct lnet_ni, ni_list); - list_del_init(&ni->ni_list); + struct lnet_ni, ni_netlist); + list_del_init(&ni->ni_netlist); cfs_percpt_for_each(ref, j, ni->ni_refs) { if (!*ref) continue; /* still busy, add it back to zombie list */ - list_add(&ni->ni_list, &the_lnet.ln_nis_zombie); + list_add(&ni->ni_netlist, &the_lnet.ln_nis_zombie); break; } - if (!list_empty(&ni->ni_list)) { + if (!list_empty(&ni->ni_netlist)) { lnet_net_unlock(LNET_LOCK_EX); ++i; if ((i & (-i)) == i) { @@ -1126,6 +1144,7 @@ lnet_shutdown_lndnis(void) { struct lnet_ni *ni; int i; + struct lnet_net *net; /* NB called holding the global mutex */ @@ -1138,10 +1157,14 @@ lnet_shutdown_lndnis(void) the_lnet.ln_shutdown = 1; /* flag shutdown */ /* Unlink NIs from the global table */ - while (!list_empty(&the_lnet.ln_nis)) { - ni = list_entry(the_lnet.ln_nis.next, - struct lnet_ni, ni_list); - lnet_ni_unlink_locked(ni); + while (!list_empty(&the_lnet.ln_nets)) { + net = list_entry(the_lnet.ln_nets.next, + struct lnet_net, net_list); + while (!list_empty(&net->net_ni_list)) { + ni = list_entry(net->net_ni_list.next, + struct lnet_ni, ni_netlist); + lnet_ni_unlink_locked(ni); + } } /* Drop the cached loopback NI. */ @@ -1212,7 +1235,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) /* Make sure this new NI is unique. */ lnet_net_lock(LNET_LOCK_EX); - rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis); + rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nets); lnet_net_unlock(LNET_LOCK_EX); if (!rc) { if (lnd_type == LOLND) { @@ -1297,7 +1320,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) lnet_net_lock(LNET_LOCK_EX); /* refcount for ln_nis */ lnet_ni_addref_locked(ni, 0); - list_add_tail(&ni->ni_list, &the_lnet.ln_nis); + list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); if (ni->ni_cpts) { lnet_ni_addref_locked(ni, 0); list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); @@ -1363,8 +1386,8 @@ lnet_startup_lndnis(struct list_head *nilist) int ni_count = 0; while (!list_empty(nilist)) { - ni = list_entry(nilist->next, struct lnet_ni, ni_list); - list_del(&ni->ni_list); + ni = list_entry(nilist->next, struct lnet_ni, ni_netlist); + list_del(&ni->ni_netlist); rc = lnet_startup_lndni(ni, NULL); if (rc < 0) @@ -1486,6 +1509,7 @@ LNetNIInit(lnet_pid_t requested_pid) struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; struct list_head net_head; + struct lnet_net *net; INIT_LIST_HEAD(&net_head); @@ -1505,8 +1529,15 @@ LNetNIInit(lnet_pid_t requested_pid) return rc; } - /* Add in the loopback network */ - if (!lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head)) { + /* create a network for Loopback network */ + net = lnet_net_alloc(LNET_MKNET(LOLND, 0), &net_head); + if (net == NULL) { + rc = -ENOMEM; + goto err_empty_list; + } + + /* Add in the loopback NI */ + if (lnet_ni_alloc(net, NULL, NULL) == NULL) { rc = -ENOMEM; goto err_empty_list; } @@ -1584,11 +1615,11 @@ LNetNIInit(lnet_pid_t requested_pid) LASSERT(rc < 0); mutex_unlock(&the_lnet.ln_api_mutex); while (!list_empty(&net_head)) { - struct lnet_ni *ni; + struct lnet_net *net; - ni = list_entry(net_head.next, struct lnet_ni, ni_list); - list_del_init(&ni->ni_list); - lnet_ni_free(ni); + net = list_entry(net_head.next, struct lnet_net, net_list); + list_del_init(&net->net_list); + lnet_net_free(net); } return rc; } @@ -1714,25 +1745,83 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) } } +struct lnet_ni * +lnet_get_ni_idx_locked(int idx) +{ + struct lnet_ni *ni; + struct lnet_net *net; + + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (idx-- == 0) + return ni; + } + } + + return NULL; +} + +struct lnet_ni * +lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev) +{ + struct lnet_ni *ni; + struct lnet_net *net = mynet; + + if (prev == NULL) { + if (net == NULL) + net = list_entry(the_lnet.ln_nets.next, struct lnet_net, + net_list); + ni = list_entry(net->net_ni_list.next, struct lnet_ni, + ni_netlist); + + return ni; + } + + if (prev->ni_netlist.next == &prev->ni_net->net_ni_list) { + /* if you reached the end of the ni list and the net is + * specified, then there are no more nis in that net */ + if (net != NULL) + return NULL; + + /* we reached the end of this net ni list. move to the + * next net */ + if (prev->ni_net->net_list.next == &the_lnet.ln_nets) + /* no more nets and no more NIs. */ + return NULL; + + /* get the next net */ + net = list_entry(prev->ni_net->net_list.next, struct lnet_net, + net_list); + /* get the ni on it */ + ni = list_entry(net->net_ni_list.next, struct lnet_ni, + ni_netlist); + + return ni; + } + + /* there are more nis left */ + ni = list_entry(prev->ni_netlist.next, struct lnet_ni, ni_netlist); + + return ni; +} + static int lnet_get_net_config(struct lnet_ioctl_config_data *config) { struct lnet_ni *ni; + int cpt; int idx = config->cfg_count; - int cpt, i = 0; int rc = -ENOENT; cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (i++ != idx) - continue; + ni = lnet_get_ni_idx_locked(idx); + if (ni != NULL) { + rc = 0; lnet_ni_lock(ni); lnet_fill_ni_info(ni, config); lnet_ni_unlock(ni); - rc = 0; - break; } lnet_net_unlock(cpt); @@ -1745,6 +1834,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) char *nets = conf->cfg_config_u.cfg_net.net_intf; struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; + struct lnet_net *net; struct lnet_ni *ni; struct list_head net_head; struct lnet_remotenet *rnet; @@ -1752,7 +1842,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) INIT_LIST_HEAD(&net_head); - /* Create a ni structure for the network string */ + /* Create a net/ni structures for the network string */ rc = lnet_parse_networks(&net_head, nets); if (rc <= 0) return !rc ? -EINVAL : rc; @@ -1760,14 +1850,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) mutex_lock(&the_lnet.ln_api_mutex); if (rc > 1) { - rc = -EINVAL; /* only add one interface per call */ + rc = -EINVAL; /* only add one network per call */ goto failed0; } - ni = list_entry(net_head.next, struct lnet_ni, ni_list); + net = list_entry(net_head.next, struct lnet_net, net_list); lnet_net_lock(LNET_LOCK_EX); - rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid)); + rnet = lnet_find_net_locked(net->net_id); lnet_net_unlock(LNET_LOCK_EX); /* * make sure that the net added doesn't invalidate the current @@ -1785,8 +1875,8 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) if (rc) goto failed0; - list_del_init(&ni->ni_list); - + list_del_init(&net->net_list); + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); rc = lnet_startup_lndni(ni, conf); if (rc) goto failed1; @@ -1812,9 +1902,9 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) failed0: mutex_unlock(&the_lnet.ln_api_mutex); while (!list_empty(&net_head)) { - ni = list_entry(net_head.next, struct lnet_ni, ni_list); - list_del_init(&ni->ni_list); - lnet_ni_free(ni); + net = list_entry(net_head.next, struct lnet_net, net_list); + list_del_init(&net->net_list); + lnet_net_free(net); } return rc; } @@ -1849,7 +1939,7 @@ lnet_dyn_del_ni(__u32 net) lnet_shutdown_lndni(ni); - if (!lnet_count_acceptor_nis()) + if (!lnet_count_acceptor_nets()) lnet_acceptor_stop(); lnet_ping_target_update(pinfo, md_handle); @@ -2103,7 +2193,8 @@ EXPORT_SYMBOL(LNetDebugPeer); int LNetGetId(unsigned int index, struct lnet_process_id *id) { - struct lnet_ni *ni; + struct lnet_ni *ni; + struct lnet_net *net; int cpt; int rc = -ENOENT; @@ -2111,14 +2202,16 @@ LNetGetId(unsigned int index, struct lnet_process_id *id) cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (index--) - continue; + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (index-- != 0) + continue; - id->nid = ni->ni_nid; - id->pid = the_lnet.ln_pid; - rc = 0; - break; + id->nid = ni->ni_nid; + id->pid = the_lnet.ln_pid; + rc = 0; + break; + } } lnet_net_unlock(cpt); diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 5646feeb433e..e83bdbec11e3 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -78,17 +78,17 @@ lnet_issep(char c) } } -int -lnet_net_unique(__u32 net, struct list_head *nilist) +bool +lnet_net_unique(__u32 net, struct list_head *netlist) { - struct lnet_ni *ni; + struct lnet_net *net_l; - list_for_each_entry(ni, nilist, ni_list) { - if (LNET_NIDNET(ni->ni_nid) == net) - return 0; + list_for_each_entry(net_l, netlist, net_list) { + if (net_l->net_id == net) + return false; } - return 1; + return true; } void @@ -112,41 +112,78 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_net_ns) put_net(ni->ni_net_ns); - kvfree(ni->ni_net); kfree(ni); } -struct lnet_ni * -lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) +void +lnet_net_free(struct lnet_net *net) { - struct lnet_tx_queue *tq; + struct list_head *tmp, *tmp2; struct lnet_ni *ni; - int rc; - int i; + + /* delete any nis which have been started. */ + list_for_each_safe(tmp, tmp2, &net->net_ni_list) { + ni = list_entry(tmp, struct lnet_ni, ni_netlist); + list_del_init(&ni->ni_netlist); + lnet_ni_free(ni); + } + + kfree(net); +} + +struct lnet_net * +lnet_net_alloc(__u32 net_id, struct list_head *net_list) +{ struct lnet_net *net; - if (!lnet_net_unique(net_id, nilist)) { - LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", - libcfs_net2str(net_id)); + if (!lnet_net_unique(net_id, net_list)) { + CERROR("Duplicate net %s. Ignore\n", + libcfs_net2str(net_id)); return NULL; } - ni = kzalloc(sizeof(*ni), GFP_NOFS); net = kzalloc(sizeof(*net), GFP_NOFS); - if (!ni || !net) { - kfree(ni); kfree(net); + if (!net) { CERROR("Out of memory creating network %s\n", libcfs_net2str(net_id)); return NULL; } + + INIT_LIST_HEAD(&net->net_list); + INIT_LIST_HEAD(&net->net_ni_list); + + net->net_id = net_id; + /* initialize global paramters to undefiend */ net->net_tunables.lct_peer_timeout = -1; net->net_tunables.lct_max_tx_credits = -1; net->net_tunables.lct_peer_tx_credits = -1; net->net_tunables.lct_peer_rtr_credits = -1; + list_add_tail(&net->net_list, net_list); + + return net; +} + +struct lnet_ni * +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) +{ + struct lnet_tx_queue *tq; + struct lnet_ni *ni; + int rc; + int i; + + ni = kzalloc(sizeof(*ni), GFP_KERNEL); + if (ni == NULL) { + CERROR("Out of memory creating network interface %s%s\n", + libcfs_net2str(net->net_id), + (iface != NULL) ? iface : ""); + return NULL; + } + spin_lock_init(&ni->ni_lock); INIT_LIST_HEAD(&ni->ni_cptlist); + INIT_LIST_HEAD(&ni->ni_netlist); ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*ni->ni_refs[0])); if (!ni->ni_refs) @@ -166,8 +203,9 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) } 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_id), rc); + CERROR("Failed to set CPTs for NI %s(%s): %d\n", + libcfs_net2str(net->net_id), + (iface != NULL) ? iface : "", rc); goto failed; } @@ -182,7 +220,7 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) ni->ni_net = net; /* LND will fill in the address part of the NID */ - ni->ni_nid = LNET_MKNID(net_id, 0); + ni->ni_nid = LNET_MKNID(net->net_id, 0); /* Store net namespace in which current ni is being created */ if (current->nsproxy->net_ns) @@ -191,22 +229,24 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) ni->ni_net_ns = NULL; ni->ni_last_alive = ktime_get_real_seconds(); - list_add_tail(&ni->ni_list, nilist); + list_add_tail(&ni->ni_netlist, &net->net_ni_list); + return ni; - failed: +failed: lnet_ni_free(ni); return NULL; } int -lnet_parse_networks(struct list_head *nilist, char *networks) +lnet_parse_networks(struct list_head *netlist, char *networks) { struct cfs_expr_list *el = NULL; char *tokens; char *str; char *tmp; - struct lnet_ni *ni; - __u32 net; + struct lnet_net *net; + struct lnet_ni *ni = NULL; + __u32 net_id; int nnets = 0; struct list_head *temp_node; @@ -275,18 +315,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) if (comma) *comma++ = 0; - net = libcfs_str2net(strim(str)); + net_id = libcfs_str2net(strim(str)); - if (net == LNET_NIDNET(LNET_NID_ANY)) { + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { LCONSOLE_ERROR_MSG(0x113, "Unrecognised network type\n"); tmp = str; goto failed_syntax; } - if (LNET_NETTYP(net) != LOLND && /* LO is implicit */ - !lnet_ni_alloc(net, el, nilist)) - goto failed; + if (LNET_NETTYP(net_id) != LOLND) { /* LO is implicit */ + net = lnet_net_alloc(net_id, netlist); + if (!net || + !lnet_ni_alloc(net, el, NULL)) + goto failed; + } if (el) { cfs_expr_list_free(el); @@ -298,14 +341,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) } *bracket = 0; - net = libcfs_str2net(strim(str)); - if (net == LNET_NIDNET(LNET_NID_ANY)) { + net_id = libcfs_str2net(strim(str)); + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { tmp = str; goto failed_syntax; } - ni = lnet_ni_alloc(net, el, nilist); - if (!ni) + /* always allocate a net, since we will eventually add an + * interface to it, or we will fail, in which case we'll + * just delete it */ + net = lnet_net_alloc(net_id, netlist); + if (IS_ERR_OR_NULL(net)) + goto failed; + + ni = lnet_ni_alloc(net, el, NULL); + if (IS_ERR_OR_NULL(ni)) goto failed; if (el) { @@ -337,7 +387,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) if (niface == LNET_MAX_INTERFACES) { LCONSOLE_ERROR_MSG(0x115, "Too many interfaces for net %s\n", - libcfs_net2str(net)); + libcfs_net2str(net_id)); goto failed; } @@ -378,7 +428,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) } } - list_for_each(temp_node, nilist) + list_for_each(temp_node, netlist) nnets++; kfree(tokens); @@ -387,11 +437,12 @@ lnet_parse_networks(struct list_head *nilist, char *networks) failed_syntax: lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp)); failed: - while (!list_empty(nilist)) { - ni = list_entry(nilist->next, struct lnet_ni, ni_list); + /* free the net list and all the nis on each net */ + while (!list_empty(netlist)) { + net = list_entry(netlist->next, struct lnet_net, net_list); - list_del(&ni->ni_list); - lnet_ni_free(ni); + list_del_init(&net->net_list); + lnet_net_free(net); } if (el) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 1bf12af87a20..1c874025fa74 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -2289,7 +2289,7 @@ EXPORT_SYMBOL(LNetGet); int LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) { - struct lnet_ni *ni; + struct lnet_ni *ni = NULL; struct lnet_remotenet *rnet; __u32 dstnet = LNET_NIDNET(dstnid); int hops; @@ -2307,9 +2307,9 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { if (ni->ni_nid == dstnid) { - if (srcnidp) + if (srcnidp != NULL) *srcnidp = dstnid; if (orderp) { if (LNET_NETTYP(LNET_NIDNET(dstnid)) == LOLND) diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 0c0ec0b27982..135dfe793b0b 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -245,13 +245,10 @@ static void lnet_shuffle_seed(void) if (seeded) return; - /* - * Nodes with small feet have little entropy - * the NID for this node gives the most entropy in the low bits - */ - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { + /* Nodes with small feet have little entropy + * the NID for this node gives the most entropy in the low bits */ + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { __u32 lnd_type, seed; - lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); if (lnd_type != LOLND) { seed = (LNET_NIDADDR(ni->ni_nid) | lnd_type); @@ -807,8 +804,8 @@ lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) static void lnet_update_ni_status_locked(void) { - struct lnet_ni *ni; - time64_t now; + struct lnet_ni *ni = NULL; + time64_t now; time64_t timeout; LASSERT(the_lnet.ln_routing); @@ -817,7 +814,7 @@ lnet_update_ni_status_locked(void) max(live_router_check_interval, dead_router_check_interval); now = ktime_get_real_seconds(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { if (ni->ni_net->net_lnd->lnd_type == LOLND) continue; diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index f3ccd6a2b70e..2a366e9a8627 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -641,26 +641,12 @@ static int proc_lnet_nis(struct ctl_table *table, int write, "rtr", "max", "tx", "min"); LASSERT(tmpstr + tmpsiz - s > 0); } else { - struct list_head *n; struct lnet_ni *ni = NULL; int skip = *ppos - 1; lnet_net_lock(0); - n = the_lnet.ln_nis.next; - - while (n != &the_lnet.ln_nis) { - struct lnet_ni *a_ni; - - a_ni = list_entry(n, struct lnet_ni, ni_list); - if (!skip) { - ni = a_ni; - break; - } - - skip--; - n = n->next; - } + ni = lnet_get_ni_idx_locked(skip); if (ni) { struct lnet_tx_queue *tq; From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 06/34] lnet: store separate xmit/recv net-interface in each message. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137147.8267.3706504130592682241.stgit@noble> Currently we store the net-interface in the peer, but the peer should identify just the network, not the particular interface. To help track which actual interface is used for each message, store them explicitly. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split and includes commit 63c3e5129873 ("LU-7734 lnet: Fix lnet_msg_free()") Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 3 +++ drivers/staging/lustre/lnet/lnet/lib-move.c | 21 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 5f0d4703bf86..16a493529a46 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -98,6 +98,9 @@ struct lnet_msg { void *msg_private; struct lnet_libmd *msg_md; + /* the NI the message was sent or received over */ + struct lnet_ni *msg_txni; + struct lnet_ni *msg_rxni; unsigned int msg_len; unsigned int msg_wanted; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 1c874025fa74..b2a52ddcefcb 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -782,6 +782,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) { struct lnet_peer *txpeer = msg->msg_txpeer; struct lnet_msg *msg2; + struct lnet_ni *txni = msg->msg_txni; if (msg->msg_txcredit) { struct lnet_ni *ni = txpeer->lp_ni; @@ -829,6 +830,11 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) } } + if (txni != NULL) { + msg->msg_txni = NULL; + lnet_ni_decref_locked(txni, msg->msg_tx_cpt); + } + if (txpeer) { msg->msg_txpeer = NULL; lnet_peer_decref_locked(txpeer); @@ -876,6 +882,7 @@ void lnet_return_rx_credits_locked(struct lnet_msg *msg) { struct lnet_peer *rxpeer = msg->msg_rxpeer; + struct lnet_ni *rxni = msg->msg_rxni; struct lnet_msg *msg2; if (msg->msg_rtrcredit) { @@ -951,6 +958,10 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) (void)lnet_post_routed_recv_locked(msg2, 1); } } + if (rxni != NULL) { + msg->msg_rxni = NULL; + lnet_ni_decref_locked(rxni, msg->msg_rx_cpt); + } if (rxpeer) { msg->msg_rxpeer = NULL; lnet_peer_decref_locked(rxpeer); @@ -1218,9 +1229,12 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) LASSERT(!msg->msg_peertxcredit); LASSERT(!msg->msg_txcredit); - LASSERT(!msg->msg_txpeer); + LASSERT(msg->msg_txpeer == NULL); - msg->msg_txpeer = lp; /* msg takes my ref on lp */ + msg->msg_txpeer = lp; /* msg takes my ref on lp */ + /* set the NI for this message */ + msg->msg_txni = src_ni; + lnet_ni_addref_locked(msg->msg_txni, cpt); rc = lnet_post_send_locked(msg, 0); lnet_net_unlock(cpt); @@ -1818,6 +1832,8 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, return 0; goto drop; } + msg->msg_rxni = ni; + lnet_ni_addref_locked(ni, cpt); if (lnet_isrouter(msg->msg_rxpeer)) { lnet_peer_set_alive(msg->msg_rxpeer); @@ -1934,6 +1950,7 @@ lnet_recv_delayed_msg_list(struct list_head *head) LASSERT(msg->msg_rx_delayed); LASSERT(msg->msg_md); LASSERT(msg->msg_rxpeer); + LASSERT(msg->msg_rxni); LASSERT(msg->msg_hdr.type == LNET_MSG_PUT); CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d match %llu offset %d length %d.\n", From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 07/34] lnet: change lnet_peer to reference the net, rather than ni. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137151.8267.3943711043829439593.stgit@noble> As a net will soon have multiple ni, a peer should identify just the net. Various places that we need the ni, we now use rxni or txni from the message This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 + .../staging/lustre/include/linux/lnet/lib-types.h | 5 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 13 +++++ drivers/staging/lustre/lnet/lnet/lib-move.c | 49 +++++++++++--------- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 - drivers/staging/lustre/lnet/lnet/net_fault.c | 3 + drivers/staging/lustre/lnet/lnet/peer.c | 26 ++++------- drivers/staging/lustre/lnet/lnet/router.c | 14 +++--- drivers/staging/lustre/lnet/lnet/router_proc.c | 2 - 9 files changed, 67 insertions(+), 50 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 4440b87299c4..34509e52bac7 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -435,6 +435,7 @@ int lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf); int lnet_dyn_del_ni(__u32 net); int lnet_clear_lazy_portal(struct lnet_ni *ni, int portal, char *reason); +struct lnet_net *lnet_get_net_locked(__u32 net_id); int lnet_islocalnid(lnet_nid_t nid); int lnet_islocalnet(__u32 net); @@ -617,7 +618,7 @@ int lnet_sock_connect(struct socket **sockp, int *fatal, void libcfs_sock_release(struct socket *sock); int lnet_peers_start_down(void); -int lnet_peer_buffer_credits(struct lnet_ni *ni); +int lnet_peer_buffer_credits(struct lnet_net *net); int lnet_router_checker_start(void); void lnet_router_checker_stop(void); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 16a493529a46..255c6c4bbb89 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -396,7 +396,8 @@ struct lnet_peer { time64_t lp_last_query; /* when lp_ni was queried * last time */ - struct lnet_ni *lp_ni; /* interface peer is on */ + /* network peer is on */ + struct lnet_net *lp_net; lnet_nid_t lp_nid; /* peer's NID */ int lp_refcount; /* # refs */ int lp_cpt; /* CPT this peer attached on */ @@ -427,7 +428,7 @@ struct lnet_peer_table { * lnet_ni::ni_peertimeout has been set to a positive value */ #define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing && \ - (lp)->lp_ni->ni_net->net_tunables.lct_peer_timeout > 0) + (lp)->lp_net->net_tunables.lct_peer_timeout > 0) struct lnet_route { struct list_head lr_list; /* chain on net */ diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 05687278334a..c21aef32cdde 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -680,6 +680,19 @@ lnet_net2ni(__u32 net) } EXPORT_SYMBOL(lnet_net2ni); +struct lnet_net * +lnet_get_net_locked(__u32 net_id) +{ + struct lnet_net *net; + + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + if (net->net_id == net_id) + return net; + } + + return NULL; +} + static unsigned int lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) { diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b2a52ddcefcb..b8b15f56a275 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -525,7 +525,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) return 0; deadline = lp->lp_last_alive + - lp->lp_ni->ni_net->net_tunables.lct_peer_timeout; + lp->lp_net->net_tunables.lct_peer_timeout; alive = deadline > now; /* Update obsolete lp_alive except for routers assumed to be dead @@ -544,7 +544,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) * may drop the lnet_net_lock */ static int -lnet_peer_alive_locked(struct lnet_peer *lp) +lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) { time64_t now = ktime_get_seconds(); @@ -570,13 +570,13 @@ lnet_peer_alive_locked(struct lnet_peer *lp) libcfs_nid2str(lp->lp_nid), now, next_query, lnet_queryinterval, - lp->lp_ni->ni_net->net_tunables.lct_peer_timeout); + lp->lp_net->net_tunables.lct_peer_timeout); return 0; } } /* query NI for latest aliveness news */ - lnet_ni_query_locked(lp->lp_ni, lp); + lnet_ni_query_locked(ni, lp); if (lnet_peer_is_alive(lp, now)) return 1; @@ -600,7 +600,7 @@ static int lnet_post_send_locked(struct lnet_msg *msg, int do_send) { struct lnet_peer *lp = msg->msg_txpeer; - struct lnet_ni *ni = lp->lp_ni; + struct lnet_ni *ni = msg->msg_txni; int cpt = msg->msg_tx_cpt; struct lnet_tx_queue *tq = ni->ni_tx_queues[cpt]; @@ -611,7 +611,7 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) /* NB 'lp' is always the next hop */ if (!(msg->msg_target.pid & LNET_PID_USERFLAG) && - !lnet_peer_alive_locked(lp)) { + !lnet_peer_alive_locked(ni, lp)) { the_lnet.ln_counters[cpt]->drop_count++; the_lnet.ln_counters[cpt]->drop_length += msg->msg_len; lnet_net_unlock(cpt); @@ -770,7 +770,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) int cpt = msg->msg_rx_cpt; lnet_net_unlock(cpt); - lnet_ni_recv(lp->lp_ni, msg->msg_private, msg, 1, + lnet_ni_recv(msg->msg_rxni, msg->msg_private, msg, 1, 0, msg->msg_len, msg->msg_len); lnet_net_lock(cpt); } @@ -785,7 +785,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) struct lnet_ni *txni = msg->msg_txni; if (msg->msg_txcredit) { - struct lnet_ni *ni = txpeer->lp_ni; + struct lnet_ni *ni = msg->msg_txni; struct lnet_tx_queue *tq = ni->ni_tx_queues[msg->msg_tx_cpt]; /* give back NI txcredits */ @@ -800,7 +800,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) struct lnet_msg, msg_list); list_del(&msg2->msg_list); - LASSERT(msg2->msg_txpeer->lp_ni == ni); + LASSERT(msg2->msg_txni == ni); LASSERT(msg2->msg_tx_delayed); (void)lnet_post_send_locked(msg2, 1); @@ -869,7 +869,7 @@ lnet_drop_routed_msgs_locked(struct list_head *list, int cpt) while(!list_empty(&drop)) { msg = list_first_entry(&drop, struct lnet_msg, msg_list); - lnet_ni_recv(msg->msg_rxpeer->lp_ni, msg->msg_private, NULL, + lnet_ni_recv(msg->msg_rxni, msg->msg_private, NULL, 0, 0, 0, msg->msg_hdr.payload_length); list_del_init(&msg->msg_list); lnet_finalize(NULL, msg, -ECANCELED); @@ -1007,7 +1007,7 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) } static struct lnet_peer * -lnet_find_route_locked(struct lnet_ni *ni, lnet_nid_t target, +lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, lnet_nid_t rtr_nid) { struct lnet_remotenet *rnet; @@ -1035,7 +1035,7 @@ lnet_find_route_locked(struct lnet_ni *ni, lnet_nid_t target, if (!lnet_is_route_alive(route)) continue; - if (ni && lp->lp_ni != ni) + if (net && lp->lp_net != net) continue; if (lp->lp_nid == rtr_nid) /* it's pre-determined router */ @@ -1164,10 +1164,12 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) /* ENOMEM or shutting down */ return rc; } - LASSERT(lp->lp_ni == src_ni); + LASSERT(lp->lp_net == src_ni->ni_net); } else { /* sending to a remote network */ - lp = lnet_find_route_locked(src_ni, dst_nid, rtr_nid); + lp = lnet_find_route_locked(src_ni != NULL ? + src_ni->ni_net : NULL, + dst_nid, rtr_nid); if (!lp) { if (src_ni) lnet_ni_decref_locked(src_ni, cpt); @@ -1203,10 +1205,11 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) lnet_msgtyp2str(msg->msg_type), msg->msg_len); if (!src_ni) { - src_ni = lp->lp_ni; + src_ni = lnet_get_next_ni_locked(lp->lp_net, NULL); + LASSERT(src_ni != NULL); src_nid = src_ni->ni_nid; } else { - LASSERT(src_ni == lp->lp_ni); + LASSERT(src_ni->ni_net == lp->lp_net); lnet_ni_decref_locked(src_ni, cpt); } @@ -1918,7 +1921,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) * called lnet_drop_message(), so I just hang onto msg as well * until that's done */ - lnet_drop_message(msg->msg_rxpeer->lp_ni, + lnet_drop_message(msg->msg_rxni, msg->msg_rxpeer->lp_cpt, msg->msg_private, msg->msg_len); /* @@ -1926,7 +1929,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) * but we still should give error code so lnet_msg_decommit() * can skip counters operations and other checks. */ - lnet_finalize(msg->msg_rxpeer->lp_ni, msg, -ENOENT); + lnet_finalize(msg->msg_rxni, msg, -ENOENT); } } @@ -1959,7 +1962,7 @@ lnet_recv_delayed_msg_list(struct list_head *head) msg->msg_hdr.msg.put.offset, msg->msg_hdr.payload_length); - lnet_recv_put(msg->msg_rxpeer->lp_ni, msg); + lnet_recv_put(msg->msg_rxni, msg); } } @@ -2384,8 +2387,12 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) LASSERT(shortest); hops = shortest_hops; - if (srcnidp) - *srcnidp = shortest->lr_gateway->lp_ni->ni_nid; + if (srcnidp) { + ni = lnet_get_next_ni_locked( + shortest->lr_gateway->lp_net, + NULL); + *srcnidp = ni->ni_nid; + } if (orderp) *orderp = order; lnet_net_unlock(cpt); diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index fc47379c5938..4c5737083422 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -946,7 +946,7 @@ lnet_clear_lazy_portal(struct lnet_ni *ni, int portal, char *reason) /* grab all messages which are on the NI passed in */ list_for_each_entry_safe(msg, tmp, &ptl->ptl_msg_delayed, msg_list) { - if (msg->msg_rxpeer->lp_ni == ni) + if (msg->msg_txni == ni || msg->msg_rxni == ni) list_move(&msg->msg_list, &zombies); } } else { diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c index 41d6131ee15a..6c53ae1811e5 100644 --- a/drivers/staging/lustre/lnet/lnet/net_fault.c +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c @@ -601,8 +601,9 @@ delayed_msg_process(struct list_head *msg_list, bool drop) msg = list_entry(msg_list->next, struct lnet_msg, msg_list); LASSERT(msg->msg_rxpeer); + LASSERT(msg->msg_rxni != NULL); - ni = msg->msg_rxpeer->lp_ni; + ni = msg->msg_rxni; cpt = msg->msg_rx_cpt; list_del_init(&msg->msg_list); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index b76ac3e051d9..ed29124ebded 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -112,7 +112,7 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], lp_hashlist) { - if (ni && ni != lp->lp_ni) + if (ni && ni->ni_net != lp->lp_net) continue; list_del_init(&lp->lp_hashlist); /* Lose hash table's ref */ @@ -154,7 +154,7 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], lp_hashlist) { - if (ni != lp->lp_ni) + if (ni->ni_net != lp->lp_net) continue; if (!lp->lp_rtr_refcount) @@ -230,8 +230,7 @@ lnet_destroy_peer_locked(struct lnet_peer *lp) LASSERT(ptable->pt_number > 0); ptable->pt_number--; - lnet_ni_decref_locked(lp->lp_ni, lp->lp_cpt); - lp->lp_ni = NULL; + lp->lp_net = NULL; list_add(&lp->lp_hashlist, &ptable->pt_deathrow); LASSERT(ptable->pt_zombies > 0); @@ -336,16 +335,11 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) goto out; } - lp->lp_ni = lnet_net2ni_locked(LNET_NIDNET(nid), cpt2); - if (!lp->lp_ni) { - rc = -EHOSTUNREACH; - goto out; - } - - lp->lp_txcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; - lp->lp_mintxcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; - lp->lp_rtrcredits = lnet_peer_buffer_credits(lp->lp_ni); - lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni); + lp->lp_net = lnet_get_net_locked(LNET_NIDNET(!lp->lp_nid)); + lp->lp_txcredits = + lp->lp_mintxcredits = lp->lp_net->net_tunables.lct_peer_tx_credits; + lp->lp_rtrcredits = + lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_net); list_add_tail(&lp->lp_hashlist, &ptable->pt_hash[lnet_nid2peerhash(nid)]); @@ -383,7 +377,7 @@ lnet_debug_peer(lnet_nid_t nid) CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", libcfs_nid2str(lp->lp_nid), lp->lp_refcount, - aliveness, lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits, + aliveness, lp->lp_net->net_tunables.lct_peer_tx_credits, lp->lp_rtrcredits, lp->lp_minrtrcredits, lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob); @@ -439,7 +433,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, *nid = lp->lp_nid; *refcount = lp->lp_refcount; *ni_peer_tx_credits = - lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; + lp->lp_net->net_tunables.lct_peer_tx_credits; *peer_tx_credits = lp->lp_txcredits; *peer_rtr_credits = lp->lp_rtrcredits; *peer_min_rtr_credits = lp->lp_mintxcredits; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 135dfe793b0b..72b8ca2b0fc6 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -55,10 +55,8 @@ module_param(auto_down, int, 0444); MODULE_PARM_DESC(auto_down, "Automatically mark peers down on comms error"); int -lnet_peer_buffer_credits(struct lnet_ni *ni) +lnet_peer_buffer_credits(struct lnet_net *net) { - struct lnet_net *net = ni->ni_net; - /* NI option overrides LNet default */ if (net->net_tunables.lct_peer_rtr_credits > 0) return net->net_tunables.lct_peer_rtr_credits; @@ -373,7 +371,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, lnet_peer_addref_locked(route->lr_gateway); /* +1 for notify */ lnet_add_route_to_rnet(rnet2, route); - ni = route->lr_gateway->lp_ni; + ni = lnet_get_next_ni_locked(route->lr_gateway->lp_net, NULL); lnet_net_unlock(LNET_LOCK_EX); /* XXX Assume alive */ @@ -428,8 +426,8 @@ lnet_check_routes(void) continue; } - if (route->lr_gateway->lp_ni == - route2->lr_gateway->lp_ni) + if (route->lr_gateway->lp_net == + route2->lr_gateway->lp_net) continue; nid1 = route->lr_gateway->lp_nid; @@ -952,6 +950,7 @@ lnet_ping_router_locked(struct lnet_peer *rtr) struct lnet_rc_data *rcd = NULL; time64_t now = ktime_get_seconds(); time64_t secs; + struct lnet_ni *ni; lnet_peer_addref_locked(rtr); @@ -960,7 +959,8 @@ lnet_ping_router_locked(struct lnet_peer *rtr) lnet_notify_locked(rtr, 1, 0, now); /* Run any outstanding notifications */ - lnet_ni_notify_locked(rtr->lp_ni, rtr); + ni = lnet_get_next_ni_locked(rtr->lp_net, NULL); + lnet_ni_notify_locked(ni, rtr); if (!lnet_isrouter(rtr) || the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) { diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 2a366e9a8627..52714b898aac 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -489,7 +489,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, int nrefs = peer->lp_refcount; time64_t lastalive = -1; char *aliveness = "NA"; - int maxcr = peer->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; + int maxcr = peer->lp_net->net_tunables.lct_peer_tx_credits; int txcr = peer->lp_txcredits; int mintxcr = peer->lp_mintxcredits; int rtrcr = peer->lp_rtrcredits; From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 08/34] lnet: add cpt to lnet_match_info. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137155.8267.2566576537174390617.stgit@noble> This seems to be a more direct way to get the cpt needed in lnet_mt_of_match(). This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 1 + drivers/staging/lustre/lnet/lnet/lib-move.c | 1 + drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 255c6c4bbb89..2d2c066a11ba 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -511,6 +511,7 @@ enum lnet_match_flags { struct lnet_match_info { __u64 mi_mbits; struct lnet_process_id mi_id; + unsigned int mi_cpt; unsigned int mi_opc; unsigned int mi_portal; unsigned int mi_rlength; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b8b15f56a275..b6e81a693fc3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1303,6 +1303,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) info.mi_rlength = hdr->payload_length; info.mi_roffset = hdr->msg.put.offset; info.mi_mbits = hdr->msg.put.match_bits; + info.mi_cpt = msg->msg_rxpeer->lp_cpt; msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; ready_delay = msg->msg_rx_ready_delay; diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 4c5737083422..90ce51801726 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -292,7 +292,7 @@ lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg) rotor = ptl->ptl_rotor++; /* get round-robin factor */ if (portal_rotor == LNET_PTL_ROTOR_HASH_RT && routed) - cpt = lnet_cpt_of_nid(msg->msg_hdr.src_nid); + cpt = info->mi_cpt; else cpt = rotor % LNET_CPT_NUMBER; From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 09/34] lnet: add list of cpts to lnet_net. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137159.8267.921309094971745898.stgit@noble> struct lnet_net now has a list of cpts, which is the union of the cpts for each lnet_ni. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 6 + drivers/staging/lustre/lnet/lnet/config.c | 164 ++++++++++++++++++++ 2 files changed, 170 insertions(+) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 2d2c066a11ba..22957d142cc0 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -266,6 +266,12 @@ struct lnet_net { * lnet/include/lnet/nidstr.h */ __u32 net_id; + /* total number of CPTs in the array */ + __u32 net_ncpts; + + /* cumulative CPTs of all NIs in this net */ + __u32 *net_cpts; + /* network tunables */ struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index e83bdbec11e3..380a3fb1caba 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -91,11 +91,169 @@ lnet_net_unique(__u32 net, struct list_head *netlist) return true; } +static bool +in_array(__u32 *array, __u32 size, __u32 value) +{ + int i; + + for (i = 0; i < size; i++) { + if (array[i] == value) + return false; + } + + return true; +} + +static int +lnet_net_append_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net) +{ + __u32 *added_cpts = NULL; + int i, j = 0, rc = 0; + + /* + * no need to go futher since a subset of the NIs already exist on + * all CPTs + */ + if (net->net_ncpts == LNET_CPT_NUMBER) + return 0; + + if (cpts == NULL) { + /* there is an NI which will exist on all CPTs */ + if (net->net_cpts != NULL) + kvfree(net->net_cpts); + net->net_cpts = NULL; + net->net_ncpts = LNET_CPT_NUMBER; + return 0; + } + + if (net->net_cpts == NULL) { + net->net_cpts = kmalloc_array(ncpts, sizeof(net->net_cpts), + GFP_KERNEL); + if (net->net_cpts == NULL) + return -ENOMEM; + memcpy(net->net_cpts, cpts, ncpts); + return 0; + } + + added_cpts = kmalloc_array(LNET_CPT_NUMBER, sizeof(*added_cpts), + GFP_KERNEL); + if (added_cpts == NULL) + return -ENOMEM; + + for (i = 0; i < ncpts; i++) { + if (!in_array(net->net_cpts, net->net_ncpts, cpts[i])) { + added_cpts[j] = cpts[i]; + j++; + } + } + + /* append the new cpts if any to the list of cpts in the net */ + if (j > 0) { + __u32 *array = NULL, *loc; + __u32 total_entries = j + net->net_ncpts; + + array = kmalloc_array(total_entries, sizeof(*net->net_cpts), + GFP_KERNEL); + if (array == NULL) { + rc = -ENOMEM; + goto failed; + } + + memcpy(array, net->net_cpts, + net->net_ncpts * sizeof(*net->net_cpts)); + loc = array + net->net_ncpts; + memcpy(loc, added_cpts, j * sizeof(*net->net_cpts)); + + kfree(net->net_cpts); + net->net_ncpts = total_entries; + net->net_cpts = array; + } + +failed: + kfree(added_cpts); + + return rc; +} + +static void +lnet_net_remove_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net) +{ + struct lnet_ni *ni; + int rc; + + /* + * Operation Assumption: + * This function is called after an NI has been removed from + * its parent net. + * + * if we're removing an NI which exists on all CPTs then + * we have to check if any of the other NIs on this net also + * exists on all CPTs. If none, then we need to build our Net CPT + * list based on the remaining NIs. + * + * If the NI being removed exist on a subset of the CPTs then we + * alo rebuild the Net CPT list based on the remaining NIs, which + * should resutl in the expected Net CPT list. + */ + + /* + * sometimes this function can be called due to some failure + * creating an NI, before any of the cpts are allocated, so check + * for that case and don't do anything + */ + if (ncpts == 0) + return; + + if (ncpts == LNET_CPT_NUMBER) { + /* + * first iteration through the NI list in the net to see + * if any of the NIs exist on all the CPTs. If one is + * found then our job is done. + */ + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (ni->ni_ncpts == LNET_CPT_NUMBER) + return; + } + } + + /* + * Rebuild the Net CPT list again, thereby only including only the + * CPTs which the remaining NIs are associated with. + */ + if (net->net_cpts != NULL) { + kfree(net->net_cpts); + net->net_cpts = NULL; + } + + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, + net); + if (rc != 0) { + CERROR("Out of Memory\n"); + /* + * do our best to keep on going. Delete + * the net cpts and set it to NULL. This + * way we can keep on going but less + * efficiently, since memory accesses might be + * accross CPT lines. + */ + if (net->net_cpts != NULL) { + kfree(net->net_cpts); + net->net_cpts = NULL; + net->net_ncpts = LNET_CPT_NUMBER; + } + return; + } + } +} + void lnet_ni_free(struct lnet_ni *ni) { int i; + lnet_net_remove_cpts(ni->ni_cpts, ni->ni_ncpts, ni->ni_net); + if (ni->ni_refs) cfs_percpt_free(ni->ni_refs); @@ -128,6 +286,9 @@ lnet_net_free(struct lnet_net *net) lnet_ni_free(ni); } + if (net->net_cpts != NULL) + kfree(net->net_cpts); + kfree(net); } @@ -229,6 +390,9 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) ni->ni_net_ns = NULL; ni->ni_last_alive = ktime_get_real_seconds(); + rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); + if (rc != 0) + goto failed; list_add_tail(&ni->ni_netlist, &net->net_ni_list); return ni; From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 10/34] lnet: add ni arg to lnet_cpt_of_nid() In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137163.8267.8668023630519839070.stgit@noble> When choosing a cpt to use for a given network (identified by nid), the choice might depend on a particular interface which has already been identified - different interfaces can have different sets of cpts. So add an 'ni' arg to lnet_cpt_of_nid(). If given, choose a cpt from the cpts of that interface. If not given, choose one from the set of all cpts associated with any interface on the network. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 4 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 4 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 2 - .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 4 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 41 ++++++++++++-------- drivers/staging/lustre/lnet/lnet/lib-move.c | 12 +++--- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 - drivers/staging/lustre/lnet/lnet/peer.c | 4 +- drivers/staging/lustre/lnet/lnet/router.c | 4 +- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 - drivers/staging/lustre/lnet/selftest/framework.c | 3 + drivers/staging/lustre/lnet/selftest/selftest.h | 2 - 12 files changed, 48 insertions(+), 36 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 34509e52bac7..e32dbb854d80 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -395,8 +395,8 @@ lnet_net2rnethash(__u32 net) extern struct lnet_lnd the_lolnd; extern int avoid_asym_router_failure; -int lnet_cpt_of_nid_locked(lnet_nid_t nid); -int lnet_cpt_of_nid(lnet_nid_t nid); +int lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni); +int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); struct lnet_ni *lnet_net2ni(__u32 net); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index ade566d20c69..958ac9a99045 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -320,7 +320,7 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, { struct kib_peer *peer; struct kib_net *net = ni->ni_data; - int cpt = lnet_cpt_of_nid(nid); + int cpt = lnet_cpt_of_nid(nid, ni); unsigned long flags; LASSERT(net); @@ -643,7 +643,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm dev = net->ibn_dev; - cpt = lnet_cpt_of_nid(peer->ibp_nid); + cpt = lnet_cpt_of_nid(peer->ibp_nid, peer->ibp_ni); sched = kiblnd_data.kib_scheds[cpt]; LASSERT(sched->ibs_nthreads > 0); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index c266940cb2ae..e64c14914924 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -119,7 +119,7 @@ kiblnd_get_idle_tx(struct lnet_ni *ni, lnet_nid_t target) struct kib_tx *tx; struct kib_tx_poolset *tps; - tps = net->ibn_tx_ps[lnet_cpt_of_nid(target)]; + tps = net->ibn_tx_ps[lnet_cpt_of_nid(target, ni)]; node = kiblnd_pool_alloc_node(&tps->tps_poolset); if (!node) return NULL; diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 2036a0ae5917..ba68bcee90bc 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -101,7 +101,7 @@ static int ksocknal_create_peer(struct ksock_peer **peerp, struct lnet_ni *ni, struct lnet_process_id id) { - int cpt = lnet_cpt_of_nid(id.nid); + int cpt = lnet_cpt_of_nid(id.nid, ni); struct ksock_net *net = ni->ni_data; struct ksock_peer *peer; @@ -1099,7 +1099,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, LASSERT(conn->ksnc_proto); LASSERT(peerid.nid != LNET_NID_ANY); - cpt = lnet_cpt_of_nid(peerid.nid); + cpt = lnet_cpt_of_nid(peerid.nid, ni); if (active) { ksocknal_peer_addref(peer); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index c21aef32cdde..6e0b8310574d 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -713,31 +713,41 @@ lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) } int -lnet_cpt_of_nid_locked(lnet_nid_t nid) +lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni) { - struct lnet_ni *ni; + struct lnet_net *net; /* must called with hold of lnet_net_lock */ if (LNET_CPT_NUMBER == 1) return 0; /* the only one */ - /* take lnet_net_lock(any) would be OK */ - if (!list_empty(&the_lnet.ln_nis_cpt)) { - list_for_each_entry(ni, &the_lnet.ln_nis_cpt, ni_cptlist) { - if (LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid)) - continue; + /* + * If NI is provided then use the CPT identified in the NI cpt + * list if one exists. If one doesn't exist, then that NI is + * associated with all CPTs and it follows that the net it belongs + * to is implicitly associated with all CPTs, so just hash the nid + * and return that. + */ + if (ni != NULL) { + if (ni->ni_cpts != NULL) + return ni->ni_cpts[lnet_nid_cpt_hash(nid, + ni->ni_ncpts)]; + else + return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); + } - LASSERT(ni->ni_cpts); - return ni->ni_cpts[lnet_nid_cpt_hash - (nid, ni->ni_ncpts)]; - } + /* no NI provided so look at the net */ + net = lnet_get_net_locked(LNET_NIDNET(nid)); + + if (net != NULL && net->net_cpts) { + return net->net_cpts[lnet_nid_cpt_hash(nid, net->net_ncpts)]; } return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); } int -lnet_cpt_of_nid(lnet_nid_t nid) +lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni) { int cpt; int cpt2; @@ -745,11 +755,10 @@ lnet_cpt_of_nid(lnet_nid_t nid) if (LNET_CPT_NUMBER == 1) return 0; /* the only one */ - if (list_empty(&the_lnet.ln_nis_cpt)) - return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); - cpt = lnet_net_lock_current(); - cpt2 = lnet_cpt_of_nid_locked(nid); + + cpt2 = lnet_cpt_of_nid_locked(nid, ni); + lnet_net_unlock(cpt); return cpt2; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b6e81a693fc3..02cd1a5a466f 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1095,7 +1095,9 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) msg->msg_sending = 1; LASSERT(!msg->msg_tx_committed); - cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid); + local_ni = lnet_net2ni(LNET_NIDNET(dst_nid)); + cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid, + local_ni); again: lnet_net_lock(cpt); @@ -1188,7 +1190,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) * was changed when we release the lock */ if (rtr_nid != lp->lp_nid) { - cpt2 = lnet_cpt_of_nid_locked(lp->lp_nid); + cpt2 = lp->lp_cpt; if (cpt2 != cpt) { if (src_ni) lnet_ni_decref_locked(src_ni, cpt); @@ -1677,7 +1679,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, payload_length = le32_to_cpu(hdr->payload_length); for_me = (ni->ni_nid == dest_nid); - cpt = lnet_cpt_of_nid(from_nid); + cpt = lnet_cpt_of_nid(from_nid, ni); switch (type) { case LNET_MSG_ACK: @@ -2149,7 +2151,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) lnet_msg_attach_md(msg, getmd, getmd->md_offset, getmd->md_length); lnet_res_unlock(cpt); - cpt = lnet_cpt_of_nid(peer_id.nid); + cpt = lnet_cpt_of_nid(peer_id.nid, ni); lnet_net_lock(cpt); lnet_msg_commit(msg, cpt); @@ -2160,7 +2162,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) return msg; drop: - cpt = lnet_cpt_of_nid(peer_id.nid); + cpt = lnet_cpt_of_nid(peer_id.nid, ni); lnet_net_lock(cpt); the_lnet.ln_counters[cpt]->drop_count++; diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 90ce51801726..c8d8162cc706 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -220,7 +220,7 @@ lnet_match2mt(struct lnet_portal *ptl, struct lnet_process_id id, __u64 mbits) /* if it's a unique portal, return match-table hashed by NID */ return lnet_ptl_is_unique(ptl) ? - ptl->ptl_mtables[lnet_cpt_of_nid(id.nid)] : NULL; + ptl->ptl_mtables[lnet_cpt_of_nid(id.nid, NULL)] : NULL; } struct lnet_match_table * diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index ed29124ebded..808ce25f1f00 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -270,7 +270,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) return -ESHUTDOWN; /* cpt can be LNET_LOCK_EX if it's called from router functions */ - cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid); + cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid, NULL); ptable = the_lnet.ln_peer_tables[cpt2]; lp = lnet_find_peer_locked(ptable, nid); @@ -362,7 +362,7 @@ lnet_debug_peer(lnet_nid_t nid) int rc; int cpt; - cpt = lnet_cpt_of_nid(nid); + cpt = lnet_cpt_of_nid(nid, NULL); lnet_net_lock(cpt); rc = lnet_nid2peer_locked(&lp, nid, cpt); diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 72b8ca2b0fc6..5493d13de6d9 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -1207,7 +1207,7 @@ lnet_router_checker(void *arg) version = the_lnet.ln_routers_version; list_for_each_entry(rtr, &the_lnet.ln_routers, lp_rtr_list) { - cpt2 = lnet_cpt_of_nid_locked(rtr->lp_nid); + cpt2 = rtr->lp_cpt; if (cpt != cpt2) { lnet_net_unlock(cpt); cpt = cpt2; @@ -1693,7 +1693,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) { struct lnet_peer *lp = NULL; time64_t now = ktime_get_seconds(); - int cpt = lnet_cpt_of_nid(nid); + int cpt = lnet_cpt_of_nid(nid, ni); LASSERT(!in_interrupt()); diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index f1ee219bc8f3..e372ff3044c8 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -124,7 +124,7 @@ brw_client_init(struct sfw_test_instance *tsi) return -EINVAL; list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) { - bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid), + bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid, NULL), off, npg, len, opc == LST_BRW_READ); if (!bulk) { brw_client_fini(tsi); diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index 944a2a6598fa..a82efc394659 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -1013,7 +1013,8 @@ sfw_run_batch(struct sfw_batch *tsb) tsu->tsu_loop = tsi->tsi_loop; wi = &tsu->tsu_worker; swi_init_workitem(wi, sfw_run_test, - lst_test_wq[lnet_cpt_of_nid(tsu->tsu_dest.nid)]); + lst_test_wq[lnet_cpt_of_nid(tsu->tsu_dest.nid, + NULL)]); swi_schedule_workitem(wi); } } diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index 9dbb0a51d430..edf783af90e8 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -527,7 +527,7 @@ srpc_init_client_rpc(struct srpc_client_rpc *rpc, struct lnet_process_id peer, INIT_LIST_HEAD(&rpc->crpc_list); swi_init_workitem(&rpc->crpc_wi, srpc_send_rpc, - lst_test_wq[lnet_cpt_of_nid(peer.nid)]); + lst_test_wq[lnet_cpt_of_nid(peer.nid, NULL)]); spin_lock_init(&rpc->crpc_lock); atomic_set(&rpc->crpc_refcount, 1); /* 1 ref for caller */ From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 11/34] lnet: pass tun to lnet_startup_lndni, instead of full conf In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137168.8267.1167942220741712684.stgit@noble> I don't understand parts of this change. Particularly the removal for /* If given some LND tunable parameters, parse those now to * override the values in the NI structure. */ isn't clear to me. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 41 ++++++++--------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 6e0b8310574d..53ecfd700db3 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1240,10 +1240,8 @@ lnet_shutdown_lndni(struct lnet_ni *ni) } static int -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) { - struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; - struct lnet_lnd_tunables *tun = NULL; int rc = -EINVAL; int lnd_type; struct lnet_lnd *lnd; @@ -1296,36 +1294,12 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) ni->ni_net->net_lnd = lnd; - if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) { - lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; - tun = &lnd_tunables->lt_tun; - } - if (tun) { memcpy(&ni->ni_lnd_tunables, tun, sizeof(*tun)); ni->ni_lnd_tunables_set = true; } - /* - * If given some LND tunable parameters, parse those now to - * override the values in the NI structure. - */ - if (conf) { - if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) - ni->ni_net->net_tunables.lct_peer_rtr_credits = - conf->cfg_config_u.cfg_net.net_peer_rtr_credits; - if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) - ni->ni_net->net_tunables.lct_peer_timeout = - conf->cfg_config_u.cfg_net.net_peer_timeout; - if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) - ni->ni_net->net_tunables.lct_peer_tx_credits = - conf->cfg_config_u.cfg_net.net_peer_tx_credits; - if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) - ni->ni_net->net_tunables.lct_max_tx_credits = - conf->cfg_config_u.cfg_net.net_max_tx_credits; - } - rc = lnd->lnd_startup(ni); mutex_unlock(&the_lnet.ln_lnd_mutex); @@ -1861,9 +1835,13 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) struct list_head net_head; struct lnet_remotenet *rnet; int rc; + struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; INIT_LIST_HEAD(&net_head); + if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) + lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; + /* Create a net/ni structures for the network string */ rc = lnet_parse_networks(&net_head, nets); if (rc <= 0) @@ -1898,9 +1876,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) goto failed0; list_del_init(&net->net_list); + if (lnd_tunables) + memcpy(&net->net_tunables, + &lnd_tunables->lt_cmn, sizeof(lnd_tunables->lt_cmn)); + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); - rc = lnet_startup_lndni(ni, conf); - if (rc) + rc = lnet_startup_lndni(ni, (lnd_tunables ? + &lnd_tunables->lt_tun : NULL)); + if (rc < 0) goto failed1; if (ni->ni_net->net_lnd->lnd_accept) { From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 12/34] lnet: split lnet_startup_lndni In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137171.8267.13510813931908233567.stgit@noble> Split into lnet_startup_lndnet which starts all nis in a net, and lnet_startup_lndni which starts an individual ni. lnet_startup_lndni() returns 0 on success, or -ve error. lnet_startup_lndnis() returned the count of interfaces started. The new lnet_startup_lndnet() returns the count of started interfaces, This requires adding lnet_shutdown_lndnet() to handle errors in lnet_dyn_add_ni(), which now uses the new lnet_startup_lndnet(). We now drop the ln_lnd_mutex near the end of lnet_startup_lndnet(), and re-claim it for each lnet_startup_lndni(). This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 142 +++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 31 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 53ecfd700db3..8afddf11b5e2 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1239,32 +1239,61 @@ lnet_shutdown_lndni(struct lnet_ni *ni) lnet_net_unlock(LNET_LOCK_EX); } +static void +lnet_shutdown_lndnet(struct lnet_net *net) +{ + struct lnet_ni *ni; + + lnet_net_lock(LNET_LOCK_EX); + + list_del_init(&net->net_list); + + while (!list_empty(&net->net_ni_list)) { + ni = list_entry(net->net_ni_list.next, + struct lnet_ni, ni_netlist); + lnet_net_unlock(LNET_LOCK_EX); + lnet_shutdown_lndni(ni); + lnet_net_lock(LNET_LOCK_EX); + } + + /* + * decrement ref count on lnd only when the entire network goes + * away + */ + net->net_lnd->lnd_refcount--; + + lnet_net_unlock(LNET_LOCK_EX); + + lnet_net_free(net); +} + static int -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun); + +static int +lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) { - int rc = -EINVAL; - int lnd_type; - struct lnet_lnd *lnd; - struct lnet_tx_queue *tq; - int i; - u32 seed; + struct lnet_ni *ni; + __u32 lnd_type; + struct lnet_lnd *lnd; + int rc; - lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); + lnd_type = LNET_NETTYP(net->net_id); LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ lnet_net_lock(LNET_LOCK_EX); - rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nets); + rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); lnet_net_unlock(LNET_LOCK_EX); if (!rc) { if (lnd_type == LOLND) { - lnet_ni_free(ni); + lnet_net_free(net); return 0; } CERROR("Net %s is not unique\n", - libcfs_net2str(LNET_NIDNET(ni->ni_nid))); + libcfs_net2str(net->net_id)); rc = -EEXIST; goto failed0; } @@ -1291,8 +1320,32 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) lnet_net_lock(LNET_LOCK_EX); lnd->lnd_refcount++; lnet_net_unlock(LNET_LOCK_EX); + net->net_lnd = lnd; + mutex_unlock(&the_lnet.ln_lnd_mutex); - ni->ni_net->net_lnd = lnd; + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); + + rc = lnet_startup_lndni(ni, tun); + if (rc < 0) + return rc; + return 1; + +failed0: + lnet_net_free(net); + + return rc; +} + +static int +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) +{ + int rc = -EINVAL; + struct lnet_tx_queue *tq; + int i; + struct lnet_net *net = ni->ni_net; + u32 seed; + + mutex_lock(&the_lnet.ln_lnd_mutex); if (tun) { memcpy(&ni->ni_lnd_tunables, tun, @@ -1300,15 +1353,15 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) ni->ni_lnd_tunables_set = true; } - rc = lnd->lnd_startup(ni); + rc = net->net_lnd->lnd_startup(ni); mutex_unlock(&the_lnet.ln_lnd_mutex); if (rc) { LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n", - rc, libcfs_lnd2str(lnd->lnd_type)); + rc, libcfs_lnd2str(net->net_lnd->lnd_type)); lnet_net_lock(LNET_LOCK_EX); - lnd->lnd_refcount--; + net->net_lnd->lnd_refcount--; lnet_net_unlock(LNET_LOCK_EX); goto failed0; } @@ -1324,7 +1377,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) lnet_net_unlock(LNET_LOCK_EX); - if (lnd->lnd_type == LOLND) { + if (net->net_lnd->lnd_type == LOLND) { lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); the_lnet.ln_loni = ni; @@ -1338,7 +1391,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) if (!ni->ni_net->net_tunables.lct_peer_tx_credits || !ni->ni_net->net_tunables.lct_max_tx_credits) { LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n", - libcfs_lnd2str(lnd->lnd_type), + libcfs_lnd2str(net->net_lnd->lnd_type), !ni->ni_net->net_tunables.lct_peer_tx_credits ? "" : "per-peer "); /* @@ -1375,21 +1428,22 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) } static int -lnet_startup_lndnis(struct list_head *nilist) +lnet_startup_lndnets(struct list_head *netlist) { - struct lnet_ni *ni; + struct lnet_net *net; int rc; int ni_count = 0; - while (!list_empty(nilist)) { - ni = list_entry(nilist->next, struct lnet_ni, ni_netlist); - list_del(&ni->ni_netlist); - rc = lnet_startup_lndni(ni, NULL); + while (!list_empty(netlist)) { + net = list_entry(netlist->next, struct lnet_net, net_list); + list_del_init(&net->net_list); + + rc = lnet_startup_lndnet(net, NULL); if (rc < 0) goto failed; - ni_count++; + ni_count += rc; } return ni_count; @@ -1552,7 +1606,7 @@ LNetNIInit(lnet_pid_t requested_pid) goto err_empty_list; } - ni_count = lnet_startup_lndnis(&net_head); + ni_count = lnet_startup_lndnets(&net_head); if (ni_count < 0) { rc = ni_count; goto err_empty_list; @@ -1831,10 +1885,11 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; struct lnet_net *net; - struct lnet_ni *ni; struct list_head net_head; struct lnet_remotenet *rnet; int rc; + int num_acceptor_nets; + __u32 net_type; struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; INIT_LIST_HEAD(&net_head); @@ -1876,22 +1931,47 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) goto failed0; list_del_init(&net->net_list); + if (lnd_tunables) memcpy(&net->net_tunables, &lnd_tunables->lt_cmn, sizeof(lnd_tunables->lt_cmn)); - ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); - rc = lnet_startup_lndni(ni, (lnd_tunables ? + /* + * before starting this network get a count of the current TCP + * networks which require the acceptor thread running. If that + * count is == 0 before we start up this network, then we'd want to + * start up the acceptor thread after starting up this network + */ + num_acceptor_nets = lnet_count_acceptor_nets(); + + /* + * lnd_startup_lndnet() can deallocate 'net' even if it it returns + * success, because we endded up adding interfaces to an existing + * network. So grab the net_type now + */ + net_type = LNET_NETTYP(net->net_id); + + rc = lnet_startup_lndnet(net, (lnd_tunables ? &lnd_tunables->lt_tun : NULL)); if (rc < 0) goto failed1; - if (ni->ni_net->net_lnd->lnd_accept) { + /* + * Start the acceptor thread if this is the first network + * being added that requires the thread. + */ + if (net_type == SOCKLND && num_acceptor_nets == 0) { rc = lnet_acceptor_start(); if (rc < 0) { - /* shutdown the ni that we just started */ + /* shutdown the net that we just started */ CERROR("Failed to start up acceptor thread\n"); - lnet_shutdown_lndni(ni); + /* + * Note that if we needed to start the acceptor + * thread, then 'net' must have been the first TCP + * network, therefore was unique, and therefore + * wasn't deallocated by lnet_startup_lndnet() + */ + lnet_shutdown_lndnet(net); goto failed1; } } From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 13/34] lnet: reverse order of lnet_startup_lnd{net, ni} In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137175.8267.2271624767774752203.stgit@noble> Change the order - no other change. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 135 ++++++++++++++--------------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 8afddf11b5e2..09ea7e506128 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1267,75 +1267,6 @@ lnet_shutdown_lndnet(struct lnet_net *net) lnet_net_free(net); } -static int -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun); - -static int -lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) -{ - struct lnet_ni *ni; - __u32 lnd_type; - struct lnet_lnd *lnd; - int rc; - - lnd_type = LNET_NETTYP(net->net_id); - - LASSERT(libcfs_isknown_lnd(lnd_type)); - - /* Make sure this new NI is unique. */ - lnet_net_lock(LNET_LOCK_EX); - rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); - lnet_net_unlock(LNET_LOCK_EX); - if (!rc) { - if (lnd_type == LOLND) { - lnet_net_free(net); - return 0; - } - - CERROR("Net %s is not unique\n", - libcfs_net2str(net->net_id)); - rc = -EEXIST; - goto failed0; - } - - mutex_lock(&the_lnet.ln_lnd_mutex); - lnd = lnet_find_lnd_by_type(lnd_type); - - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - rc = request_module("%s", libcfs_lnd2modname(lnd_type)); - mutex_lock(&the_lnet.ln_lnd_mutex); - - lnd = lnet_find_lnd_by_type(lnd_type); - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - CERROR("Can't load LND %s, module %s, rc=%d\n", - libcfs_lnd2str(lnd_type), - libcfs_lnd2modname(lnd_type), rc); - rc = -EINVAL; - goto failed0; - } - } - - lnet_net_lock(LNET_LOCK_EX); - lnd->lnd_refcount++; - lnet_net_unlock(LNET_LOCK_EX); - net->net_lnd = lnd; - mutex_unlock(&the_lnet.ln_lnd_mutex); - - ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); - - rc = lnet_startup_lndni(ni, tun); - if (rc < 0) - return rc; - return 1; - -failed0: - lnet_net_free(net); - - return rc; -} - static int lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) { @@ -1427,6 +1358,72 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) return rc; } +static int +lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) +{ + struct lnet_ni *ni; + __u32 lnd_type; + struct lnet_lnd *lnd; + int rc; + + lnd_type = LNET_NETTYP(net->net_id); + + LASSERT(libcfs_isknown_lnd(lnd_type)); + + /* Make sure this new NI is unique. */ + lnet_net_lock(LNET_LOCK_EX); + rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); + lnet_net_unlock(LNET_LOCK_EX); + if (!rc) { + if (lnd_type == LOLND) { + lnet_net_free(net); + return 0; + } + + CERROR("Net %s is not unique\n", + libcfs_net2str(net->net_id)); + rc = -EEXIST; + goto failed0; + } + + mutex_lock(&the_lnet.ln_lnd_mutex); + lnd = lnet_find_lnd_by_type(lnd_type); + + if (!lnd) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + rc = request_module("%s", libcfs_lnd2modname(lnd_type)); + mutex_lock(&the_lnet.ln_lnd_mutex); + + lnd = lnet_find_lnd_by_type(lnd_type); + if (!lnd) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + CERROR("Can't load LND %s, module %s, rc=%d\n", + libcfs_lnd2str(lnd_type), + libcfs_lnd2modname(lnd_type), rc); + rc = -EINVAL; + goto failed0; + } + } + + lnet_net_lock(LNET_LOCK_EX); + lnd->lnd_refcount++; + lnet_net_unlock(LNET_LOCK_EX); + net->net_lnd = lnd; + mutex_unlock(&the_lnet.ln_lnd_mutex); + + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); + + rc = lnet_startup_lndni(ni, tun); + if (rc < 0) + return rc; + return 1; + +failed0: + lnet_net_free(net); + + return rc; +} + static int lnet_startup_lndnets(struct list_head *netlist) { From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 14/34] lnet: rename lnet_find_net_locked to lnet_find_rnet_locked In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137179.8267.355535015389180735.stgit@noble> This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 2 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 2 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- drivers/staging/lustre/lnet/lnet/router.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index e32dbb854d80..faa3f19dd844 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -430,7 +430,7 @@ int lnet_rtrpools_adjust(int tiny, int small, int large); int lnet_rtrpools_enable(void); void lnet_rtrpools_disable(void); void lnet_rtrpools_free(int keep_pools); -struct lnet_remotenet *lnet_find_net_locked(__u32 net); +struct lnet_remotenet *lnet_find_rnet_locked(__u32 net); int lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf); int lnet_dyn_del_ni(__u32 net); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 09ea7e506128..c3c568e63342 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1909,7 +1909,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) net = list_entry(net_head.next, struct lnet_net, net_list); lnet_net_lock(LNET_LOCK_EX); - rnet = lnet_find_net_locked(net->net_id); + rnet = lnet_find_rnet_locked(net->net_id); lnet_net_unlock(LNET_LOCK_EX); /* * make sure that the net added doesn't invalidate the current diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 02cd1a5a466f..00a89221c9b3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1022,7 +1022,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, * If @rtr_nid is not LNET_NID_ANY, return the gateway with * rtr_nid nid, otherwise find the best gateway I can use */ - rnet = lnet_find_net_locked(LNET_NIDNET(target)); + rnet = lnet_find_rnet_locked(LNET_NIDNET(target)); if (!rnet) return NULL; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 5493d13de6d9..1fce991fcb0e 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -220,7 +220,7 @@ lnet_rtr_decref_locked(struct lnet_peer *lp) } struct lnet_remotenet * -lnet_find_net_locked(__u32 net) +lnet_find_rnet_locked(__u32 net) { struct lnet_remotenet *rnet; struct list_head *rn_list; @@ -347,7 +347,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, LASSERT(!the_lnet.ln_shutdown); - rnet2 = lnet_find_net_locked(net); + rnet2 = lnet_find_rnet_locked(net); if (!rnet2) { /* new network */ list_add_tail(&rnet->lrn_list, lnet_net2rnethash(net)); From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 15/34] lnet: extend zombie handling to nets and nis In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137183.8267.14166864803956204561.stgit@noble> A zombie lnet_ni is now attached to the lnet_net rather than the global the_lnet. The zombie lnet_net are attached to the_lnet. For some reason, we don't drop the refcount on the lnd before shutting it down now. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 9 ++- drivers/staging/lustre/lnet/lnet/api-ni.c | 65 ++++++++++---------- drivers/staging/lustre/lnet/lnet/config.c | 3 + 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 22957d142cc0..1d372672e2de 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -284,6 +284,9 @@ struct lnet_net { struct lnet_lnd *net_lnd; /* list of NIs on this net */ struct list_head net_ni_list; + + /* dying LND instances */ + struct list_head net_ni_zombie; }; struct lnet_ni { @@ -653,11 +656,11 @@ struct lnet { /* LND instances */ struct list_head ln_nets; /* NIs bond on specific CPT(s) */ - struct list_head ln_nis_cpt; - /* dying LND instances */ - struct list_head ln_nis_zombie; + struct list_head ln_nis_cpt; /* the loopback NI */ struct lnet_ni *ln_loni; + /* network zombie list */ + struct list_head ln_net_zombie; /* remote networks with routes to them */ struct list_head *ln_remote_nets_hash; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index c3c568e63342..18d111cb826b 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -539,7 +539,6 @@ lnet_prepare(lnet_pid_t requested_pid) INIT_LIST_HEAD(&the_lnet.ln_test_peers); INIT_LIST_HEAD(&the_lnet.ln_nets); INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); - INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); INIT_LIST_HEAD(&the_lnet.ln_routers); INIT_LIST_HEAD(&the_lnet.ln_drop_rules); INIT_LIST_HEAD(&the_lnet.ln_delay_rules); @@ -618,7 +617,6 @@ lnet_unprepare(void) LASSERT(list_empty(&the_lnet.ln_test_peers)); LASSERT(list_empty(&the_lnet.ln_nets)); LASSERT(list_empty(&the_lnet.ln_nis_cpt)); - LASSERT(list_empty(&the_lnet.ln_nis_zombie)); lnet_portals_destroy(); @@ -1095,34 +1093,35 @@ lnet_ni_unlink_locked(struct lnet_ni *ni) /* move it to zombie list and nobody can find it anymore */ LASSERT(!list_empty(&ni->ni_netlist)); - list_move(&ni->ni_netlist, &the_lnet.ln_nis_zombie); + list_move(&ni->ni_netlist, &ni->ni_net->net_ni_zombie); lnet_ni_decref_locked(ni, 0); } static void -lnet_clear_zombies_nis_locked(void) +lnet_clear_zombies_nis_locked(struct lnet_net *net) { int i; int islo; struct lnet_ni *ni; + struct list_head *zombie_list = &net->net_ni_zombie; /* - * Now wait for the NI's I just nuked to show up on ln_zombie_nis - * and shut them down in guaranteed thread context + * Now wait for the NIs I just nuked to show up on the zombie + * list and shut them down in guaranteed thread context */ i = 2; - while (!list_empty(&the_lnet.ln_nis_zombie)) { + while (!list_empty(zombie_list)) { int *ref; int j; - ni = list_entry(the_lnet.ln_nis_zombie.next, + ni = list_entry(zombie_list->next, struct lnet_ni, ni_netlist); list_del_init(&ni->ni_netlist); cfs_percpt_for_each(ref, j, ni->ni_refs) { if (!*ref) continue; /* still busy, add it back to zombie list */ - list_add(&ni->ni_netlist, &the_lnet.ln_nis_zombie); + list_add(&ni->ni_netlist, zombie_list); break; } @@ -1138,18 +1137,13 @@ lnet_clear_zombies_nis_locked(void) continue; } - ni->ni_net->net_lnd->lnd_refcount--; lnet_net_unlock(LNET_LOCK_EX); islo = ni->ni_net->net_lnd->lnd_type == LOLND; LASSERT(!in_interrupt()); - ni->ni_net->net_lnd->lnd_shutdown(ni); + net->net_lnd->lnd_shutdown(ni); - /* - * can't deref lnd anymore now; it might have unregistered - * itself... - */ if (!islo) CDEBUG(D_LNI, "Removed LNI %s\n", libcfs_nid2str(ni->ni_nid)); @@ -1162,9 +1156,11 @@ lnet_clear_zombies_nis_locked(void) } static void -lnet_shutdown_lndnis(void) +lnet_shutdown_lndnet(struct lnet_net *net); + +static void +lnet_shutdown_lndnets(void) { - struct lnet_ni *ni; int i; struct lnet_net *net; @@ -1173,30 +1169,35 @@ lnet_shutdown_lndnis(void) /* All quiet on the API front */ LASSERT(!the_lnet.ln_shutdown); LASSERT(!the_lnet.ln_refcount); - LASSERT(list_empty(&the_lnet.ln_nis_zombie)); lnet_net_lock(LNET_LOCK_EX); the_lnet.ln_shutdown = 1; /* flag shutdown */ - /* Unlink NIs from the global table */ while (!list_empty(&the_lnet.ln_nets)) { + /* + * move the nets to the zombie list to avoid them being + * picked up for new work. LONET is also included in the + * Nets that will be moved to the zombie list + */ net = list_entry(the_lnet.ln_nets.next, struct lnet_net, net_list); - while (!list_empty(&net->net_ni_list)) { - ni = list_entry(net->net_ni_list.next, - struct lnet_ni, ni_netlist); - lnet_ni_unlink_locked(ni); - } + list_move(&net->net_list, &the_lnet.ln_net_zombie); } - /* Drop the cached loopback NI. */ + /* Drop the cached loopback Net. */ if (the_lnet.ln_loni) { lnet_ni_decref_locked(the_lnet.ln_loni, 0); the_lnet.ln_loni = NULL; } - lnet_net_unlock(LNET_LOCK_EX); + /* iterate through the net zombie list and delete each net */ + while (!list_empty(&the_lnet.ln_net_zombie)) { + net = list_entry(the_lnet.ln_net_zombie.next, + struct lnet_net, net_list); + lnet_shutdown_lndnet(net); + } + /* * Clear lazy portals and drop delayed messages which hold refs * on their lnet_msg::msg_rxpeer @@ -1211,8 +1212,6 @@ lnet_shutdown_lndnis(void) lnet_peer_tables_cleanup(NULL); lnet_net_lock(LNET_LOCK_EX); - - lnet_clear_zombies_nis_locked(); the_lnet.ln_shutdown = 0; lnet_net_unlock(LNET_LOCK_EX); } @@ -1222,6 +1221,7 @@ static void lnet_shutdown_lndni(struct lnet_ni *ni) { int i; + struct lnet_net *net = ni->ni_net; lnet_net_lock(LNET_LOCK_EX); lnet_ni_unlink_locked(ni); @@ -1235,7 +1235,7 @@ lnet_shutdown_lndni(struct lnet_ni *ni) lnet_peer_tables_cleanup(ni); lnet_net_lock(LNET_LOCK_EX); - lnet_clear_zombies_nis_locked(); + lnet_clear_zombies_nis_locked(net); lnet_net_unlock(LNET_LOCK_EX); } @@ -1445,7 +1445,7 @@ lnet_startup_lndnets(struct list_head *netlist) return ni_count; failed: - lnet_shutdown_lndnis(); + lnet_shutdown_lndnets(); return rc; } @@ -1492,6 +1492,7 @@ int lnet_lib_init(void) the_lnet.ln_refcount = 0; LNetInvalidateEQHandle(&the_lnet.ln_rc_eqh); INIT_LIST_HEAD(&the_lnet.ln_lnds); + INIT_LIST_HEAD(&the_lnet.ln_net_zombie); INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie); INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow); @@ -1656,7 +1657,7 @@ LNetNIInit(lnet_pid_t requested_pid) if (!the_lnet.ln_nis_from_mod_params) lnet_destroy_routes(); err_shutdown_lndnis: - lnet_shutdown_lndnis(); + lnet_shutdown_lndnets(); err_empty_list: lnet_unprepare(); LASSERT(rc < 0); @@ -1703,7 +1704,7 @@ LNetNIFini(void) lnet_acceptor_stop(); lnet_destroy_routes(); - lnet_shutdown_lndnis(); + lnet_shutdown_lndnets(); lnet_unprepare(); } diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 380a3fb1caba..2588d67fea1b 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -279,6 +279,8 @@ lnet_net_free(struct lnet_net *net) struct list_head *tmp, *tmp2; struct lnet_ni *ni; + LASSERT(list_empty(&net->net_ni_zombie)); + /* delete any nis which have been started. */ list_for_each_safe(tmp, tmp2, &net->net_ni_list) { ni = list_entry(tmp, struct lnet_ni, ni_netlist); @@ -312,6 +314,7 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) INIT_LIST_HEAD(&net->net_list); INIT_LIST_HEAD(&net->net_ni_list); + INIT_LIST_HEAD(&net->net_ni_zombie); net->net_id = net_id; From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 16/34] lnet: lnet_shutdown_lndnets - remove some cleanup code. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137187.8267.1370078359892639459.stgit@noble> I don't know what this did, or why it is being removed. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 18d111cb826b..2529a11c6c59 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1161,7 +1161,6 @@ lnet_shutdown_lndnet(struct lnet_net *net); static void lnet_shutdown_lndnets(void) { - int i; struct lnet_net *net; /* NB called holding the global mutex */ @@ -1198,19 +1197,6 @@ lnet_shutdown_lndnets(void) lnet_shutdown_lndnet(net); } - /* - * Clear lazy portals and drop delayed messages which hold refs - * on their lnet_msg::msg_rxpeer - */ - for (i = 0; i < the_lnet.ln_nportals; i++) - LNetClearLazyPortal(i); - - /* - * Clear the peer table and wait for all peers to go (they hold refs on - * their NIs) - */ - lnet_peer_tables_cleanup(NULL); - lnet_net_lock(LNET_LOCK_EX); the_lnet.ln_shutdown = 0; lnet_net_unlock(LNET_LOCK_EX); From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 17/34] lnet: move lnet_shutdown_lndnets down to after first use In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137192.8267.6087363236690952153.stgit@noble> This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 91 ++++++++++++++--------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2529a11c6c59..46c5ca71bc07 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1155,53 +1155,6 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net) } } -static void -lnet_shutdown_lndnet(struct lnet_net *net); - -static void -lnet_shutdown_lndnets(void) -{ - struct lnet_net *net; - - /* NB called holding the global mutex */ - - /* All quiet on the API front */ - LASSERT(!the_lnet.ln_shutdown); - LASSERT(!the_lnet.ln_refcount); - - lnet_net_lock(LNET_LOCK_EX); - the_lnet.ln_shutdown = 1; /* flag shutdown */ - - while (!list_empty(&the_lnet.ln_nets)) { - /* - * move the nets to the zombie list to avoid them being - * picked up for new work. LONET is also included in the - * Nets that will be moved to the zombie list - */ - net = list_entry(the_lnet.ln_nets.next, - struct lnet_net, net_list); - list_move(&net->net_list, &the_lnet.ln_net_zombie); - } - - /* Drop the cached loopback Net. */ - if (the_lnet.ln_loni) { - lnet_ni_decref_locked(the_lnet.ln_loni, 0); - the_lnet.ln_loni = NULL; - } - lnet_net_unlock(LNET_LOCK_EX); - - /* iterate through the net zombie list and delete each net */ - while (!list_empty(&the_lnet.ln_net_zombie)) { - net = list_entry(the_lnet.ln_net_zombie.next, - struct lnet_net, net_list); - lnet_shutdown_lndnet(net); - } - - lnet_net_lock(LNET_LOCK_EX); - the_lnet.ln_shutdown = 0; - lnet_net_unlock(LNET_LOCK_EX); -} - /* shutdown down the NI and release refcount */ static void lnet_shutdown_lndni(struct lnet_ni *ni) @@ -1253,6 +1206,50 @@ lnet_shutdown_lndnet(struct lnet_net *net) lnet_net_free(net); } +static void +lnet_shutdown_lndnets(void) +{ + struct lnet_net *net; + + /* NB called holding the global mutex */ + + /* All quiet on the API front */ + LASSERT(!the_lnet.ln_shutdown); + LASSERT(!the_lnet.ln_refcount); + + lnet_net_lock(LNET_LOCK_EX); + the_lnet.ln_shutdown = 1; /* flag shutdown */ + + while (!list_empty(&the_lnet.ln_nets)) { + /* + * move the nets to the zombie list to avoid them being + * picked up for new work. LONET is also included in the + * Nets that will be moved to the zombie list + */ + net = list_entry(the_lnet.ln_nets.next, + struct lnet_net, net_list); + list_move(&net->net_list, &the_lnet.ln_net_zombie); + } + + /* Drop the cached loopback Net. */ + if (the_lnet.ln_loni) { + lnet_ni_decref_locked(the_lnet.ln_loni, 0); + the_lnet.ln_loni = NULL; + } + lnet_net_unlock(LNET_LOCK_EX); + + /* iterate through the net zombie list and delete each net */ + while (!list_empty(&the_lnet.ln_net_zombie)) { + net = list_entry(the_lnet.ln_net_zombie.next, + struct lnet_net, net_list); + lnet_shutdown_lndnet(net); + } + + lnet_net_lock(LNET_LOCK_EX); + the_lnet.ln_shutdown = 0; + lnet_net_unlock(LNET_LOCK_EX); +} + static int lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) { From neilb at suse.com Fri Sep 7 00:49:31 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:31 +1000 Subject: [lustre-devel] [PATCH 18/34] lnet: add ni_state In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137195.8267.16400748098054215181.stgit@noble> This is barely used. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + .../staging/lustre/include/linux/lnet/lib-types.h | 16 ++++++++++++++++ drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++++++++++ drivers/staging/lustre/lnet/lnet/config.c | 1 + 4 files changed, 34 insertions(+) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index faa3f19dd844..54a93235834c 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -400,6 +400,7 @@ int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); struct lnet_ni *lnet_net2ni(__u32 net); +bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); extern int portal_rotor; diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 1d372672e2de..6c34ecf22021 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -256,6 +256,19 @@ struct lnet_tx_queue { struct list_head tq_delayed; /* delayed TXs */ }; +enum lnet_ni_state { + /* set when NI block is allocated */ + LNET_NI_STATE_INIT = 0, + /* set when NI is started successfully */ + LNET_NI_STATE_ACTIVE, + /* set when LND notifies NI failed */ + LNET_NI_STATE_FAILED, + /* set when LND notifies NI degraded */ + LNET_NI_STATE_DEGRADED, + /* set when shuttding down NI */ + LNET_NI_STATE_DELETING +}; + struct lnet_net { /* chain on the ln_nets */ struct list_head net_list; @@ -324,6 +337,9 @@ struct lnet_ni { /* my health status */ struct lnet_ni_status *ni_status; + /* NI FSM */ + enum lnet_ni_state ni_state; + /* per NI LND tunables */ struct lnet_lnd_tunables ni_lnd_tunables; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 46c5ca71bc07..618fdf8141f0 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -780,6 +780,16 @@ lnet_islocalnet(__u32 net) return !!ni; } +bool +lnet_is_ni_healthy_locked(struct lnet_ni *ni) +{ + if (ni->ni_state == LNET_NI_STATE_ACTIVE || + ni->ni_state == LNET_NI_STATE_DEGRADED) + return true; + + return false; +} + struct lnet_ni * lnet_nid2ni_locked(lnet_nid_t nid, int cpt) { @@ -1117,6 +1127,9 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net) ni = list_entry(zombie_list->next, struct lnet_ni, ni_netlist); list_del_init(&ni->ni_netlist); + /* the ni should be in deleting state. If it's not it's + * a bug */ + LASSERT(ni->ni_state == LNET_NI_STATE_DELETING); cfs_percpt_for_each(ref, j, ni->ni_refs) { if (!*ref) continue; @@ -1163,6 +1176,7 @@ lnet_shutdown_lndni(struct lnet_ni *ni) struct lnet_net *net = ni->ni_net; lnet_net_lock(LNET_LOCK_EX); + ni->ni_state = LNET_NI_STATE_DELETING; lnet_ni_unlink_locked(ni); lnet_net_unlock(LNET_LOCK_EX); @@ -1291,6 +1305,8 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) lnet_net_unlock(LNET_LOCK_EX); + ni->ni_state = LNET_NI_STATE_ACTIVE; + if (net->net_lnd->lnd_type == LOLND) { lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 2588d67fea1b..081812e19b13 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -393,6 +393,7 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) ni->ni_net_ns = NULL; ni->ni_last_alive = ktime_get_real_seconds(); + ni->ni_state = LNET_NI_STATE_INIT; rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); if (rc != 0) goto failed; From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 19/34] lnet: simplify lnet_islocalnet() In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137199.8267.13740900509571445302.stgit@noble> Having lnet_get_net_locked() makes this (a little) simpler. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 618fdf8141f0..546d5101360f 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -764,20 +764,16 @@ lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni) EXPORT_SYMBOL(lnet_cpt_of_nid); int -lnet_islocalnet(__u32 net) +lnet_islocalnet(__u32 net_id) { - struct lnet_ni *ni; - int cpt; + struct lnet_net *net; + int cpt; cpt = lnet_net_lock_current(); - - ni = lnet_net2ni_locked(net, cpt); - if (ni) - lnet_ni_decref_locked(ni, cpt); - + net = lnet_get_net_locked(net_id); lnet_net_unlock(cpt); - return !!ni; + return !!net; } bool From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 20/34] lnet: discard ni_cpt_list In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137203.8267.14277020278461943610.stgit@noble> This isn't used any more. The new comment is odd - this is no net_ni_cpt !! The ni_cptlist linkage is no longer used - should it go too? This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 4 +--- drivers/staging/lustre/lnet/lnet/api-ni.c | 7 ------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 6c34ecf22021..dc15fa75a9d2 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -305,7 +305,7 @@ struct lnet_net { struct lnet_ni { /* chain on the lnet_net structure */ struct list_head ni_netlist; - /* chain on ln_nis_cpt */ + /* chain on net_ni_cpt */ struct list_head ni_cptlist; spinlock_t ni_lock; @@ -671,8 +671,6 @@ struct lnet { /* LND instances */ struct list_head ln_nets; - /* NIs bond on specific CPT(s) */ - struct list_head ln_nis_cpt; /* the loopback NI */ struct lnet_ni *ln_loni; /* network zombie list */ diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 546d5101360f..960f235df5e7 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -538,7 +538,6 @@ lnet_prepare(lnet_pid_t requested_pid) INIT_LIST_HEAD(&the_lnet.ln_test_peers); INIT_LIST_HEAD(&the_lnet.ln_nets); - INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); INIT_LIST_HEAD(&the_lnet.ln_routers); INIT_LIST_HEAD(&the_lnet.ln_drop_rules); INIT_LIST_HEAD(&the_lnet.ln_delay_rules); @@ -616,7 +615,6 @@ lnet_unprepare(void) LASSERT(!the_lnet.ln_refcount); LASSERT(list_empty(&the_lnet.ln_test_peers)); LASSERT(list_empty(&the_lnet.ln_nets)); - LASSERT(list_empty(&the_lnet.ln_nis_cpt)); lnet_portals_destroy(); @@ -1294,11 +1292,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) /* refcount for ln_nis */ lnet_ni_addref_locked(ni, 0); list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); - if (ni->ni_cpts) { - lnet_ni_addref_locked(ni, 0); - list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); - } - lnet_net_unlock(LNET_LOCK_EX); ni->ni_state = LNET_NI_STATE_ACTIVE; From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 21/34] lnet: add net_ni_added In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137207.8267.8628833457984431545.stgit@noble> When we allocate an ni, it is now added to the new net_ni_added list of unstarted interfaces. lnet_startup_lndnet() now starts all those added interfaces. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 3 ++ drivers/staging/lustre/lnet/lnet/api-ni.c | 39 +++++++++++++++++--- drivers/staging/lustre/lnet/lnet/config.c | 13 ++++++- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index dc15fa75a9d2..1faa247a93b8 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -298,6 +298,9 @@ struct lnet_net { /* list of NIs on this net */ struct list_head net_ni_list; + /* list of NIs being added, but not started yet */ + struct list_head net_ni_added; + /* dying LND instances */ struct list_head net_ni_zombie; }; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 960f235df5e7..ce3dd0f32e12 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1350,12 +1350,15 @@ static int lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) { struct lnet_ni *ni; + struct list_head local_ni_list; + int rc; + int ni_count = 0; __u32 lnd_type; struct lnet_lnd *lnd; - int rc; lnd_type = LNET_NETTYP(net->net_id); + INIT_LIST_HEAD(&local_ni_list); LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ @@ -1399,12 +1402,36 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) net->net_lnd = lnd; mutex_unlock(&the_lnet.ln_lnd_mutex); - ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); + while (!list_empty(&net->net_ni_added)) { + ni = list_entry(net->net_ni_added.next, struct lnet_ni, + ni_netlist); + list_del_init(&ni->ni_netlist); - rc = lnet_startup_lndni(ni, tun); - if (rc < 0) - return rc; - return 1; + rc = lnet_startup_lndni(ni, tun); + + if (rc < 0) + goto failed1; + + list_add_tail(&ni->ni_netlist, &local_ni_list); + + ni_count++; + } + lnet_net_lock(LNET_LOCK_EX); + list_splice_tail(&local_ni_list, &net->net_ni_list); + lnet_net_unlock(LNET_LOCK_EX); + return ni_count; + +failed1: + /* + * shutdown the new NIs that are being started up + * free the NET being started + */ + while (!list_empty(&local_ni_list)) { + ni = list_entry(local_ni_list.next, struct lnet_ni, + ni_netlist); + + lnet_shutdown_lndni(ni); + } failed0: lnet_net_free(net); diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 081812e19b13..f886dcfc6d6e 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -281,6 +281,16 @@ lnet_net_free(struct lnet_net *net) LASSERT(list_empty(&net->net_ni_zombie)); + /* + * delete any nis that haven't been added yet. This could happen + * if there is a failure on net startup + */ + list_for_each_safe(tmp, tmp2, &net->net_ni_added) { + ni = list_entry(tmp, struct lnet_ni, ni_netlist); + list_del_init(&ni->ni_netlist); + lnet_ni_free(ni); + } + /* delete any nis which have been started. */ list_for_each_safe(tmp, tmp2, &net->net_ni_list) { ni = list_entry(tmp, struct lnet_ni, ni_netlist); @@ -314,6 +324,7 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) INIT_LIST_HEAD(&net->net_list); INIT_LIST_HEAD(&net->net_ni_list); + INIT_LIST_HEAD(&net->net_ni_added); INIT_LIST_HEAD(&net->net_ni_zombie); net->net_id = net_id; @@ -397,7 +408,7 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); if (rc != 0) goto failed; - list_add_tail(&ni->ni_netlist, &net->net_ni_list); + list_add_tail(&ni->ni_netlist, &net->net_ni_added); return ni; failed: From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 22/34] lnet: don't take reference in lnet_XX2ni_locked() In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137211.8267.6066882916704220570.stgit@noble> lnet_net2ni_locked() and lnet_nid2ni_locked() no longer take a reference - as the lock is held, a ref isn't always needed. Instead, introduce lnet_nid2ni_addref() which does take the reference (but doesn't need the lock). Various places which called lnet_net2ni_locked() or lnet_nid2ni_locked() no longer need to drop the ref afterwards. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 2 + drivers/staging/lustre/lnet/lnet/acceptor.c | 2 + drivers/staging/lustre/lnet/lnet/api-ni.c | 27 +++++++++++++------- drivers/staging/lustre/lnet/lnet/lib-move.c | 17 +------------ 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 54a93235834c..6401d9a37b23 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -398,6 +398,7 @@ extern int avoid_asym_router_failure; int lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni); int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); +struct lnet_ni *lnet_nid2ni_addref(lnet_nid_t nid); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); struct lnet_ni *lnet_net2ni(__u32 net); bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index e64c14914924..af8f863b6a68 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -2294,7 +2294,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) } nid = reqmsg->ibm_srcnid; - ni = lnet_net2ni(LNET_NIDNET(reqmsg->ibm_dstnid)); + ni = lnet_nid2ni_addref(reqmsg->ibm_dstnid); if (ni) { net = (struct kib_net *)ni->ni_data; diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index 88b90c1fdbaf..25205f686801 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -296,7 +296,7 @@ lnet_accept(struct socket *sock, __u32 magic) if (flip) __swab64s(&cr.acr_nid); - ni = lnet_net2ni(LNET_NIDNET(cr.acr_nid)); + ni = lnet_nid2ni_addref(cr.acr_nid); if (!ni || /* no matching net */ ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */ if (ni) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ce3dd0f32e12..42e775e2a669 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -655,7 +655,6 @@ lnet_net2ni_locked(__u32 net_id, int cpt) if (net->net_id == net_id) { ni = list_entry(net->net_ni_list.next, struct lnet_ni, ni_netlist); - lnet_ni_addref_locked(ni, cpt); return ni; } } @@ -794,16 +793,29 @@ lnet_nid2ni_locked(lnet_nid_t nid, int cpt) list_for_each_entry(net, &the_lnet.ln_nets, net_list) { list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { - if (ni->ni_nid == nid) { - lnet_ni_addref_locked(ni, cpt); + if (ni->ni_nid == nid) return ni; - } } } return NULL; } +struct lnet_ni * +lnet_nid2ni_addref(lnet_nid_t nid) +{ + struct lnet_ni *ni; + + lnet_net_lock(0); + ni = lnet_nid2ni_locked(nid, 0); + if (ni) + lnet_ni_addref_locked(ni, 0); + lnet_net_unlock(0); + + return ni; +} +EXPORT_SYMBOL(lnet_nid2ni_addref); + int lnet_islocalnid(lnet_nid_t nid) { @@ -812,8 +824,6 @@ lnet_islocalnid(lnet_nid_t nid) cpt = lnet_net_lock_current(); ni = lnet_nid2ni_locked(nid, cpt); - if (ni) - lnet_ni_decref_locked(ni, cpt); lnet_net_unlock(cpt); return !!ni; @@ -1412,6 +1422,7 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) if (rc < 0) goto failed1; + lnet_ni_addref(ni); list_add_tail(&ni->ni_netlist, &local_ni_list); ni_count++; @@ -2032,9 +2043,6 @@ lnet_dyn_del_ni(__u32 net) goto failed; } - /* decrement the reference counter taken by lnet_net2ni() */ - lnet_ni_decref_locked(ni, 0); - lnet_shutdown_lndni(ni); if (!lnet_count_acceptor_nets()) @@ -2264,7 +2272,6 @@ LNetCtl(unsigned int cmd, void *arg) else rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); - lnet_ni_decref(ni); return rc; } /* not reached */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 00a89221c9b3..60f34c4b85d3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1127,11 +1127,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) if (!src_ni) { src_ni = local_ni; src_nid = src_ni->ni_nid; - } else if (src_ni == local_ni) { - lnet_ni_decref_locked(local_ni, cpt); - } else { - lnet_ni_decref_locked(local_ni, cpt); - lnet_ni_decref_locked(src_ni, cpt); + } else if (src_ni != local_ni) { lnet_net_unlock(cpt); LCONSOLE_WARN("No route to %s via from %s\n", libcfs_nid2str(dst_nid), @@ -1149,16 +1145,10 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) /* No send credit hassles with LOLND */ lnet_net_unlock(cpt); lnet_ni_send(src_ni, msg); - - lnet_net_lock(cpt); - lnet_ni_decref_locked(src_ni, cpt); - lnet_net_unlock(cpt); return 0; } rc = lnet_nid2peer_locked(&lp, dst_nid, cpt); - /* lp has ref on src_ni; lose mine */ - lnet_ni_decref_locked(src_ni, cpt); if (rc) { lnet_net_unlock(cpt); LCONSOLE_WARN("Error %d finding peer %s\n", rc, @@ -1173,8 +1163,6 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) src_ni->ni_net : NULL, dst_nid, rtr_nid); if (!lp) { - if (src_ni) - lnet_ni_decref_locked(src_ni, cpt); lnet_net_unlock(cpt); LCONSOLE_WARN("No route to %s via %s (all routers down)\n", @@ -1192,8 +1180,6 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) if (rtr_nid != lp->lp_nid) { cpt2 = lp->lp_cpt; if (cpt2 != cpt) { - if (src_ni) - lnet_ni_decref_locked(src_ni, cpt); lnet_net_unlock(cpt); rtr_nid = lp->lp_nid; @@ -1212,7 +1198,6 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) src_nid = src_ni->ni_nid; } else { LASSERT(src_ni->ni_net == lp->lp_net); - lnet_ni_decref_locked(src_ni, cpt); } lnet_peer_addref_locked(lp); From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 23/34] lnet: don't need lock to test ln_shutdown. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137216.8267.15666994772553520296.stgit@noble> ln_shutdown returns -ESHUTDOWN if ln_shutdown is already set. The lock is always taken to set ln_shutdown, but apparently we don't need to hold the lock for this test. I guess if it is set immediately after the test, and before we take the lock then.... can anything bad happen? This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/lib-move.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 60f34c4b85d3..46e593fbb44f 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1099,12 +1099,9 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid, local_ni); again: - lnet_net_lock(cpt); - - if (the_lnet.ln_shutdown) { - lnet_net_unlock(cpt); + if (the_lnet.ln_shutdown) return -ESHUTDOWN; - } + lnet_net_lock(cpt); if (src_nid == LNET_NID_ANY) { src_ni = NULL; From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 24/34] lnet: don't take lock over lnet_net_unique() In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137220.8267.9479780300443400770.stgit@noble> holding ln_api_mutex is enough to keep the list stable. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 42e775e2a669..2b5c25a1dc7c 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1372,9 +1372,7 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ - lnet_net_lock(LNET_LOCK_EX); rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); - lnet_net_unlock(LNET_LOCK_EX); if (!rc) { if (lnd_type == LOLND) { lnet_net_free(net); From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 25/34] lnet: swap 'then' and 'else' branches in lnet_startup_lndnet In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137225.8267.589541269937133692.stgit@noble> This swap makes the diff for the next patch more readable. We also stop storing the return value from lnet_net_unique() as it is never used. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 55 +++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2b5c25a1dc7c..ab4d093c04da 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1372,8 +1372,34 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ - rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); - if (!rc) { + if (lnet_net_unique(net->net_id, &the_lnet.ln_nets)) { + mutex_lock(&the_lnet.ln_lnd_mutex); + lnd = lnet_find_lnd_by_type(lnd_type); + + if (lnd == NULL) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + rc = request_module("%s", libcfs_lnd2modname(lnd_type)); + mutex_lock(&the_lnet.ln_lnd_mutex); + + lnd = lnet_find_lnd_by_type(lnd_type); + if (lnd == NULL) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + CERROR("Can't load LND %s, module %s, rc=%d\n", + libcfs_lnd2str(lnd_type), + libcfs_lnd2modname(lnd_type), rc); + rc = -EINVAL; + goto failed0; + } + } + + lnet_net_lock(LNET_LOCK_EX); + lnd->lnd_refcount++; + lnet_net_unlock(LNET_LOCK_EX); + + net->net_lnd = lnd; + + mutex_unlock(&the_lnet.ln_lnd_mutex); + } else { if (lnd_type == LOLND) { lnet_net_free(net); return 0; @@ -1385,31 +1411,6 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) goto failed0; } - mutex_lock(&the_lnet.ln_lnd_mutex); - lnd = lnet_find_lnd_by_type(lnd_type); - - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - rc = request_module("%s", libcfs_lnd2modname(lnd_type)); - mutex_lock(&the_lnet.ln_lnd_mutex); - - lnd = lnet_find_lnd_by_type(lnd_type); - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - CERROR("Can't load LND %s, module %s, rc=%d\n", - libcfs_lnd2str(lnd_type), - libcfs_lnd2modname(lnd_type), rc); - rc = -EINVAL; - goto failed0; - } - } - - lnet_net_lock(LNET_LOCK_EX); - lnd->lnd_refcount++; - lnet_net_unlock(LNET_LOCK_EX); - net->net_lnd = lnd; - mutex_unlock(&the_lnet.ln_lnd_mutex); - while (!list_empty(&net->net_ni_added)) { ni = list_entry(net->net_ni_added.next, struct lnet_ni, ni_netlist); From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 26/34] lnet: only valid lnd_type when net_id is unique. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137230.8267.13002746471298616108.stgit@noble> If it isn't unique, we won't add it, so no need to validate. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ab4d093c04da..0dfd3004f735 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1366,13 +1366,14 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) __u32 lnd_type; struct lnet_lnd *lnd; - lnd_type = LNET_NETTYP(net->net_id); - INIT_LIST_HEAD(&local_ni_list); - LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ if (lnet_net_unique(net->net_id, &the_lnet.ln_nets)) { + lnd_type = LNET_NETTYP(net->net_id); + + LASSERT(libcfs_isknown_lnd(lnd_type)); + mutex_lock(&the_lnet.ln_lnd_mutex); lnd = lnet_find_lnd_by_type(lnd_type); From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 27/34] lnet: make it possible to add a new interface to a network In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137234.8267.14872362382875902424.stgit@noble> lnet_startup_lndnet() is enhanced to cope if the net already exists. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 + drivers/staging/lustre/lnet/lnet/api-ni.c | 69 +++++++++++++++----- drivers/staging/lustre/lnet/lnet/config.c | 12 ++- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 6401d9a37b23..905213fc16c7 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -630,7 +630,8 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); int lnet_parse_routes(char *route_str, int *im_a_router); int lnet_parse_networks(struct list_head *nilist, char *networks); -bool lnet_net_unique(__u32 net, struct list_head *nilist); +bool lnet_net_unique(__u32 net_id, struct list_head *nilist, + struct lnet_net **net); int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 0dfd3004f735..042ab0d9e318 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1298,14 +1298,9 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) goto failed0; } - lnet_net_lock(LNET_LOCK_EX); - /* refcount for ln_nis */ - lnet_ni_addref_locked(ni, 0); - list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); - lnet_net_unlock(LNET_LOCK_EX); - ni->ni_state = LNET_NI_STATE_ACTIVE; + /* We keep a reference on the loopback net through the loopback NI */ if (net->net_lnd->lnd_type == LOLND) { lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); @@ -1360,6 +1355,7 @@ static int lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) { struct lnet_ni *ni; + struct lnet_net *net_l = NULL; struct list_head local_ni_list; int rc; int ni_count = 0; @@ -1368,8 +1364,14 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) INIT_LIST_HEAD(&local_ni_list); - /* Make sure this new NI is unique. */ - if (lnet_net_unique(net->net_id, &the_lnet.ln_nets)) { + /* + * make sure that this net is unique. If it isn't then + * we are adding interfaces to an already existing network, and + * 'net' is just a convenient way to pass in the list. + * if it is unique we need to find the LND and load it if + * necessary. + */ + if (lnet_net_unique(net->net_id, &the_lnet.ln_nets, &net_l)) { lnd_type = LNET_NETTYP(net->net_id); LASSERT(libcfs_isknown_lnd(lnd_type)); @@ -1400,23 +1402,41 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) net->net_lnd = lnd; mutex_unlock(&the_lnet.ln_lnd_mutex); - } else { - if (lnd_type == LOLND) { - lnet_net_free(net); - return 0; - } - CERROR("Net %s is not unique\n", - libcfs_net2str(net->net_id)); - rc = -EEXIST; - goto failed0; + net_l = net; } + /* + * net_l: if the network being added is unique then net_l + * will point to that network + * if the network being added is not unique then + * net_l points to the existing network. + * + * When we enter the loop below, we'll pick NIs off he + * network beign added and start them up, then add them to + * a local ni list. Once we've successfully started all + * the NIs then we join the local NI list (of started up + * networks) with the net_l->net_ni_list, which should + * point to the correct network to add the new ni list to + * + * If any of the new NIs fail to start up, then we want to + * iterate through the local ni list, which should include + * any NIs which were successfully started up, and shut + * them down. + * + * After than we want to delete the network being added, + * to avoid a memory leak. + */ + while (!list_empty(&net->net_ni_added)) { ni = list_entry(net->net_ni_added.next, struct lnet_ni, ni_netlist); list_del_init(&ni->ni_netlist); + /* adjust the pointer the parent network, just in case it + * the net is a duplicate */ + ni->ni_net = net_l; + rc = lnet_startup_lndni(ni, tun); if (rc < 0) @@ -1427,9 +1447,22 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) ni_count++; } + lnet_net_lock(LNET_LOCK_EX); - list_splice_tail(&local_ni_list, &net->net_ni_list); + list_splice_tail(&local_ni_list, &net_l->net_ni_list); lnet_net_unlock(LNET_LOCK_EX); + + /* if the network is not unique then we don't want to keep + * it around after we're done. Free it. Otherwise add that + * net to the global the_lnet.ln_nets */ + if (net_l != net && net_l != NULL) { + lnet_net_free(net); + } else { + lnet_net_lock(LNET_LOCK_EX); + list_add_tail(&net->net_list, &the_lnet.ln_nets); + lnet_net_unlock(LNET_LOCK_EX); + } + return ni_count; failed1: diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index f886dcfc6d6e..fcae50676422 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -79,13 +79,17 @@ lnet_issep(char c) } bool -lnet_net_unique(__u32 net, struct list_head *netlist) +lnet_net_unique(__u32 net_id, struct list_head *netlist, + struct lnet_net **net) { - struct lnet_net *net_l; + struct lnet_net *net_l; list_for_each_entry(net_l, netlist, net_list) { - if (net_l->net_id == net) + if (net_l->net_id == net_id) { + if (net != NULL) + *net = net_l; return false; + } } return true; @@ -309,7 +313,7 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) { struct lnet_net *net; - if (!lnet_net_unique(net_id, net_list)) { + if (!lnet_net_unique(net_id, net_list, NULL)) { CERROR("Duplicate net %s. Ignore\n", libcfs_net2str(net_id)); return NULL; From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 28/34] lnet: add checks to ensure network interface names are unique. In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137237.8267.13304938702171788855.stgit@noble> This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + drivers/staging/lustre/lnet/lnet/api-ni.c | 8 ++++++ drivers/staging/lustre/lnet/lnet/config.c | 25 ++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 905213fc16c7..ef551b571935 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -632,6 +632,7 @@ int lnet_parse_routes(char *route_str, int *im_a_router); int lnet_parse_networks(struct list_head *nilist, char *networks); bool lnet_net_unique(__u32 net_id, struct list_head *nilist, struct lnet_net **net); +bool lnet_ni_unique_net(struct list_head *nilist, char *iface); int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 042ab0d9e318..3f6f5ead8a03 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1433,6 +1433,14 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) ni_netlist); list_del_init(&ni->ni_netlist); + /* make sure that the the NI we're about to start + * up is actually unique. if it's not fail. */ + if (!lnet_ni_unique_net(&net_l->net_ni_list, + ni->ni_interfaces[0])) { + rc = -EINVAL; + goto failed1; + } + /* adjust the pointer the parent network, just in case it * the net is a duplicate */ ni->ni_net = net_l; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index fcae50676422..11d6dbc80507 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -95,6 +95,25 @@ lnet_net_unique(__u32 net_id, struct list_head *netlist, return true; } +/* check that the NI is unique within the list of NIs already added to + * a network */ +bool +lnet_ni_unique_net(struct list_head *nilist, char *iface) +{ + struct list_head *tmp; + struct lnet_ni *ni; + + list_for_each(tmp, nilist) { + ni = list_entry(tmp, struct lnet_ni, ni_netlist); + + if (ni->ni_interfaces[0] != NULL && + strncmp(ni->ni_interfaces[0], iface, strlen(iface)) == 0) + return false; + } + + return true; +} + static bool in_array(__u32 *array, __u32 size, __u32 value) { @@ -352,6 +371,12 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) int rc; int i; + if (iface != NULL) + /* make sure that this NI is unique in the net it's + * being added to */ + if (!lnet_ni_unique_net(&net->net_ni_added, iface)) + return NULL; + ni = kzalloc(sizeof(*ni), GFP_KERNEL); if (ni == NULL) { CERROR("Out of memory creating network interface %s%s\n", From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 29/34] lnet: track tunables in lnet_startup_lndnet() In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137241.8267.17639366442733480713.stgit@noble> Not really sure what this is yet. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 3f6f5ead8a03..f4efb48c4cf3 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1361,6 +1361,12 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) int ni_count = 0; __u32 lnd_type; struct lnet_lnd *lnd; + int peer_timeout = + net->net_tunables.lct_peer_timeout; + int maxtxcredits = + net->net_tunables.lct_max_tx_credits; + int peerrtrcredits = + net->net_tunables.lct_peer_rtr_credits; INIT_LIST_HEAD(&local_ni_list); @@ -1447,6 +1453,9 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) rc = lnet_startup_lndni(ni, tun); + LASSERT(ni->ni_net->net_tunables.lct_peer_timeout <= 0 || + ni->ni_net->net_lnd->lnd_query != NULL); + if (rc < 0) goto failed1; @@ -1464,8 +1473,23 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) * it around after we're done. Free it. Otherwise add that * net to the global the_lnet.ln_nets */ if (net_l != net && net_l != NULL) { + /* + * TODO - note. currently the tunables can not be updated + * once added + */ lnet_net_free(net); } else { + /* + * restore tunables after it has been overwitten by the + * lnd + */ + if (peer_timeout != -1) + net->net_tunables.lct_peer_timeout = peer_timeout; + if (maxtxcredits != -1) + net->net_tunables.lct_max_tx_credits = maxtxcredits; + if (peerrtrcredits != -1) + net->net_tunables.lct_peer_rtr_credits = peerrtrcredits; + lnet_net_lock(LNET_LOCK_EX); list_add_tail(&net->net_list, &the_lnet.ln_nets); lnet_net_unlock(LNET_LOCK_EX); From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 30/34] lnet: fix typo In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137245.8267.15918400233109764157.stgit@noble> to -> too This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index f4efb48c4cf3..cf0ffb8ac84b 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1868,7 +1868,7 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) if (config->cfg_hdr.ioc_len > min_size) tunable_size = config->cfg_hdr.ioc_len - min_size; - /* Don't copy to much data to user space */ + /* Don't copy too much data to user space */ min_size = min(tunable_size, sizeof(ni->ni_lnd_tunables)); lnd_cfg = (struct lnet_ioctl_config_lnd_tunables *)net_config->cfg_bulk; From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 31/34] lnet: lnet_dyn_add_ni: fix ping_info count In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137248.8267.6726065772840936203.stgit@noble> Use the correct count of interfaces when calling lnet_ping_info_setup() in lnet_dyn_add_ni() Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index cf0ffb8ac84b..2ce0a7212dc2 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -871,6 +871,18 @@ lnet_ping_info_create(int num_ni) return ping_info; } +static inline int +lnet_get_net_ni_count_locked(struct lnet_net *net) +{ + struct lnet_ni *ni; + int count = 0; + + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) + count++; + + return count; +} + static inline int lnet_get_ni_count(void) { @@ -1977,6 +1989,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) struct list_head net_head; struct lnet_remotenet *rnet; int rc; + int net_ni_count; int num_acceptor_nets; __u32 net_type; struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; @@ -2014,7 +2027,19 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) goto failed0; } - rc = lnet_ping_info_setup(&pinfo, &md_handle, 1 + lnet_get_ni_count(), + /* + * make sure you calculate the correct number of slots in the ping + * info. Since the ping info is a flattened list of all the NIs, + * we should allocate enough slots to accomodate the number of NIs + * which will be added. + * + * We can use lnet_get_net_ni_count_locked() since the net is not + * on a public list yet, so locking is not a problem + */ + net_ni_count = lnet_get_net_ni_count_locked(net); + + rc = lnet_ping_info_setup(&pinfo, &md_handle, + net_ni_count + lnet_get_ni_count(), false); if (rc) goto failed0; From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 32/34] lnet: lnet_dyn_del_ni: fix ping_info count In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137252.8267.5413803631901452139.stgit@noble> - use correct interface count for lnet_ping_info_setup(). - also rename 'net' to 'net_id' so the name 'net' is free to identify the lnet_net. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 35 +++++++++++++++++------------ 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2ce0a7212dc2..ff5149da2d79 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -2109,40 +2109,45 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) } int -lnet_dyn_del_ni(__u32 net) +lnet_dyn_del_ni(__u32 net_id) { - struct lnet_ni *ni; + struct lnet_net *net; struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; int rc; + int net_ni_count; /* don't allow userspace to shutdown the LOLND */ - if (LNET_NETTYP(net) == LOLND) + if (LNET_NETTYP(net_id) == LOLND) return -EINVAL; mutex_lock(&the_lnet.ln_api_mutex); + + lnet_net_lock(0); + + net = lnet_get_net_locked(net_id); + if (net == NULL) { + rc = -EINVAL; + goto out; + } + + net_ni_count = lnet_get_net_ni_count_locked(net); + + lnet_net_unlock(0); + /* create and link a new ping info, before removing the old one */ rc = lnet_ping_info_setup(&pinfo, &md_handle, - lnet_get_ni_count() - 1, false); + lnet_get_ni_count() - net_ni_count, false); if (rc) goto out; - ni = lnet_net2ni(net); - if (!ni) { - rc = -EINVAL; - goto failed; - } - - lnet_shutdown_lndni(ni); + lnet_shutdown_lndnet(net); if (!lnet_count_acceptor_nets()) lnet_acceptor_stop(); lnet_ping_target_update(pinfo, md_handle); - goto out; -failed: - lnet_ping_md_unlink(pinfo, &md_handle); - lnet_ping_info_free(pinfo); + out: mutex_unlock(&the_lnet.ln_api_mutex); From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 33/34] Completely re-write lnet_parse_networks(). In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137255.8267.7924367116215461900.stgit@noble> From: Amir Shehata Was: LU-7734 lnet: Multi-Rail local NI split This patch allows the configuration of multiple NIs under one Net. It is now possible to have multiple NIDs on the same network: Ex: @tcp, @tcp. This can be configured using the following syntax: Ex: tcp(eth0, eth1) The data structures for the example above can be visualized as follows NET(tcp) | ----------------- | | NI(eth0) NI(eth1) For more details refer to the Mult-Rail Requirements and HLD documents Signed-off-by: Amir Shehata Change-Id: Id7c73b9b811a3082b61e53b9e9f95743188cbd51 Reviewed-on: http://review.whamcloud.com/18274 Tested-by: Jenkins Reviewed-by: Doug Oucharek Tested-by: Maloo Reviewed-by: Olaf Weber --- drivers/staging/lustre/lnet/lnet/config.c | 341 ++++++++++++++++++----------- 1 file changed, 217 insertions(+), 124 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 11d6dbc80507..0571fa6a7249 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -48,8 +48,11 @@ static int lnet_tbnob; /* track text buf allocation */ #define LNET_MAX_TEXTBUF_NOB (64 << 10) /* bound allocation */ #define LNET_SINGLE_TEXTBUF_NOB (4 << 10) +#define SPACESTR " \t\v\r\n" +#define DELIMITERS ":()[]" + static void -lnet_syntax(char *name, char *str, int offset, int width) +lnet_syntax(const char *name, const char *str, int offset, int width) { static char dots[LNET_SINGLE_TEXTBUF_NOB]; static char dashes[LNET_SINGLE_TEXTBUF_NOB]; @@ -363,6 +366,42 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) return net; } +static int +lnet_ni_add_interface(struct lnet_ni *ni, char *iface) +{ + int niface = 0; + + if (ni == NULL) + return -ENOMEM; + + /* Allocate a separate piece of memory and copy + * into it the string, so we don't have + * a depencency on the tokens string. This way we + * can free the tokens at the end of the function. + * The newly allocated ni_interfaces[] can be + * freed when freeing the NI */ + while (niface < LNET_MAX_INTERFACES && + ni->ni_interfaces[niface] != NULL) + niface++; + + if (niface >= LNET_MAX_INTERFACES) { + LCONSOLE_ERROR_MSG(0x115, "Too many interfaces " + "for net %s\n", + libcfs_net2str(LNET_NIDNET(ni->ni_nid))); + return -EINVAL; + } + + ni->ni_interfaces[niface] = kstrdup(iface, GFP_KERNEL); + + if (ni->ni_interfaces[niface] == NULL) { + CERROR("Can't allocate net interface name\n"); + return -ENOMEM; + } + + return 0; +} + +/* allocate and add to the provided network */ struct lnet_ni * lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) { @@ -439,24 +478,33 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) goto failed; list_add_tail(&ni->ni_netlist, &net->net_ni_added); + /* if an interface name is provided then make sure to add in that + * interface name in NI */ + if (iface != NULL) + if (lnet_ni_add_interface(ni, iface) != 0) + goto failed; + return ni; failed: lnet_ni_free(ni); return NULL; } +/* + * Parse the networks string and create the matching set of NIs on the + * nilist. + */ int lnet_parse_networks(struct list_head *netlist, char *networks) { - struct cfs_expr_list *el = NULL; + struct cfs_expr_list *net_el = NULL; + struct cfs_expr_list *ni_el = NULL; char *tokens; char *str; - char *tmp; struct lnet_net *net; struct lnet_ni *ni = NULL; __u32 net_id; int nnets = 0; - struct list_head *temp_node; if (!networks) { CERROR("networks string is undefined\n"); @@ -476,84 +524,108 @@ lnet_parse_networks(struct list_head *netlist, char *networks) return -ENOMEM; } - tmp = tokens; str = tokens; - while (str && *str) { - char *comma = strchr(str, ','); - char *bracket = strchr(str, '('); - char *square = strchr(str, '['); - char *iface; - int niface; + /* + * Main parser loop. + * + * NB we don't check interface conflicts here; it's the LNDs + * responsibility (if it cares at all) + */ + do { + char *nistr; + char *elstr; + char *name; int rc; /* - * NB we don't check interface conflicts here; it's the LNDs - * responsibility (if it cares at all) + * Parse a network string into its components. + * + * {"("...")"}{"[""]"} */ - if (square && (!comma || square < comma)) { - /* - * i.e: o2ib0(ib0)[1,2], number between square - * brackets are CPTs this NI needs to be bond - */ - if (bracket && bracket > square) { - tmp = square; + + /* Network name (mandatory) + */ + while (isspace(*str)) + *str++ = '\0'; + if (!*str) + break; + name = str; + str += strcspn(str, SPACESTR ":()[],"); + while (isspace(*str)) + *str++ = '\0'; + + /* Interface list (optional) */ + if (*str == '(') { + *str++ = '\0'; + nistr = str; + str += strcspn(str, ")"); + if (*str != ')') { + str = nistr; goto failed_syntax; } + do { + *str++ = '\0'; + } while (isspace(*str)); + } else { + nistr = NULL; + } - tmp = strchr(square, ']'); - if (!tmp) { - tmp = square; + /* CPT expression (optional) */ + if (*str == '[') { + elstr = str; + str += strcspn(str, "]"); + if (*str != ']') { + str = elstr; goto failed_syntax; } - - rc = cfs_expr_list_parse(square, tmp - square + 1, - 0, LNET_CPT_NUMBER - 1, &el); + rc = cfs_expr_list_parse(elstr, str - elstr + 1, + 0, LNET_CPT_NUMBER - 1, + &net_el); if (rc) { - tmp = square; + str = elstr; goto failed_syntax; } - - while (square <= tmp) - *square++ = ' '; + *elstr = '\0'; + do { + *str++ = '\0'; + } while (isspace(*str)); } - if (!bracket || (comma && comma < bracket)) { - /* no interface list specified */ + /* Bad delimiters */ + if (*str && (strchr(DELIMITERS, *str) != NULL)) + goto failed_syntax; - if (comma) - *comma++ = 0; - net_id = libcfs_str2net(strim(str)); + /* go to the next net if it exits */ + str += strcspn(str, ","); + if (*str == ',') + *str++ = '\0'; - if (net_id == LNET_NIDNET(LNET_NID_ANY)) { - LCONSOLE_ERROR_MSG(0x113, - "Unrecognised network type\n"); - tmp = str; - goto failed_syntax; - } - - if (LNET_NETTYP(net_id) != LOLND) { /* LO is implicit */ - net = lnet_net_alloc(net_id, netlist); - if (!net || - !lnet_ni_alloc(net, el, NULL)) - goto failed; - } + /* + * At this point the name is properly terminated. + */ + net_id = libcfs_str2net(name); + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { + LCONSOLE_ERROR_MSG(0x113, + "Unrecognised network type\n"); + str = name; + goto failed_syntax; + } - if (el) { - cfs_expr_list_free(el); - el = NULL; + if (LNET_NETTYP(net_id) == LOLND) { + /* Loopback is implicit, and there can be only one. */ + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; } - - str = comma; + /* Should we error out instead? */ continue; } - *bracket = 0; - net_id = libcfs_str2net(strim(str)); - if (net_id == LNET_NIDNET(LNET_NID_ANY)) { - tmp = str; - goto failed_syntax; - } + /* + * All network paramaters are now known. + */ + nnets++; /* always allocate a net, since we will eventually add an * interface to it, or we will fail, in which case we'll @@ -562,88 +634,107 @@ lnet_parse_networks(struct list_head *netlist, char *networks) if (IS_ERR_OR_NULL(net)) goto failed; - ni = lnet_ni_alloc(net, el, NULL); - if (IS_ERR_OR_NULL(ni)) - goto failed; - - if (el) { - cfs_expr_list_free(el); - el = NULL; - } - - niface = 0; - iface = bracket + 1; + if (!nistr) { + /* + * No interface list was specified, allocate a + * ni using the defaults. + */ + ni = lnet_ni_alloc(net, net_el, NULL); + if (IS_ERR_OR_NULL(ni)) + goto failed; - bracket = strchr(iface, ')'); - if (!bracket) { - tmp = iface; - goto failed_syntax; + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; + } + continue; } - *bracket = 0; do { - comma = strchr(iface, ','); - if (comma) - *comma++ = 0; - - iface = strim(iface); - if (!*iface) { - tmp = iface; - goto failed_syntax; + elstr = NULL; + + /* Interface name (mandatory) */ + while (isspace(*nistr)) + *nistr++ = '\0'; + name = nistr; + nistr += strcspn(nistr, SPACESTR "[],"); + while (isspace(*nistr)) + *nistr++ = '\0'; + + /* CPT expression (optional) */ + if (*nistr == '[') { + elstr = nistr; + nistr += strcspn(nistr, "]"); + if (*nistr != ']') { + str = elstr; + goto failed_syntax; + } + rc = cfs_expr_list_parse(elstr, + nistr - elstr + 1, + 0, LNET_CPT_NUMBER - 1, + &ni_el); + if (rc != 0) { + str = elstr; + goto failed_syntax; + } + *elstr = '\0'; + do { + *nistr++ = '\0'; + } while (isspace(*nistr)); + } else { + ni_el = net_el; } - if (niface == LNET_MAX_INTERFACES) { - LCONSOLE_ERROR_MSG(0x115, - "Too many interfaces for net %s\n", - libcfs_net2str(net_id)); - goto failed; + /* + * End of single interface specificaton, + * advance to the start of the next one, if + * any. + */ + if (*nistr == ',') { + do { + *nistr++ = '\0'; + } while (isspace(*nistr)); + if (!*nistr) { + str = nistr; + goto failed_syntax; + } + } else if (*nistr) { + str = nistr; + goto failed_syntax; } /* - * Allocate a separate piece of memory and copy - * into it the string, so we don't have - * a depencency on the tokens string. This way we - * can free the tokens at the end of the function. - * The newly allocated ni_interfaces[] can be - * freed when freeing the NI + * At this point the name + is properly terminated. */ - ni->ni_interfaces[niface] = kstrdup(iface, GFP_KERNEL); - if (!ni->ni_interfaces[niface]) { - CERROR("Can't allocate net interface name\n"); - goto failed; - } - niface++; - iface = comma; - } while (iface); - - str = bracket + 1; - comma = strchr(bracket + 1, ','); - if (comma) { - *comma = 0; - str = strim(str); - if (*str) { - tmp = str; + if (!*name) { + str = name; goto failed_syntax; } - str = comma + 1; - continue; - } - str = strim(str); - if (*str) { - tmp = str; - goto failed_syntax; - } - } + ni = lnet_ni_alloc(net, ni_el, name); + if (IS_ERR_OR_NULL(ni)) + goto failed; - list_for_each(temp_node, netlist) - nnets++; + if (ni_el) { + if (ni_el != net_el) { + cfs_expr_list_free(ni_el); + ni_el = NULL; + } + } + } while (*nistr); + + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; + } + } while (*str); kfree(tokens); return nnets; failed_syntax: - lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp)); + lnet_syntax("networks", networks, (int)(str - tokens), strlen(str)); failed: /* free the net list and all the nis on each net */ while (!list_empty(netlist)) { @@ -653,8 +744,10 @@ lnet_parse_networks(struct list_head *netlist, char *networks) lnet_net_free(net); } - if (el) - cfs_expr_list_free(el); + if (ni_el && ni_el != net_el) + cfs_expr_list_free(ni_el); + if (net_el) + cfs_expr_list_free(net_el); kfree(tokens); From neilb at suse.com Fri Sep 7 00:49:32 2018 From: neilb at suse.com (NeilBrown) Date: Fri, 07 Sep 2018 10:49:32 +1000 Subject: [lustre-devel] [PATCH 34/34] lnet: introduce use_tcp_bonding mod param In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <153628137259.8267.2306617574801795911.stgit@noble> This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 + drivers/staging/lustre/lnet/lnet/api-ni.c | 22 ++++++++- drivers/staging/lustre/lnet/lnet/config.c | 50 ++++++++++++++++---- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index ef551b571935..5ee770cd7a5f 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -629,7 +629,8 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); int lnet_parse_routes(char *route_str, int *im_a_router); -int lnet_parse_networks(struct list_head *nilist, char *networks); +int lnet_parse_networks(struct list_head *nilist, char *networks, + bool use_tcp_bonding); bool lnet_net_unique(__u32 net_id, struct list_head *nilist, struct lnet_net **net); bool lnet_ni_unique_net(struct list_head *nilist, char *iface); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ff5149da2d79..8ff386992c99 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -59,6 +59,11 @@ static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT; module_param(rnet_htable_size, int, 0444); MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table"); +static int use_tcp_bonding = false; +module_param(use_tcp_bonding, int, 0444); +MODULE_PARM_DESC(use_tcp_bonding, + "Set to 1 to use socklnd bonding. 0 to use Multi-Rail"); + static int lnet_ping(struct lnet_process_id id, signed long timeout, struct lnet_process_id __user *ids, int n_ids); @@ -1446,6 +1451,18 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) * to avoid a memory leak. */ + /* + * When a network uses TCP bonding then all its interfaces + * must be specified when the network is first defined: the + * TCP bonding code doesn't allow for interfaces to be added + * or removed. + */ + if (net_l != net && net_l != NULL && use_tcp_bonding && + LNET_NETTYP(net_l->net_id) == SOCKLND) { + rc = -EINVAL; + goto failed0; + } + while (!list_empty(&net->net_ni_added)) { ni = list_entry(net->net_ni_added.next, struct lnet_ni, ni_netlist); @@ -1702,7 +1719,8 @@ LNetNIInit(lnet_pid_t requested_pid) * routes if it has been loaded */ if (!the_lnet.ln_nis_from_mod_params) { - rc = lnet_parse_networks(&net_head, lnet_get_networks()); + rc = lnet_parse_networks(&net_head, lnet_get_networks(), + use_tcp_bonding); if (rc < 0) goto err_empty_list; } @@ -2000,7 +2018,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; /* Create a net/ni structures for the network string */ - rc = lnet_parse_networks(&net_head, nets); + rc = lnet_parse_networks(&net_head, nets, use_tcp_bonding); if (rc <= 0) return !rc ? -EINVAL : rc; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 0571fa6a7249..abfc5d8dc219 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -117,6 +117,21 @@ lnet_ni_unique_net(struct list_head *nilist, char *iface) return true; } +/* check that the NI is unique to the interfaces with in the same NI. + * This is only a consideration if use_tcp_bonding is set */ +static bool +lnet_ni_unique_ni(char *iface_list[LNET_MAX_INTERFACES], char *iface) +{ + int i; + for (i = 0; i < LNET_MAX_INTERFACES; i++) { + if (iface_list[i] != NULL && + strncmp(iface_list[i], iface, strlen(iface)) == 0) + return false; + } + + return true; +} + static bool in_array(__u32 *array, __u32 size, __u32 value) { @@ -374,6 +389,9 @@ lnet_ni_add_interface(struct lnet_ni *ni, char *iface) if (ni == NULL) return -ENOMEM; + if (!lnet_ni_unique_ni(ni->ni_interfaces, iface)) + return -EINVAL; + /* Allocate a separate piece of memory and copy * into it the string, so we don't have * a depencency on the tokens string. This way we @@ -495,7 +513,8 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) * nilist. */ int -lnet_parse_networks(struct list_head *netlist, char *networks) +lnet_parse_networks(struct list_head *netlist, char *networks, + bool use_tcp_bonding) { struct cfs_expr_list *net_el = NULL; struct cfs_expr_list *ni_el = NULL; @@ -634,7 +653,8 @@ lnet_parse_networks(struct list_head *netlist, char *networks) if (IS_ERR_OR_NULL(net)) goto failed; - if (!nistr) { + if (!nistr || + (use_tcp_bonding && LNET_NETTYP(net_id) == SOCKLND)) { /* * No interface list was specified, allocate a * ni using the defaults. @@ -643,11 +663,13 @@ lnet_parse_networks(struct list_head *netlist, char *networks) if (IS_ERR_OR_NULL(ni)) goto failed; - if (net_el) { - cfs_expr_list_free(net_el); - net_el = NULL; + if (!nistr) { + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; + } + continue; } - continue; } do { @@ -704,17 +726,23 @@ lnet_parse_networks(struct list_head *netlist, char *networks) } /* - * At this point the name - is properly terminated. + * At this point the name is properly terminated. */ if (!*name) { str = name; goto failed_syntax; } - ni = lnet_ni_alloc(net, ni_el, name); - if (IS_ERR_OR_NULL(ni)) - goto failed; + if (use_tcp_bonding && + LNET_NETTYP(net->net_id) == SOCKLND) { + rc = lnet_ni_add_interface(ni, name); + if (rc != 0) + goto failed; + } else { + ni = lnet_ni_alloc(net, ni_el, name); + if (IS_ERR_OR_NULL(ni)) + goto failed; + } if (ni_el) { if (ni_el != net_el) { From doucharek at cray.com Mon Sep 10 22:49:30 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 22:49:30 +0000 Subject: [lustre-devel] [PATCH 01/34] struct lnet_ni - reformat comments. In-Reply-To: <153628137125.8267.7825080417267355121.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137125.8267.7825080417267355121.stgit@noble> Message-ID: Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split --- .../staging/lustre/include/linux/lnet/lib-types.h | 38 +++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 6d4106fd9039..078bc97a9ebf 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -263,18 +263,38 @@ struct lnet_ni { int ni_peerrtrcredits; /* seconds to consider peer dead */ int ni_peertimeout; - int ni_ncpts; /* number of CPTs */ - __u32 *ni_cpts; /* bond NI on some CPTs */ - lnet_nid_t ni_nid; /* interface's NID */ - void *ni_data; /* instance-specific data */ + /* number of CPTs */ + int ni_ncpts; + + /* bond NI on some CPTs */ + __u32 *ni_cpts; + + /* interface's NID */ + lnet_nid_t ni_nid; + + /* instance-specific data */ + void *ni_data; + struct lnet_lnd *ni_lnd; /* procedural interface */ - struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */ - int **ni_refs; /* percpt reference count */ - time64_t ni_last_alive;/* when I was last alive */ - struct lnet_ni_status *ni_status; /* my health status */ + + /* percpt TX queues */ + struct lnet_tx_queue **ni_tx_queues; + + /* percpt reference count */ + int **ni_refs; + + /* when I was last alive */ + time64_t ni_last_alive; + + /* my health status */ + struct lnet_ni_status *ni_status; + /* per NI LND tunables */ struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables; - /* equivalent interfaces to use */ + /* + * equivalent interfaces to use + * This is an array because socklnd bonding can still be configured + */ char *ni_interfaces[LNET_MAX_INTERFACES]; /* original net namespace */ struct net *ni_net_ns; -------------- next part -------------- An HTML attachment was scrubbed... URL: From doucharek at cray.com Mon Sep 10 22:56:13 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 22:56:13 +0000 Subject: [lustre-devel] [PATCH 02/34] lnet: Create struct lnet_net In-Reply-To: <153628137129.8267.345070695068208597.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137129.8267.345070695068208597.stgit@noble> Message-ID: Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: This will contain some fields from lnet_ni, to be shared between multiple ni on the one network. For now, only tunables are moved across, using struct lnet_ioctl_config_lnd_cmn_tunables which is changed to use signed values so -1 can be stored. -1 means "no value" If the tunables haven't been initialised, then net_tunables_set is false. Previously a NULL pointer had this meaning. A 'struct lnet_net' is allocated as part of lnet_ni_alloc(), and freed by lnet_ni_free(). This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown > --- .../staging/lustre/include/linux/lnet/lib-types.h | 25 ++++++-- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 8 +-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 - .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 61 +++++++++++--------- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 19 ++++-- drivers/staging/lustre/lnet/lnet/api-ni.c | 45 +++++++++------ drivers/staging/lustre/lnet/lnet/config.c | 24 ++++++-- drivers/staging/lustre/lnet/lnet/lib-move.c | 5 +- drivers/staging/lustre/lnet/lnet/peer.c | 9 ++- drivers/staging/lustre/lnet/lnet/router.c | 8 ++- drivers/staging/lustre/lnet/lnet/router_proc.c | 6 +- 11 files changed, 129 insertions(+), 83 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 078bc97a9ebf..ead8a4e1125a 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -43,6 +43,7 @@ #include #include +#include /* Max payload size */ #define LNET_MAX_PAYLOAD CONFIG_LNET_MAX_PAYLOAD @@ -252,17 +253,22 @@ struct lnet_tx_queue { struct list_head tq_delayed; /* delayed TXs */ }; +struct lnet_net { + /* network tunables */ + struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; + + /* + * boolean to indicate that the tunables have been set and + * shouldn't be reset + */ + bool net_tunables_set; +}; + struct lnet_ni { spinlock_t ni_lock; struct list_head ni_list; /* chain on ln_nis */ struct list_head ni_cptlist; /* chain on ln_nis_cpt */ - int ni_maxtxcredits; /* # tx credits */ - /* # per-peer send credits */ - int ni_peertxcredits; - /* # per-peer router buffer credits */ - int ni_peerrtrcredits; - /* seconds to consider peer dead */ - int ni_peertimeout; + /* number of CPTs */ int ni_ncpts; @@ -286,6 +292,9 @@ struct lnet_ni { /* when I was last alive */ time64_t ni_last_alive; + /* pointer to parent network */ + struct lnet_net *ni_net; + /* my health status */ struct lnet_ni_status *ni_status; @@ -397,7 +406,7 @@ struct lnet_peer_table { * lnet_ni::ni_peertimeout has been set to a positive value */ #define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing && \ - (lp)->lp_ni->ni_peertimeout > 0) + (lp)->lp_ni->ni_net->net_tunables.lct_peer_timeout > 0) struct lnet_route { struct list_head lr_list; /* chain on net */ diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index c1619f411d81..a8eb3b8f9fd7 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -39,10 +39,10 @@ struct lnet_ioctl_config_lnd_cmn_tunables { __u32 lct_version; - __u32 lct_peer_timeout; - __u32 lct_peer_tx_credits; - __u32 lct_peer_rtr_credits; - __u32 lct_max_tx_credits; + __s32 lct_peer_timeout; + __s32 lct_peer_tx_credits; + __s32 lct_peer_rtr_credits; + __s32 lct_max_tx_credits; }; struct lnet_ioctl_config_o2iblnd_tunables { diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index f496e6fcc416..0d17e22c4401 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -337,7 +337,7 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, peer->ibp_error = 0; peer->ibp_last_alive = 0; peer->ibp_max_frags = kiblnd_cfg_rdma_frags(peer->ibp_ni); - peer->ibp_queue_depth = ni->ni_peertxcredits; + peer->ibp_queue_depth = ni->ni_net->net_tunables.lct_peer_tx_credits; atomic_set(&peer->ibp_refcount, 1); /* 1 ref for caller */ INIT_LIST_HEAD(&peer->ibp_list); /* not in the peer table yet */ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index 39d07926d603..a1aca4dda38f 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -171,7 +171,7 @@ int kiblnd_msg_queue_size(int version, struct lnet_ni *ni) if (version == IBLND_MSG_VERSION_1) return IBLND_MSG_QUEUE_SIZE_V1; else if (ni) - return ni->ni_peertxcredits; + return ni->ni_net->net_tunables.lct_peer_tx_credits; else return peer_credits; } @@ -179,6 +179,7 @@ int kiblnd_msg_queue_size(int version, struct lnet_ni *ni) int kiblnd_tunables_setup(struct lnet_ni *ni) { struct lnet_ioctl_config_o2iblnd_tunables *tunables; + struct lnet_ioctl_config_lnd_cmn_tunables *net_tunables; /* * if there was no tunables specified, setup the tunables to be @@ -204,35 +205,39 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) return -EINVAL; } - if (!ni->ni_peertimeout) - ni->ni_peertimeout = peer_timeout; + net_tunables = &ni->ni_net->net_tunables; - if (!ni->ni_maxtxcredits) - ni->ni_maxtxcredits = credits; + if (net_tunables->lct_peer_timeout == -1) + net_tunables->lct_peer_timeout = peer_timeout; - if (!ni->ni_peertxcredits) - ni->ni_peertxcredits = peer_credits; + if (net_tunables->lct_max_tx_credits == -1) + net_tunables->lct_max_tx_credits = credits; - if (!ni->ni_peerrtrcredits) - ni->ni_peerrtrcredits = peer_buffer_credits; + if (net_tunables->lct_peer_tx_credits == -1) + net_tunables->lct_peer_tx_credits = peer_credits; - if (ni->ni_peertxcredits < IBLND_CREDITS_DEFAULT) - ni->ni_peertxcredits = IBLND_CREDITS_DEFAULT; + if (net_tunables->lct_peer_rtr_credits == -1) + net_tunables->lct_peer_rtr_credits = peer_buffer_credits; - if (ni->ni_peertxcredits > IBLND_CREDITS_MAX) - ni->ni_peertxcredits = IBLND_CREDITS_MAX; + if (net_tunables->lct_peer_tx_credits < IBLND_CREDITS_DEFAULT) + net_tunables->lct_peer_tx_credits = IBLND_CREDITS_DEFAULT; - if (ni->ni_peertxcredits > credits) - ni->ni_peertxcredits = credits; + if (net_tunables->lct_peer_tx_credits > IBLND_CREDITS_MAX) + net_tunables->lct_peer_tx_credits = IBLND_CREDITS_MAX; + + if (net_tunables->lct_peer_tx_credits > + net_tunables->lct_max_tx_credits) + net_tunables->lct_peer_tx_credits = + net_tunables->lct_max_tx_credits; if (!tunables->lnd_peercredits_hiw) tunables->lnd_peercredits_hiw = peer_credits_hiw; - if (tunables->lnd_peercredits_hiw < ni->ni_peertxcredits / 2) - tunables->lnd_peercredits_hiw = ni->ni_peertxcredits / 2; + if (tunables->lnd_peercredits_hiw < net_tunables->lct_peer_tx_credits / 2) + tunables->lnd_peercredits_hiw = net_tunables->lct_peer_tx_credits / 2; - if (tunables->lnd_peercredits_hiw >= ni->ni_peertxcredits) - tunables->lnd_peercredits_hiw = ni->ni_peertxcredits - 1; + if (tunables->lnd_peercredits_hiw >= net_tunables->lct_peer_tx_credits) + tunables->lnd_peercredits_hiw = net_tunables->lct_peer_tx_credits - 1; if (tunables->lnd_map_on_demand <= 0 || tunables->lnd_map_on_demand > IBLND_MAX_RDMA_FRAGS) { @@ -252,21 +257,23 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) if (tunables->lnd_map_on_demand > 0 && tunables->lnd_map_on_demand <= IBLND_MAX_RDMA_FRAGS / 8) { tunables->lnd_concurrent_sends = - ni->ni_peertxcredits * 2; + net_tunables->lct_peer_tx_credits * 2; } else { - tunables->lnd_concurrent_sends = ni->ni_peertxcredits; + tunables->lnd_concurrent_sends = + net_tunables->lct_peer_tx_credits; } } - if (tunables->lnd_concurrent_sends > ni->ni_peertxcredits * 2) - tunables->lnd_concurrent_sends = ni->ni_peertxcredits * 2; + if (tunables->lnd_concurrent_sends > net_tunables->lct_peer_tx_credits * 2) + tunables->lnd_concurrent_sends = net_tunables->lct_peer_tx_credits * 2; - if (tunables->lnd_concurrent_sends < ni->ni_peertxcredits / 2) - tunables->lnd_concurrent_sends = ni->ni_peertxcredits / 2; + if (tunables->lnd_concurrent_sends < net_tunables->lct_peer_tx_credits / 2) + tunables->lnd_concurrent_sends = net_tunables->lct_peer_tx_credits / 2; - if (tunables->lnd_concurrent_sends < ni->ni_peertxcredits) { + if (tunables->lnd_concurrent_sends < net_tunables->lct_peer_tx_credits) { CWARN("Concurrent sends %d is lower than message queue size: %d, performance may drop slightly.\n", - tunables->lnd_concurrent_sends, ni->ni_peertxcredits); + tunables->lnd_concurrent_sends, + net_tunables->lct_peer_tx_credits); } if (!tunables->lnd_fmr_pool_size) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 4dde158451ea..4ad885f10235 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2739,12 +2739,19 @@ ksocknal_startup(struct lnet_ni *ni) goto fail_0; spin_lock_init(&net->ksnn_lock); - net->ksnn_incarnation = ktime_get_real_ns(); - ni->ni_data = net; - ni->ni_peertimeout = *ksocknal_tunables.ksnd_peertimeout; - ni->ni_maxtxcredits = *ksocknal_tunables.ksnd_credits; - ni->ni_peertxcredits = *ksocknal_tunables.ksnd_peertxcredits; - ni->ni_peerrtrcredits = *ksocknal_tunables.ksnd_peerrtrcredits; + net->ksnn_incarnation = ktime_get_real_ns(); + ni->ni_data = net; + if (!ni->ni_net->net_tunables_set) { + ni->ni_net->net_tunables.lct_peer_timeout = + *ksocknal_tunables.ksnd_peertimeout; + ni->ni_net->net_tunables.lct_max_tx_credits = + *ksocknal_tunables.ksnd_credits; + ni->ni_net->net_tunables.lct_peer_tx_credits = + *ksocknal_tunables.ksnd_peertxcredits; + ni->ni_net->net_tunables.lct_peer_rtr_credits = + *ksocknal_tunables.ksnd_peerrtrcredits; + ni->ni_net->net_tunables_set = true; + } net->ksnn_ninterfaces = 0; if (!ni->ni_interfaces[0]) { diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index f9fcce2a5643..cd4189fa7acb 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1036,11 +1036,11 @@ lnet_ni_tq_credits(struct lnet_ni *ni) LASSERT(ni->ni_ncpts >= 1); if (ni->ni_ncpts == 1) - return ni->ni_maxtxcredits; + return ni->ni_net->net_tunables.lct_max_tx_credits; - credits = ni->ni_maxtxcredits / ni->ni_ncpts; - credits = max(credits, 8 * ni->ni_peertxcredits); - credits = min(credits, ni->ni_maxtxcredits); + credits = ni->ni_net->net_tunables.lct_max_tx_credits / ni->ni_ncpts; + credits = max(credits, 8 * ni->ni_net->net_tunables.lct_peer_tx_credits); + credits = min(credits, ni->ni_net->net_tunables.lct_max_tx_credits); return credits; } @@ -1271,16 +1271,16 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) */ if (conf) { if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) - ni->ni_peerrtrcredits = + ni->ni_net->net_tunables.lct_peer_rtr_credits = conf->cfg_config_u.cfg_net.net_peer_rtr_credits; if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) - ni->ni_peertimeout = + ni->ni_net->net_tunables.lct_peer_timeout = conf->cfg_config_u.cfg_net.net_peer_timeout; if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) - ni->ni_peertxcredits = + ni->ni_net->net_tunables.lct_peer_tx_credits = conf->cfg_config_u.cfg_net.net_peer_tx_credits; if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) - ni->ni_maxtxcredits = + ni->ni_net->net_tunables.lct_max_tx_credits = conf->cfg_config_u.cfg_net.net_max_tx_credits; } @@ -1297,8 +1297,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) goto failed0; } - LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query); - lnet_net_lock(LNET_LOCK_EX); /* refcount for ln_nis */ lnet_ni_addref_locked(ni, 0); @@ -1314,13 +1312,18 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); the_lnet.ln_loni = ni; + ni->ni_net->net_tunables.lct_peer_tx_credits = 0; + ni->ni_net->net_tunables.lct_peer_rtr_credits = 0; + ni->ni_net->net_tunables.lct_max_tx_credits = 0; + ni->ni_net->net_tunables.lct_peer_timeout = 0; return 0; } - if (!ni->ni_peertxcredits || !ni->ni_maxtxcredits) { + if (!ni->ni_net->net_tunables.lct_peer_tx_credits || + !ni->ni_net->net_tunables.lct_max_tx_credits) { LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n", libcfs_lnd2str(lnd->lnd_type), - !ni->ni_peertxcredits ? + !ni->ni_net->net_tunables.lct_peer_tx_credits ? "" : "per-peer "); /* * shutdown the NI since if we get here then it must've already @@ -1343,9 +1346,11 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) add_device_randomness(&seed, sizeof(seed)); CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n", - libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits, + libcfs_nid2str(ni->ni_nid), + ni->ni_net->net_tunables.lct_peer_tx_credits, lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER, - ni->ni_peerrtrcredits, ni->ni_peertimeout); + ni->ni_net->net_tunables.lct_peer_rtr_credits, + ni->ni_net->net_tunables.lct_peer_timeout); return 0; failed0: @@ -1667,10 +1672,14 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) } config->cfg_nid = ni->ni_nid; - config->cfg_config_u.cfg_net.net_peer_timeout = ni->ni_peertimeout; - config->cfg_config_u.cfg_net.net_max_tx_credits = ni->ni_maxtxcredits; - config->cfg_config_u.cfg_net.net_peer_tx_credits = ni->ni_peertxcredits; - config->cfg_config_u.cfg_net.net_peer_rtr_credits = ni->ni_peerrtrcredits; + config->cfg_config_u.cfg_net.net_peer_timeout = + ni->ni_net->net_tunables.lct_peer_timeout; + config->cfg_config_u.cfg_net.net_max_tx_credits = + ni->ni_net->net_tunables.lct_max_tx_credits; + config->cfg_config_u.cfg_net.net_peer_tx_credits = + ni->ni_net->net_tunables.lct_peer_tx_credits; + config->cfg_config_u.cfg_net.net_peer_rtr_credits = + ni->ni_net->net_tunables.lct_peer_rtr_credits; net_config->ni_status = ni->ni_status->ns_status; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 091c4f714e84..86a53854e427 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -114,29 +114,38 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_net_ns) put_net(ni->ni_net_ns); + kvfree(ni->ni_net); kfree(ni); } struct lnet_ni * -lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) +lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) { struct lnet_tx_queue *tq; struct lnet_ni *ni; int rc; int i; + struct lnet_net *net; - if (!lnet_net_unique(net, nilist)) { + if (!lnet_net_unique(net_id, nilist)) { LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", - libcfs_net2str(net)); + libcfs_net2str(net_id)); return NULL; } ni = kzalloc(sizeof(*ni), GFP_NOFS); - if (!ni) { + net = kzalloc(sizeof(*net), GFP_NOFS); + if (!ni || !net) { + kfree(ni); kfree(net); CERROR("Out of memory creating network %s\n", - libcfs_net2str(net)); + libcfs_net2str(net_id)); return NULL; } + /* initialize global paramters to undefiend */ + net->net_tunables.lct_peer_timeout = -1; + net->net_tunables.lct_max_tx_credits = -1; + net->net_tunables.lct_peer_tx_credits = -1; + net->net_tunables.lct_peer_rtr_credits = -1; spin_lock_init(&ni->ni_lock); INIT_LIST_HEAD(&ni->ni_cptlist); @@ -160,7 +169,7 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) 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); + libcfs_net2str(net_id), rc); goto failed; } @@ -173,8 +182,9 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) ni->ni_ncpts = rc; } + ni->ni_net = net; /* LND will fill in the address part of the NID */ - ni->ni_nid = LNET_MKNID(net, 0); + ni->ni_nid = LNET_MKNID(net_id, 0); /* Store net namespace in which current ni is being created */ if (current->nsproxy->net_ns) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index edcafac055ed..f186e6a16d34 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -524,7 +524,8 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) lp->lp_timestamp >= lp->lp_last_alive) return 0; - deadline = lp->lp_last_alive + lp->lp_ni->ni_peertimeout; + deadline = lp->lp_last_alive + + lp->lp_ni->ni_net->net_tunables.lct_peer_timeout; alive = deadline > now; /* Update obsolete lp_alive except for routers assumed to be dead @@ -569,7 +570,7 @@ lnet_peer_alive_locked(struct lnet_peer *lp) libcfs_nid2str(lp->lp_nid), now, next_query, lnet_queryinterval, - lp->lp_ni->ni_peertimeout); + lp->lp_ni->ni_net->net_tunables.lct_peer_timeout); return 0; } } diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index d9452c322e4d..b76ac3e051d9 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -342,8 +342,8 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) goto out; } - lp->lp_txcredits = lp->lp_ni->ni_peertxcredits; - lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits; + lp->lp_txcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; + lp->lp_mintxcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; lp->lp_rtrcredits = lnet_peer_buffer_credits(lp->lp_ni); lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni); @@ -383,7 +383,7 @@ lnet_debug_peer(lnet_nid_t nid) CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", libcfs_nid2str(lp->lp_nid), lp->lp_refcount, - aliveness, lp->lp_ni->ni_peertxcredits, + aliveness, lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits, lp->lp_rtrcredits, lp->lp_minrtrcredits, lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob); @@ -438,7 +438,8 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, *nid = lp->lp_nid; *refcount = lp->lp_refcount; - *ni_peer_tx_credits = lp->lp_ni->ni_peertxcredits; + *ni_peer_tx_credits = + lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; *peer_tx_credits = lp->lp_txcredits; *peer_rtr_credits = lp->lp_rtrcredits; *peer_min_rtr_credits = lp->lp_mintxcredits; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 02241fbc9eaa..7d61c5d71426 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -57,9 +57,11 @@ MODULE_PARM_DESC(auto_down, "Automatically mark peers down on comms error"); int lnet_peer_buffer_credits(struct lnet_ni *ni) { + struct lnet_net *net = ni->ni_net; + /* NI option overrides LNet default */ - if (ni->ni_peerrtrcredits > 0) - return ni->ni_peerrtrcredits; + if (net->net_tunables.lct_peer_rtr_credits > 0) + return net->net_tunables.lct_peer_rtr_credits; if (peer_buffer_credits > 0) return peer_buffer_credits; @@ -67,7 +69,7 @@ lnet_peer_buffer_credits(struct lnet_ni *ni) * As an approximation, allow this peer the same number of router * buffers as it is allowed outstanding sends */ - return ni->ni_peertxcredits; + return net->net_tunables.lct_peer_tx_credits; } /* forward ref's */ diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 31f4982f7f17..19cea7076057 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -489,7 +489,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, int nrefs = peer->lp_refcount; time64_t lastalive = -1; char *aliveness = "NA"; - int maxcr = peer->lp_ni->ni_peertxcredits; + int maxcr = peer->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; int txcr = peer->lp_txcredits; int mintxcr = peer->lp_mintxcredits; int rtrcr = peer->lp_rtrcredits; @@ -704,8 +704,8 @@ static int proc_lnet_nis(struct ctl_table *table, int write, "%-24s %6s %5lld %4d %4d %4d %5d %5d %5d\n", libcfs_nid2str(ni->ni_nid), stat, last_alive, *ni->ni_refs[i], - ni->ni_peertxcredits, - ni->ni_peerrtrcredits, + ni->ni_net->net_tunables.lct_peer_tx_credits, + ni->ni_net->net_tunables.lct_peer_rtr_credits, tq->tq_credits_max, tq->tq_credits, tq->tq_credits_min); -------------- next part -------------- An HTML attachment was scrubbed... URL: From doucharek at cray.com Mon Sep 10 23:04:14 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:04:14 +0000 Subject: [lustre-devel] [PATCH 03/34] lnet: struct lnet_ni: move ni_lnd to lnet_net In-Reply-To: <153628137133.8267.15885218437939976879.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137133.8267.15885218437939976879.stgit@noble> Message-ID: <861CBCA6-75FF-4741-8507-00D891533522@cray.com> Is the gnilnd module being built upstream? Just as there were changes to o2iblnd.c and socklnd.c for this change, there should be a corresponding change to gnilnd.c. Doug > On Sep 6, 2018, at 5:49 PM, NeilBrown wrote: > > Also make some other minor changes to the structures. > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 13 ++++++++----- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- > drivers/staging/lustre/lnet/lnet/acceptor.c | 4 ++-- > drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++-------- > drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- > drivers/staging/lustre/lnet/lnet/lo.c | 2 +- > drivers/staging/lustre/lnet/lnet/router.c | 10 +++++----- > drivers/staging/lustre/lnet/lnet/router_proc.c | 2 +- > 9 files changed, 35 insertions(+), 32 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index ead8a4e1125a..e170eb07a5bf 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -262,12 +262,17 @@ struct lnet_net { > * shouldn't be reset > */ > bool net_tunables_set; > + /* procedural interface */ > + struct lnet_lnd *net_lnd; > }; > > struct lnet_ni { > - spinlock_t ni_lock; > - struct list_head ni_list; /* chain on ln_nis */ > - struct list_head ni_cptlist; /* chain on ln_nis_cpt */ > + /* chain on ln_nis */ > + struct list_head ni_list; > + /* chain on ln_nis_cpt */ > + struct list_head ni_cptlist; > + > + spinlock_t ni_lock; > > /* number of CPTs */ > int ni_ncpts; > @@ -281,8 +286,6 @@ struct lnet_ni { > /* instance-specific data */ > void *ni_data; > > - struct lnet_lnd *ni_lnd; /* procedural interface */ > - > /* percpt TX queues */ > struct lnet_tx_queue **ni_tx_queues; > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index 0d17e22c4401..5e1592b398c1 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -2830,7 +2830,7 @@ static int kiblnd_startup(struct lnet_ni *ni) > int rc; > int newdev; > > - LASSERT(ni->ni_lnd == &the_o2iblnd); > + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); > > if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { > rc = kiblnd_base_startup(); > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 4ad885f10235..2036a0ae5917 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -2726,7 +2726,7 @@ ksocknal_startup(struct lnet_ni *ni) > int rc; > int i; > > - LASSERT(ni->ni_lnd == &the_ksocklnd); > + LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); > > if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) { > rc = ksocknal_base_startup(); > diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c > index 3ae3ca1311a1..f8c921f0221c 100644 > --- a/drivers/staging/lustre/lnet/lnet/acceptor.c > +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c > @@ -306,7 +306,7 @@ lnet_accept(struct socket *sock, __u32 magic) > return -EPERM; > } > > - if (!ni->ni_lnd->lnd_accept) { > + if (!ni->ni_net->net_lnd->lnd_accept) { > /* This catches a request for the loopback LND */ > lnet_ni_decref(ni); > LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", > @@ -317,7 +317,7 @@ lnet_accept(struct socket *sock, __u32 magic) > CDEBUG(D_NET, "Accept %s from %pI4h\n", > libcfs_nid2str(cr.acr_nid), &peer_ip); > > - rc = ni->ni_lnd->lnd_accept(ni, sock); > + rc = ni->ni_net->net_lnd->lnd_accept(ni, sock); > > lnet_ni_decref(ni); > return rc; > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index cd4189fa7acb..0896e75bc3d7 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -799,7 +799,7 @@ lnet_count_acceptor_nis(void) > > cpt = lnet_net_lock_current(); > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_lnd->lnd_accept) > + if (ni->ni_net->net_lnd->lnd_accept) > count++; > } > > @@ -1098,13 +1098,13 @@ lnet_clear_zombies_nis_locked(void) > continue; > } > > - ni->ni_lnd->lnd_refcount--; > + ni->ni_net->net_lnd->lnd_refcount--; > lnet_net_unlock(LNET_LOCK_EX); > > - islo = ni->ni_lnd->lnd_type == LOLND; > + islo = ni->ni_net->net_lnd->lnd_type == LOLND; > > LASSERT(!in_interrupt()); > - ni->ni_lnd->lnd_shutdown(ni); > + ni->ni_net->net_lnd->lnd_shutdown(ni); > > /* > * can't deref lnd anymore now; it might have unregistered > @@ -1248,7 +1248,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > lnd->lnd_refcount++; > lnet_net_unlock(LNET_LOCK_EX); > > - ni->ni_lnd = lnd; > + ni->ni_net->net_lnd = lnd; > > if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) > lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; > @@ -1794,7 +1794,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > if (rc) > goto failed1; > > - if (ni->ni_lnd->lnd_accept) { > + if (ni->ni_net->net_lnd->lnd_accept) { > rc = lnet_acceptor_start(); > if (rc < 0) { > /* shutdown the ni that we just started */ > @@ -2074,10 +2074,10 @@ LNetCtl(unsigned int cmd, void *arg) > if (!ni) > return -EINVAL; > > - if (!ni->ni_lnd->lnd_ctl) > + if (!ni->ni_net->net_lnd->lnd_ctl) > rc = -EINVAL; > else > - rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); > + rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); > > lnet_ni_decref(ni); > return rc; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index f186e6a16d34..1bf12af87a20 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -406,7 +406,7 @@ lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, > iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset); > iov_iter_advance(&to, offset); > } > - rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > + rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > if (rc < 0) > lnet_finalize(ni, msg, rc); > } > @@ -461,7 +461,7 @@ lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) > LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || > (msg->msg_txcredit && msg->msg_peertxcredit)); > > - rc = ni->ni_lnd->lnd_send(ni, priv, msg); > + rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); > if (rc < 0) > lnet_finalize(ni, msg, rc); > } > @@ -474,10 +474,10 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) > LASSERT(!msg->msg_sending); > LASSERT(msg->msg_receiving); > LASSERT(!msg->msg_rx_ready_delay); > - LASSERT(ni->ni_lnd->lnd_eager_recv); > + LASSERT(ni->ni_net->net_lnd->lnd_eager_recv); > > msg->msg_rx_ready_delay = 1; > - rc = ni->ni_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > + rc = ni->ni_net->net_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > &msg->msg_private); > if (rc) { > CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", > @@ -496,10 +496,10 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > time64_t last_alive = 0; > > LASSERT(lnet_peer_aliveness_enabled(lp)); > - LASSERT(ni->ni_lnd->lnd_query); > + LASSERT(ni->ni_net->net_lnd->lnd_query); > > lnet_net_unlock(lp->lp_cpt); > - ni->ni_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > + ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > lnet_net_lock(lp->lp_cpt); > > lp->lp_last_query = ktime_get_seconds(); > @@ -1287,7 +1287,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > info.mi_roffset = hdr->msg.put.offset; > info.mi_mbits = hdr->msg.put.match_bits; > > - msg->msg_rx_ready_delay = !ni->ni_lnd->lnd_eager_recv; > + msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > ready_delay = msg->msg_rx_ready_delay; > > again: > @@ -1518,7 +1518,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) > > if (msg->msg_rxpeer->lp_rtrcredits <= 0 || > lnet_msg2bufpool(msg)->rbp_credits <= 0) { > - if (!ni->ni_lnd->lnd_eager_recv) { > + if (!ni->ni_net->net_lnd->lnd_eager_recv) { > msg->msg_rx_ready_delay = 1; > } else { > lnet_net_unlock(msg->msg_rx_cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c > index eb14146bd879..8167980c2323 100644 > --- a/drivers/staging/lustre/lnet/lnet/lo.c > +++ b/drivers/staging/lustre/lnet/lnet/lo.c > @@ -83,7 +83,7 @@ lolnd_shutdown(struct lnet_ni *ni) > static int > lolnd_startup(struct lnet_ni *ni) > { > - LASSERT(ni->ni_lnd == &the_lolnd); > + LASSERT(ni->ni_net->net_lnd == &the_lolnd); > LASSERT(!lolnd_instanced); > lolnd_instanced = 1; > > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 7d61c5d71426..0c0ec0b27982 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -154,14 +154,14 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > lp->lp_notifylnd = 0; > lp->lp_notify = 0; > > - if (notifylnd && ni->ni_lnd->lnd_notify) { > + if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { > lnet_net_unlock(lp->lp_cpt); > > /* > * A new notification could happen now; I'll handle it > * when control returns to me > */ > - ni->ni_lnd->lnd_notify(ni, lp->lp_nid, alive); > + ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); > > lnet_net_lock(lp->lp_cpt); > } > @@ -380,8 +380,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > lnet_net_unlock(LNET_LOCK_EX); > > /* XXX Assume alive */ > - if (ni->ni_lnd->lnd_notify) > - ni->ni_lnd->lnd_notify(ni, gateway, 1); > + if (ni->ni_net->net_lnd->lnd_notify) > + ni->ni_net->net_lnd->lnd_notify(ni, gateway, 1); > > lnet_net_lock(LNET_LOCK_EX); > } > @@ -818,7 +818,7 @@ lnet_update_ni_status_locked(void) > > now = ktime_get_real_seconds(); > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_lnd->lnd_type == LOLND) > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > continue; > > if (now < ni->ni_last_alive + timeout) > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 19cea7076057..f3ccd6a2b70e 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -674,7 +674,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > last_alive = now - ni->ni_last_alive; > > /* @lo forever alive */ > - if (ni->ni_lnd->lnd_type == LOLND) > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > last_alive = 0; > > lnet_ni_lock(ni); > > From doucharek at cray.com Mon Sep 10 23:08:15 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:08:15 +0000 Subject: [lustre-devel] [PATCH 04/34] lnet: embed lnd_tunables in lnet_ni In-Reply-To: <153628137138.8267.11270892110905717079.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137138.8267.11270892110905717079.stgit@noble> Message-ID: James Simmons: Should these tunable changes be made to gnilnd in a separate patch set? Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: Instead of a pointer, embed the data struct. Also other related changes. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown > --- .../staging/lustre/include/linux/lnet/lib-types.h | 6 ++++ .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 10 +++++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 + .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 6 ++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 8 +++--- .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 13 +++------- drivers/staging/lustre/lnet/lnet/api-ni.c | 27 +++++++++----------- drivers/staging/lustre/lnet/lnet/config.c | 2 - 8 files changed, 36 insertions(+), 38 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index e170eb07a5bf..c5e3363de727 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -302,7 +302,11 @@ struct lnet_ni { struct lnet_ni_status *ni_status; /* per NI LND tunables */ - struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables; + struct lnet_lnd_tunables ni_lnd_tunables; + + /* lnd tunables set explicitly */ + bool ni_lnd_tunables_set; + /* * equivalent interfaces to use * This is an array because socklnd bonding can still be configured diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index a8eb3b8f9fd7..ac29f9d24d5d 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -57,11 +57,15 @@ struct lnet_ioctl_config_o2iblnd_tunables { __u16 pad; }; +struct lnet_lnd_tunables { + union { + struct lnet_ioctl_config_o2iblnd_tunables lnd_o2ib; + } lnd_tun_u; +}; + struct lnet_ioctl_config_lnd_tunables { struct lnet_ioctl_config_lnd_cmn_tunables lt_cmn; - union { - struct lnet_ioctl_config_o2iblnd_tunables lt_o2ib; - } lt_tun_u; + struct lnet_lnd_tunables lt_tun; }; struct lnet_ioctl_net_config { diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 5e1592b398c1..ade566d20c69 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2122,7 +2122,7 @@ static int kiblnd_net_init_pools(struct kib_net *net, struct lnet_ni *ni, int rc; int i; - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; if (tunables->lnd_fmr_pool_size < *kiblnd_tunables.kib_ntx / 4) { CERROR("Can't set fmr pool size (%d) < ntx / 4(%d)\n", diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 42dc15cef194..522eb150d9a6 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -608,7 +608,7 @@ kiblnd_cfg_rdma_frags(struct lnet_ni *ni) struct lnet_ioctl_config_o2iblnd_tunables *tunables; int mod; - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; mod = tunables->lnd_map_on_demand; return mod ? mod : IBLND_MAX_RDMA_FRAGS >> IBLND_FRAG_SHIFT; } @@ -627,7 +627,7 @@ kiblnd_concurrent_sends(int version, struct lnet_ni *ni) struct lnet_ioctl_config_o2iblnd_tunables *tunables; int concurrent_sends; - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; concurrent_sends = tunables->lnd_concurrent_sends; if (version == IBLND_MSG_VERSION_1) { @@ -777,7 +777,7 @@ kiblnd_need_noop(struct kib_conn *conn) struct lnet_ni *ni = conn->ibc_peer->ibp_ni; LASSERT(conn->ibc_state >= IBLND_CONN_ESTABLISHED); - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; if (conn->ibc_outstanding_credits < IBLND_CREDITS_HIGHWATER(tunables, conn->ibc_version) && diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index a8d2b4911dab..c266940cb2ae 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1452,7 +1452,7 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) /* Brand new peer */ LASSERT(!peer->ibp_connecting); - tunables = &peer->ibp_ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + tunables = &peer->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; peer->ibp_connecting = tunables->lnd_conns_per_peer; /* always called with a ref on ni, which prevents ni being shutdown */ @@ -2592,14 +2592,14 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, break; case IBLND_REJECT_RDMA_FRAGS: { - struct lnet_ioctl_config_lnd_tunables *tunables; + struct lnet_ioctl_config_o2iblnd_tunables *tunables; if (!cp) { reason = "can't negotiate max frags"; goto out; } - tunables = peer->ibp_ni->ni_lnd_tunables; - if (!tunables->lt_tun_u.lt_o2ib.lnd_map_on_demand) { + tunables = &peer->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; + if (!tunables->lnd_map_on_demand) { reason = "map_on_demand must be enabled"; goto out; } diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index a1aca4dda38f..5117594f38fb 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -185,16 +185,11 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) * if there was no tunables specified, setup the tunables to be * defaulted */ - if (!ni->ni_lnd_tunables) { - ni->ni_lnd_tunables = kzalloc(sizeof(*ni->ni_lnd_tunables), - GFP_NOFS); - if (!ni->ni_lnd_tunables) - return -ENOMEM; - - memcpy(&ni->ni_lnd_tunables->lt_tun_u.lt_o2ib, + if (!ni->ni_lnd_tunables_set) + memcpy(&ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib, &default_tunables, sizeof(*tunables)); - } - tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib; + + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; /* Current API version */ tunables->lnd_version = 0; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 0896e75bc3d7..c944fbb155c8 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1198,6 +1198,7 @@ static int lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) { struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; + struct lnet_lnd_tunables *tun = NULL; int rc = -EINVAL; int lnd_type; struct lnet_lnd *lnd; @@ -1250,19 +1251,15 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) ni->ni_net->net_lnd = lnd; - if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) + if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) { lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; + tun = &lnd_tunables->lt_tun; + } - if (lnd_tunables) { - ni->ni_lnd_tunables = kzalloc(sizeof(*ni->ni_lnd_tunables), - GFP_NOFS); - if (!ni->ni_lnd_tunables) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - rc = -ENOMEM; - goto failed0; - } - memcpy(ni->ni_lnd_tunables, lnd_tunables, - sizeof(*ni->ni_lnd_tunables)); + if (tun) { + memcpy(&ni->ni_lnd_tunables, tun, + sizeof(*tun)); + ni->ni_lnd_tunables_set = true; } /* @@ -1702,15 +1699,15 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) tunable_size = config->cfg_hdr.ioc_len - min_size; /* Don't copy to much data to user space */ - min_size = min(tunable_size, sizeof(*ni->ni_lnd_tunables)); + min_size = min(tunable_size, sizeof(ni->ni_lnd_tunables)); lnd_cfg = (struct lnet_ioctl_config_lnd_tunables *)net_config->cfg_bulk; - if (ni->ni_lnd_tunables && lnd_cfg && min_size) { - memcpy(lnd_cfg, ni->ni_lnd_tunables, min_size); + if (lnd_cfg && min_size) { + memcpy(&lnd_cfg->lt_tun, &ni->ni_lnd_tunables, min_size); config->cfg_config_u.cfg_net.net_interface_count = 1; /* Tell user land that kernel side has less data */ - if (tunable_size > sizeof(*ni->ni_lnd_tunables)) { + if (tunable_size > sizeof(ni->ni_lnd_tunables)) { min_size = tunable_size - sizeof(ni->ni_lnd_tunables); config->cfg_hdr.ioc_len -= min_size; } diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 86a53854e427..5646feeb433e 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -105,8 +105,6 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_cpts) cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts); - kfree(ni->ni_lnd_tunables); - for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) kfree(ni->ni_interfaces[i]); -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Mon Sep 10 23:10:37 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:10:37 +0100 (BST) Subject: [lustre-devel] [PATCH 00/34] Beginning of multi-rail support for drivers/staging/lustre In-Reply-To: <153628058697.8267.6056114844033479774.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: > The following series implements the first patch in the > multi-rail series: > Commit: 8cbb8cd3e771 ("LU-7734 lnet: Multi-Rail local NI split") > > I split that commit up into 40 individual commits which can be found > at > https://github.com/neilbrown/lustre/commits/multirail > though you need to scroll down a bit, as that contains all the > multi-rail series. > > I then ported most of these patches to my mainline tree. > Some that I haven't included are: > - lnet: Move lnet_msg_alloc/free down a bit. > lnet_msg_alloc/free don't exist any more > - lnet: lib-types: change some tabs to spaces > - lnet - assorted whitespace changes. > - lnet: change ni_last_alive from time64_t to long > - lnet: add lnet_net_state > net_state is never used. > - lnet: remove 'static' from lnet_get_net_config() > > I've also made a couple of minor changes to individual patches not > strictly related to porting (the net_prio field is never used, so I > never added it - I should have made that a separate patch). > > This series compiles, but doesn't work. I get a NULL pointer > reference, then an assertion failure. If I fix those, it hangs. > The NULL pointer ref and the failing assertion are gone with > later patches, so I hope the other problems are too. > I have tried it and did a compare to what landed in the OpenSFS branch. I saw the failures in my testing and foudn the mistake in the 7th patch. > Some of these patches have very poor descriptions, such as "I have no > idea what this does". If someone would like to explain - or maybe say > "Oh, we really shouldn't have done that", I'd be very happy to > receive that, and update the description or patch accordingly. When I ran checkpatch it really dislikes: This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split I don't recommend landing the above in the commit messsage as for the reason that a person outside of lustre will not know where to look for that git commit. Instead I recommend replacing it with: ------------------------------------------------------------------ Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18274 Reviewed-by: Doug Oucharek Reviewed-by: Olaf Weber Signed-off-by: NeilBrown This gives the reviewer a URL link for both the JIRA ticket that usually contains details not in the commit message as well as the gerrit URL for the original patch. This way if a future bug is found a comparison can be done against the original patch. The policy for the Lustre project is to perserve authorship for patches when porting to other branches, upstream or LTS. > These will all appear in my lustre-testing branch, but won't migrate > to 'lustre' until I, at least, have enough other patches that I can > get a successful test run. > > Review and comments always welcome. > > Thanks, > NeilBrown > > > --- > > Amir Shehata (1): > Completely re-write lnet_parse_networks(). > > NeilBrown (33): > struct lnet_ni - reformat comments. > lnet: Create struct lnet_net > lnet: struct lnet_ni: move ni_lnd to lnet_net > lnet: embed lnd_tunables in lnet_ni > lnet: begin separating "networks" from "network interfaces". > lnet: store separate xmit/recv net-interface in each message. > lnet: change lnet_peer to reference the net, rather than ni. > lnet: add cpt to lnet_match_info. > lnet: add list of cpts to lnet_net. > lnet: add ni arg to lnet_cpt_of_nid() > lnet: pass tun to lnet_startup_lndni, instead of full conf > lnet: split lnet_startup_lndni > lnet: reverse order of lnet_startup_lnd{net,ni} > lnet: rename lnet_find_net_locked to lnet_find_rnet_locked > lnet: extend zombie handling to nets and nis > lnet: lnet_shutdown_lndnets - remove some cleanup code. > lnet: move lnet_shutdown_lndnets down to after first use > lnet: add ni_state > lnet: simplify lnet_islocalnet() > lnet: discard ni_cpt_list > lnet: add net_ni_added > lnet: don't take reference in lnet_XX2ni_locked() > lnet: don't need lock to test ln_shutdown. > lnet: don't take lock over lnet_net_unique() > lnet: swap 'then' and 'else' branches in lnet_startup_lndnet > lnet: only valid lnd_type when net_id is unique. > lnet: make it possible to add a new interface to a network > lnet: add checks to ensure network interface names are unique. > lnet: track tunables in lnet_startup_lndnet() > lnet: fix typo > lnet: lnet_dyn_add_ni: fix ping_info count > lnet: lnet_dyn_del_ni: fix ping_info count > lnet: introduce use_tcp_bonding mod param > > > .../staging/lustre/include/linux/lnet/lib-lnet.h | 31 - > .../staging/lustre/include/linux/lnet/lib-types.h | 142 ++- > .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 18 > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 10 > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 6 > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 12 > .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 74 +- > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 25 - > drivers/staging/lustre/lnet/lnet/acceptor.c | 8 > drivers/staging/lustre/lnet/lnet/api-ni.c | 939 +++++++++++++------- > drivers/staging/lustre/lnet/lnet/config.c | 688 +++++++++++---- > drivers/staging/lustre/lnet/lnet/lib-move.c | 132 ++- > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 6 > drivers/staging/lustre/lnet/lnet/lo.c | 2 > drivers/staging/lustre/lnet/lnet/net_fault.c | 3 > drivers/staging/lustre/lnet/lnet/peer.c | 31 - > drivers/staging/lustre/lnet/lnet/router.c | 51 + > drivers/staging/lustre/lnet/lnet/router_proc.c | 24 - > drivers/staging/lustre/lnet/selftest/brw_test.c | 2 > drivers/staging/lustre/lnet/selftest/framework.c | 3 > drivers/staging/lustre/lnet/selftest/selftest.h | 2 > 21 files changed, 1507 insertions(+), 702 deletions(-) > > -- > Signature > > From jsimmons at infradead.org Mon Sep 10 23:17:06 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:17:06 +0100 (BST) Subject: [lustre-devel] [PATCH 07/34] lnet: change lnet_peer to reference the net, rather than ni. In-Reply-To: <153628137151.8267.3943711043829439593.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137151.8267.3943711043829439593.stgit@noble> Message-ID: > As a net will soon have multiple ni, a peer should identify > just the net. > Various places that we need the ni, we now use rxni or txni from > the message > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 + > .../staging/lustre/include/linux/lnet/lib-types.h | 5 +- > drivers/staging/lustre/lnet/lnet/api-ni.c | 13 +++++ > drivers/staging/lustre/lnet/lnet/lib-move.c | 49 +++++++++++--------- > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 - > drivers/staging/lustre/lnet/lnet/net_fault.c | 3 + > drivers/staging/lustre/lnet/lnet/peer.c | 26 ++++------- > drivers/staging/lustre/lnet/lnet/router.c | 14 +++--- > drivers/staging/lustre/lnet/lnet/router_proc.c | 2 - > 9 files changed, 67 insertions(+), 50 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 4440b87299c4..34509e52bac7 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -435,6 +435,7 @@ int lnet_dyn_add_ni(lnet_pid_t requested_pid, > struct lnet_ioctl_config_data *conf); > int lnet_dyn_del_ni(__u32 net); > int lnet_clear_lazy_portal(struct lnet_ni *ni, int portal, char *reason); > +struct lnet_net *lnet_get_net_locked(__u32 net_id); Using __u32 and friends for internal lustre kernel code was disliked by Greg. I recommend any new code pushed in which __uXX is used is changed to the proper kernel uXX versions. > int lnet_islocalnid(lnet_nid_t nid); > int lnet_islocalnet(__u32 net); > @@ -617,7 +618,7 @@ int lnet_sock_connect(struct socket **sockp, int *fatal, > void libcfs_sock_release(struct socket *sock); > > int lnet_peers_start_down(void); > -int lnet_peer_buffer_credits(struct lnet_ni *ni); > +int lnet_peer_buffer_credits(struct lnet_net *net); > > int lnet_router_checker_start(void); > void lnet_router_checker_stop(void); > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 16a493529a46..255c6c4bbb89 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -396,7 +396,8 @@ struct lnet_peer { > time64_t lp_last_query; /* when lp_ni was queried > * last time > */ > - struct lnet_ni *lp_ni; /* interface peer is on */ > + /* network peer is on */ > + struct lnet_net *lp_net; > lnet_nid_t lp_nid; /* peer's NID */ > int lp_refcount; /* # refs */ > int lp_cpt; /* CPT this peer attached on */ > @@ -427,7 +428,7 @@ struct lnet_peer_table { > * lnet_ni::ni_peertimeout has been set to a positive value > */ > #define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing && \ > - (lp)->lp_ni->ni_net->net_tunables.lct_peer_timeout > 0) > + (lp)->lp_net->net_tunables.lct_peer_timeout > 0) > > struct lnet_route { > struct list_head lr_list; /* chain on net */ > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 05687278334a..c21aef32cdde 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -680,6 +680,19 @@ lnet_net2ni(__u32 net) > } > EXPORT_SYMBOL(lnet_net2ni); > > +struct lnet_net * > +lnet_get_net_locked(__u32 net_id) > +{ > + struct lnet_net *net; > + > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + if (net->net_id == net_id) > + return net; > + } > + > + return NULL; > +} > + > static unsigned int > lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) > { > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index b2a52ddcefcb..b8b15f56a275 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -525,7 +525,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) > return 0; > > deadline = lp->lp_last_alive + > - lp->lp_ni->ni_net->net_tunables.lct_peer_timeout; > + lp->lp_net->net_tunables.lct_peer_timeout; > alive = deadline > now; > > /* Update obsolete lp_alive except for routers assumed to be dead > @@ -544,7 +544,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) > * may drop the lnet_net_lock > */ > static int > -lnet_peer_alive_locked(struct lnet_peer *lp) > +lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) > { > time64_t now = ktime_get_seconds(); > > @@ -570,13 +570,13 @@ lnet_peer_alive_locked(struct lnet_peer *lp) > libcfs_nid2str(lp->lp_nid), > now, next_query, > lnet_queryinterval, > - lp->lp_ni->ni_net->net_tunables.lct_peer_timeout); > + lp->lp_net->net_tunables.lct_peer_timeout); > return 0; > } > } > > /* query NI for latest aliveness news */ > - lnet_ni_query_locked(lp->lp_ni, lp); > + lnet_ni_query_locked(ni, lp); > > if (lnet_peer_is_alive(lp, now)) > return 1; > @@ -600,7 +600,7 @@ static int > lnet_post_send_locked(struct lnet_msg *msg, int do_send) > { > struct lnet_peer *lp = msg->msg_txpeer; > - struct lnet_ni *ni = lp->lp_ni; > + struct lnet_ni *ni = msg->msg_txni; > int cpt = msg->msg_tx_cpt; > struct lnet_tx_queue *tq = ni->ni_tx_queues[cpt]; > > @@ -611,7 +611,7 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) > > /* NB 'lp' is always the next hop */ > if (!(msg->msg_target.pid & LNET_PID_USERFLAG) && > - !lnet_peer_alive_locked(lp)) { > + !lnet_peer_alive_locked(ni, lp)) { > the_lnet.ln_counters[cpt]->drop_count++; > the_lnet.ln_counters[cpt]->drop_length += msg->msg_len; > lnet_net_unlock(cpt); > @@ -770,7 +770,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) > int cpt = msg->msg_rx_cpt; > > lnet_net_unlock(cpt); > - lnet_ni_recv(lp->lp_ni, msg->msg_private, msg, 1, > + lnet_ni_recv(msg->msg_rxni, msg->msg_private, msg, 1, > 0, msg->msg_len, msg->msg_len); > lnet_net_lock(cpt); > } > @@ -785,7 +785,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > struct lnet_ni *txni = msg->msg_txni; > > if (msg->msg_txcredit) { > - struct lnet_ni *ni = txpeer->lp_ni; > + struct lnet_ni *ni = msg->msg_txni; > struct lnet_tx_queue *tq = ni->ni_tx_queues[msg->msg_tx_cpt]; > > /* give back NI txcredits */ > @@ -800,7 +800,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > struct lnet_msg, msg_list); > list_del(&msg2->msg_list); > > - LASSERT(msg2->msg_txpeer->lp_ni == ni); > + LASSERT(msg2->msg_txni == ni); > LASSERT(msg2->msg_tx_delayed); > > (void)lnet_post_send_locked(msg2, 1); > @@ -869,7 +869,7 @@ lnet_drop_routed_msgs_locked(struct list_head *list, int cpt) > > while(!list_empty(&drop)) { > msg = list_first_entry(&drop, struct lnet_msg, msg_list); > - lnet_ni_recv(msg->msg_rxpeer->lp_ni, msg->msg_private, NULL, > + lnet_ni_recv(msg->msg_rxni, msg->msg_private, NULL, > 0, 0, 0, msg->msg_hdr.payload_length); > list_del_init(&msg->msg_list); > lnet_finalize(NULL, msg, -ECANCELED); > @@ -1007,7 +1007,7 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) > } > > static struct lnet_peer * > -lnet_find_route_locked(struct lnet_ni *ni, lnet_nid_t target, > +lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > lnet_nid_t rtr_nid) > { > struct lnet_remotenet *rnet; > @@ -1035,7 +1035,7 @@ lnet_find_route_locked(struct lnet_ni *ni, lnet_nid_t target, > if (!lnet_is_route_alive(route)) > continue; > > - if (ni && lp->lp_ni != ni) > + if (net && lp->lp_net != net) > continue; > > if (lp->lp_nid == rtr_nid) /* it's pre-determined router */ > @@ -1164,10 +1164,12 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > /* ENOMEM or shutting down */ > return rc; > } > - LASSERT(lp->lp_ni == src_ni); > + LASSERT(lp->lp_net == src_ni->ni_net); > } else { > /* sending to a remote network */ > - lp = lnet_find_route_locked(src_ni, dst_nid, rtr_nid); > + lp = lnet_find_route_locked(src_ni != NULL ? > + src_ni->ni_net : NULL, > + dst_nid, rtr_nid); > if (!lp) { > if (src_ni) > lnet_ni_decref_locked(src_ni, cpt); > @@ -1203,10 +1205,11 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > lnet_msgtyp2str(msg->msg_type), msg->msg_len); > > if (!src_ni) { > - src_ni = lp->lp_ni; > + src_ni = lnet_get_next_ni_locked(lp->lp_net, NULL); > + LASSERT(src_ni != NULL); Checkpatch will not like the above. > src_nid = src_ni->ni_nid; > } else { > - LASSERT(src_ni == lp->lp_ni); > + LASSERT(src_ni->ni_net == lp->lp_net); > lnet_ni_decref_locked(src_ni, cpt); > } > > @@ -1918,7 +1921,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) > * called lnet_drop_message(), so I just hang onto msg as well > * until that's done > */ > - lnet_drop_message(msg->msg_rxpeer->lp_ni, > + lnet_drop_message(msg->msg_rxni, > msg->msg_rxpeer->lp_cpt, > msg->msg_private, msg->msg_len); > /* > @@ -1926,7 +1929,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) > * but we still should give error code so lnet_msg_decommit() > * can skip counters operations and other checks. > */ > - lnet_finalize(msg->msg_rxpeer->lp_ni, msg, -ENOENT); > + lnet_finalize(msg->msg_rxni, msg, -ENOENT); > } > } > > @@ -1959,7 +1962,7 @@ lnet_recv_delayed_msg_list(struct list_head *head) > msg->msg_hdr.msg.put.offset, > msg->msg_hdr.payload_length); > > - lnet_recv_put(msg->msg_rxpeer->lp_ni, msg); > + lnet_recv_put(msg->msg_rxni, msg); > } > } > > @@ -2384,8 +2387,12 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) > > LASSERT(shortest); > hops = shortest_hops; > - if (srcnidp) > - *srcnidp = shortest->lr_gateway->lp_ni->ni_nid; > + if (srcnidp) { > + ni = lnet_get_next_ni_locked( > + shortest->lr_gateway->lp_net, > + NULL); > + *srcnidp = ni->ni_nid; > + } > if (orderp) > *orderp = order; > lnet_net_unlock(cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > index fc47379c5938..4c5737083422 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > @@ -946,7 +946,7 @@ lnet_clear_lazy_portal(struct lnet_ni *ni, int portal, char *reason) > /* grab all messages which are on the NI passed in */ > list_for_each_entry_safe(msg, tmp, &ptl->ptl_msg_delayed, > msg_list) { > - if (msg->msg_rxpeer->lp_ni == ni) > + if (msg->msg_txni == ni || msg->msg_rxni == ni) > list_move(&msg->msg_list, &zombies); > } > } else { > diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c > index 41d6131ee15a..6c53ae1811e5 100644 > --- a/drivers/staging/lustre/lnet/lnet/net_fault.c > +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c > @@ -601,8 +601,9 @@ delayed_msg_process(struct list_head *msg_list, bool drop) > > msg = list_entry(msg_list->next, struct lnet_msg, msg_list); > LASSERT(msg->msg_rxpeer); > + LASSERT(msg->msg_rxni != NULL); > > - ni = msg->msg_rxpeer->lp_ni; > + ni = msg->msg_rxni; > cpt = msg->msg_rx_cpt; > > list_del_init(&msg->msg_list); > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index b76ac3e051d9..ed29124ebded 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -112,7 +112,7 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, > for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { > list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], > lp_hashlist) { > - if (ni && ni != lp->lp_ni) > + if (ni && ni->ni_net != lp->lp_net) > continue; > list_del_init(&lp->lp_hashlist); > /* Lose hash table's ref */ > @@ -154,7 +154,7 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, > for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { > list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], > lp_hashlist) { > - if (ni != lp->lp_ni) > + if (ni->ni_net != lp->lp_net) > continue; > > if (!lp->lp_rtr_refcount) > @@ -230,8 +230,7 @@ lnet_destroy_peer_locked(struct lnet_peer *lp) > LASSERT(ptable->pt_number > 0); > ptable->pt_number--; > > - lnet_ni_decref_locked(lp->lp_ni, lp->lp_cpt); > - lp->lp_ni = NULL; > + lp->lp_net = NULL; > > list_add(&lp->lp_hashlist, &ptable->pt_deathrow); > LASSERT(ptable->pt_zombies > 0); > @@ -336,16 +335,11 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > goto out; > } > > - lp->lp_ni = lnet_net2ni_locked(LNET_NIDNET(nid), cpt2); > - if (!lp->lp_ni) { > - rc = -EHOSTUNREACH; > - goto out; > - } > - > - lp->lp_txcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > - lp->lp_mintxcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > - lp->lp_rtrcredits = lnet_peer_buffer_credits(lp->lp_ni); > - lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni); > + lp->lp_net = lnet_get_net_locked(LNET_NIDNET(!lp->lp_nid)); This is the single error in your port that broke stuff. The correct code is: lp->lp_net = lnet_get_net_locked(LNET_NIDNET(lp->lp_nid)); > + lp->lp_txcredits = > + lp->lp_mintxcredits = lp->lp_net->net_tunables.lct_peer_tx_credits; > + lp->lp_rtrcredits = > + lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_net); > > list_add_tail(&lp->lp_hashlist, > &ptable->pt_hash[lnet_nid2peerhash(nid)]); > @@ -383,7 +377,7 @@ lnet_debug_peer(lnet_nid_t nid) > > CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", > libcfs_nid2str(lp->lp_nid), lp->lp_refcount, > - aliveness, lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits, > + aliveness, lp->lp_net->net_tunables.lct_peer_tx_credits, > lp->lp_rtrcredits, lp->lp_minrtrcredits, > lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob); > > @@ -439,7 +433,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, > *nid = lp->lp_nid; > *refcount = lp->lp_refcount; > *ni_peer_tx_credits = > - lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > + lp->lp_net->net_tunables.lct_peer_tx_credits; > *peer_tx_credits = lp->lp_txcredits; > *peer_rtr_credits = lp->lp_rtrcredits; > *peer_min_rtr_credits = lp->lp_mintxcredits; > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 135dfe793b0b..72b8ca2b0fc6 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -55,10 +55,8 @@ module_param(auto_down, int, 0444); > MODULE_PARM_DESC(auto_down, "Automatically mark peers down on comms error"); > > int > -lnet_peer_buffer_credits(struct lnet_ni *ni) > +lnet_peer_buffer_credits(struct lnet_net *net) > { > - struct lnet_net *net = ni->ni_net; > - > /* NI option overrides LNet default */ > if (net->net_tunables.lct_peer_rtr_credits > 0) > return net->net_tunables.lct_peer_rtr_credits; > @@ -373,7 +371,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > lnet_peer_addref_locked(route->lr_gateway); /* +1 for notify */ > lnet_add_route_to_rnet(rnet2, route); > > - ni = route->lr_gateway->lp_ni; > + ni = lnet_get_next_ni_locked(route->lr_gateway->lp_net, NULL); > lnet_net_unlock(LNET_LOCK_EX); > > /* XXX Assume alive */ > @@ -428,8 +426,8 @@ lnet_check_routes(void) > continue; > } > > - if (route->lr_gateway->lp_ni == > - route2->lr_gateway->lp_ni) > + if (route->lr_gateway->lp_net == > + route2->lr_gateway->lp_net) > continue; > > nid1 = route->lr_gateway->lp_nid; > @@ -952,6 +950,7 @@ lnet_ping_router_locked(struct lnet_peer *rtr) > struct lnet_rc_data *rcd = NULL; > time64_t now = ktime_get_seconds(); > time64_t secs; > + struct lnet_ni *ni; Another grep from Greg was the spacing in declared variables. As I port patches new code removes the spacing. Newer lustre code no long does this kind of spacing. Well most of it :-) > > lnet_peer_addref_locked(rtr); > > @@ -960,7 +959,8 @@ lnet_ping_router_locked(struct lnet_peer *rtr) > lnet_notify_locked(rtr, 1, 0, now); > > /* Run any outstanding notifications */ > - lnet_ni_notify_locked(rtr->lp_ni, rtr); > + ni = lnet_get_next_ni_locked(rtr->lp_net, NULL); > + lnet_ni_notify_locked(ni, rtr); > > if (!lnet_isrouter(rtr) || > the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) { > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 2a366e9a8627..52714b898aac 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -489,7 +489,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > int nrefs = peer->lp_refcount; > time64_t lastalive = -1; > char *aliveness = "NA"; > - int maxcr = peer->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > + int maxcr = peer->lp_net->net_tunables.lct_peer_tx_credits; > int txcr = peer->lp_txcredits; > int mintxcr = peer->lp_mintxcredits; > int rtrcr = peer->lp_rtrcredits; > > > From jsimmons at infradead.org Mon Sep 10 23:17:57 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:17:57 +0100 (BST) Subject: [lustre-devel] [PATCH 01/34] struct lnet_ni - reformat comments. In-Reply-To: <153628137125.8267.7825080417267355121.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137125.8267.7825080417267355121.stgit@noble> Message-ID: > This is part of > > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail > local NI split Better commit message would be: Rework the commonents in lib-types.h to limit the checkpatch chatter of being over 80 characters. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18274 Reviewed-by: Doug Oucharek Reviewed-by: Olaf Weber Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 38 +++++++++++++++----- > 1 file changed, 29 insertions(+), 9 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 6d4106fd9039..078bc97a9ebf 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -263,18 +263,38 @@ struct lnet_ni { > int ni_peerrtrcredits; > /* seconds to consider peer dead */ > int ni_peertimeout; > - int ni_ncpts; /* number of CPTs */ > - __u32 *ni_cpts; /* bond NI on some CPTs */ > - lnet_nid_t ni_nid; /* interface's NID */ > - void *ni_data; /* instance-specific data */ > + /* number of CPTs */ > + int ni_ncpts; > + > + /* bond NI on some CPTs */ > + __u32 *ni_cpts; > + > + /* interface's NID */ > + lnet_nid_t ni_nid; > + > + /* instance-specific data */ > + void *ni_data; > + > struct lnet_lnd *ni_lnd; /* procedural interface */ > - struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */ > - int **ni_refs; /* percpt reference count */ > - time64_t ni_last_alive;/* when I was last alive */ > - struct lnet_ni_status *ni_status; /* my health status */ > + > + /* percpt TX queues */ > + struct lnet_tx_queue **ni_tx_queues; > + > + /* percpt reference count */ > + int **ni_refs; > + > + /* when I was last alive */ > + time64_t ni_last_alive; > + > + /* my health status */ > + struct lnet_ni_status *ni_status; > + > /* per NI LND tunables */ > struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables; > - /* equivalent interfaces to use */ > + /* > + * equivalent interfaces to use > + * This is an array because socklnd bonding can still be configured > + */ > char *ni_interfaces[LNET_MAX_INTERFACES]; > /* original net namespace */ > struct net *ni_net_ns; > > > From jsimmons at infradead.org Mon Sep 10 23:19:17 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:19:17 +0100 (BST) Subject: [lustre-devel] [PATCH 03/34] lnet: struct lnet_ni: move ni_lnd to lnet_net In-Reply-To: <861CBCA6-75FF-4741-8507-00D891533522@cray.com> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137133.8267.15885218437939976879.stgit@noble> <861CBCA6-75FF-4741-8507-00D891533522@cray.com> Message-ID: > Is the gnilnd module being built upstream? Just as there were changes to o2iblnd.c and socklnd.c for this change, there should be a corresponding change to gnilnd.c. No gnilnd in th elinux kernel :-( > Doug > > > On Sep 6, 2018, at 5:49 PM, NeilBrown wrote: > > > > Also make some other minor changes to the structures. > > > > This is part of > > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > > LU-7734 lnet: Multi-Rail local NI split > > > > Signed-off-by: NeilBrown > > --- > > .../staging/lustre/include/linux/lnet/lib-types.h | 13 ++++++++----- > > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- > > drivers/staging/lustre/lnet/lnet/acceptor.c | 4 ++-- > > drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++-------- > > drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- > > drivers/staging/lustre/lnet/lnet/lo.c | 2 +- > > drivers/staging/lustre/lnet/lnet/router.c | 10 +++++----- > > drivers/staging/lustre/lnet/lnet/router_proc.c | 2 +- > > 9 files changed, 35 insertions(+), 32 deletions(-) > > > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > > index ead8a4e1125a..e170eb07a5bf 100644 > > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > > @@ -262,12 +262,17 @@ struct lnet_net { > > * shouldn't be reset > > */ > > bool net_tunables_set; > > + /* procedural interface */ > > + struct lnet_lnd *net_lnd; > > }; > > > > struct lnet_ni { > > - spinlock_t ni_lock; > > - struct list_head ni_list; /* chain on ln_nis */ > > - struct list_head ni_cptlist; /* chain on ln_nis_cpt */ > > + /* chain on ln_nis */ > > + struct list_head ni_list; > > + /* chain on ln_nis_cpt */ > > + struct list_head ni_cptlist; > > + > > + spinlock_t ni_lock; > > > > /* number of CPTs */ > > int ni_ncpts; > > @@ -281,8 +286,6 @@ struct lnet_ni { > > /* instance-specific data */ > > void *ni_data; > > > > - struct lnet_lnd *ni_lnd; /* procedural interface */ > > - > > /* percpt TX queues */ > > struct lnet_tx_queue **ni_tx_queues; > > > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > index 0d17e22c4401..5e1592b398c1 100644 > > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > @@ -2830,7 +2830,7 @@ static int kiblnd_startup(struct lnet_ni *ni) > > int rc; > > int newdev; > > > > - LASSERT(ni->ni_lnd == &the_o2iblnd); > > + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); > > > > if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { > > rc = kiblnd_base_startup(); > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > index 4ad885f10235..2036a0ae5917 100644 > > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > @@ -2726,7 +2726,7 @@ ksocknal_startup(struct lnet_ni *ni) > > int rc; > > int i; > > > > - LASSERT(ni->ni_lnd == &the_ksocklnd); > > + LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); > > > > if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) { > > rc = ksocknal_base_startup(); > > diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c > > index 3ae3ca1311a1..f8c921f0221c 100644 > > --- a/drivers/staging/lustre/lnet/lnet/acceptor.c > > +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c > > @@ -306,7 +306,7 @@ lnet_accept(struct socket *sock, __u32 magic) > > return -EPERM; > > } > > > > - if (!ni->ni_lnd->lnd_accept) { > > + if (!ni->ni_net->net_lnd->lnd_accept) { > > /* This catches a request for the loopback LND */ > > lnet_ni_decref(ni); > > LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", > > @@ -317,7 +317,7 @@ lnet_accept(struct socket *sock, __u32 magic) > > CDEBUG(D_NET, "Accept %s from %pI4h\n", > > libcfs_nid2str(cr.acr_nid), &peer_ip); > > > > - rc = ni->ni_lnd->lnd_accept(ni, sock); > > + rc = ni->ni_net->net_lnd->lnd_accept(ni, sock); > > > > lnet_ni_decref(ni); > > return rc; > > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > > index cd4189fa7acb..0896e75bc3d7 100644 > > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > > @@ -799,7 +799,7 @@ lnet_count_acceptor_nis(void) > > > > cpt = lnet_net_lock_current(); > > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > > - if (ni->ni_lnd->lnd_accept) > > + if (ni->ni_net->net_lnd->lnd_accept) > > count++; > > } > > > > @@ -1098,13 +1098,13 @@ lnet_clear_zombies_nis_locked(void) > > continue; > > } > > > > - ni->ni_lnd->lnd_refcount--; > > + ni->ni_net->net_lnd->lnd_refcount--; > > lnet_net_unlock(LNET_LOCK_EX); > > > > - islo = ni->ni_lnd->lnd_type == LOLND; > > + islo = ni->ni_net->net_lnd->lnd_type == LOLND; > > > > LASSERT(!in_interrupt()); > > - ni->ni_lnd->lnd_shutdown(ni); > > + ni->ni_net->net_lnd->lnd_shutdown(ni); > > > > /* > > * can't deref lnd anymore now; it might have unregistered > > @@ -1248,7 +1248,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > > lnd->lnd_refcount++; > > lnet_net_unlock(LNET_LOCK_EX); > > > > - ni->ni_lnd = lnd; > > + ni->ni_net->net_lnd = lnd; > > > > if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) > > lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; > > @@ -1794,7 +1794,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > > if (rc) > > goto failed1; > > > > - if (ni->ni_lnd->lnd_accept) { > > + if (ni->ni_net->net_lnd->lnd_accept) { > > rc = lnet_acceptor_start(); > > if (rc < 0) { > > /* shutdown the ni that we just started */ > > @@ -2074,10 +2074,10 @@ LNetCtl(unsigned int cmd, void *arg) > > if (!ni) > > return -EINVAL; > > > > - if (!ni->ni_lnd->lnd_ctl) > > + if (!ni->ni_net->net_lnd->lnd_ctl) > > rc = -EINVAL; > > else > > - rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); > > + rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); > > > > lnet_ni_decref(ni); > > return rc; > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > > index f186e6a16d34..1bf12af87a20 100644 > > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > > @@ -406,7 +406,7 @@ lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, > > iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset); > > iov_iter_advance(&to, offset); > > } > > - rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > > + rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > > if (rc < 0) > > lnet_finalize(ni, msg, rc); > > } > > @@ -461,7 +461,7 @@ lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) > > LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || > > (msg->msg_txcredit && msg->msg_peertxcredit)); > > > > - rc = ni->ni_lnd->lnd_send(ni, priv, msg); > > + rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); > > if (rc < 0) > > lnet_finalize(ni, msg, rc); > > } > > @@ -474,10 +474,10 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) > > LASSERT(!msg->msg_sending); > > LASSERT(msg->msg_receiving); > > LASSERT(!msg->msg_rx_ready_delay); > > - LASSERT(ni->ni_lnd->lnd_eager_recv); > > + LASSERT(ni->ni_net->net_lnd->lnd_eager_recv); > > > > msg->msg_rx_ready_delay = 1; > > - rc = ni->ni_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > > + rc = ni->ni_net->net_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > > &msg->msg_private); > > if (rc) { > > CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", > > @@ -496,10 +496,10 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > > time64_t last_alive = 0; > > > > LASSERT(lnet_peer_aliveness_enabled(lp)); > > - LASSERT(ni->ni_lnd->lnd_query); > > + LASSERT(ni->ni_net->net_lnd->lnd_query); > > > > lnet_net_unlock(lp->lp_cpt); > > - ni->ni_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > > + ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > > lnet_net_lock(lp->lp_cpt); > > > > lp->lp_last_query = ktime_get_seconds(); > > @@ -1287,7 +1287,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > > info.mi_roffset = hdr->msg.put.offset; > > info.mi_mbits = hdr->msg.put.match_bits; > > > > - msg->msg_rx_ready_delay = !ni->ni_lnd->lnd_eager_recv; > > + msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > > ready_delay = msg->msg_rx_ready_delay; > > > > again: > > @@ -1518,7 +1518,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) > > > > if (msg->msg_rxpeer->lp_rtrcredits <= 0 || > > lnet_msg2bufpool(msg)->rbp_credits <= 0) { > > - if (!ni->ni_lnd->lnd_eager_recv) { > > + if (!ni->ni_net->net_lnd->lnd_eager_recv) { > > msg->msg_rx_ready_delay = 1; > > } else { > > lnet_net_unlock(msg->msg_rx_cpt); > > diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c > > index eb14146bd879..8167980c2323 100644 > > --- a/drivers/staging/lustre/lnet/lnet/lo.c > > +++ b/drivers/staging/lustre/lnet/lnet/lo.c > > @@ -83,7 +83,7 @@ lolnd_shutdown(struct lnet_ni *ni) > > static int > > lolnd_startup(struct lnet_ni *ni) > > { > > - LASSERT(ni->ni_lnd == &the_lolnd); > > + LASSERT(ni->ni_net->net_lnd == &the_lolnd); > > LASSERT(!lolnd_instanced); > > lolnd_instanced = 1; > > > > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > > index 7d61c5d71426..0c0ec0b27982 100644 > > --- a/drivers/staging/lustre/lnet/lnet/router.c > > +++ b/drivers/staging/lustre/lnet/lnet/router.c > > @@ -154,14 +154,14 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > > lp->lp_notifylnd = 0; > > lp->lp_notify = 0; > > > > - if (notifylnd && ni->ni_lnd->lnd_notify) { > > + if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { > > lnet_net_unlock(lp->lp_cpt); > > > > /* > > * A new notification could happen now; I'll handle it > > * when control returns to me > > */ > > - ni->ni_lnd->lnd_notify(ni, lp->lp_nid, alive); > > + ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); > > > > lnet_net_lock(lp->lp_cpt); > > } > > @@ -380,8 +380,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > > lnet_net_unlock(LNET_LOCK_EX); > > > > /* XXX Assume alive */ > > - if (ni->ni_lnd->lnd_notify) > > - ni->ni_lnd->lnd_notify(ni, gateway, 1); > > + if (ni->ni_net->net_lnd->lnd_notify) > > + ni->ni_net->net_lnd->lnd_notify(ni, gateway, 1); > > > > lnet_net_lock(LNET_LOCK_EX); > > } > > @@ -818,7 +818,7 @@ lnet_update_ni_status_locked(void) > > > > now = ktime_get_real_seconds(); > > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > > - if (ni->ni_lnd->lnd_type == LOLND) > > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > > continue; > > > > if (now < ni->ni_last_alive + timeout) > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > > index 19cea7076057..f3ccd6a2b70e 100644 > > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > > @@ -674,7 +674,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > > last_alive = now - ni->ni_last_alive; > > > > /* @lo forever alive */ > > - if (ni->ni_lnd->lnd_type == LOLND) > > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > > last_alive = 0; > > > > lnet_ni_lock(ni); > > > > > > From jsimmons at infradead.org Mon Sep 10 23:19:37 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:19:37 +0100 (BST) Subject: [lustre-devel] [PATCH 03/34] lnet: struct lnet_ni: move ni_lnd to lnet_net In-Reply-To: <861CBCA6-75FF-4741-8507-00D891533522@cray.com> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137133.8267.15885218437939976879.stgit@noble> <861CBCA6-75FF-4741-8507-00D891533522@cray.com> Message-ID: > Is the gnilnd module being built upstream? Just as there were changes to o2iblnd.c and socklnd.c for this change, there should be a corresponding change to gnilnd.c. No gnilnd in th elinux kernel :-( > Doug > > > On Sep 6, 2018, at 5:49 PM, NeilBrown wrote: > > > > Also make some other minor changes to the structures. > > > > This is part of > > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > > LU-7734 lnet: Multi-Rail local NI split > > > > Signed-off-by: NeilBrown > > --- > > .../staging/lustre/include/linux/lnet/lib-types.h | 13 ++++++++----- > > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- > > drivers/staging/lustre/lnet/lnet/acceptor.c | 4 ++-- > > drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++-------- > > drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- > > drivers/staging/lustre/lnet/lnet/lo.c | 2 +- > > drivers/staging/lustre/lnet/lnet/router.c | 10 +++++----- > > drivers/staging/lustre/lnet/lnet/router_proc.c | 2 +- > > 9 files changed, 35 insertions(+), 32 deletions(-) > > > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > > index ead8a4e1125a..e170eb07a5bf 100644 > > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > > @@ -262,12 +262,17 @@ struct lnet_net { > > * shouldn't be reset > > */ > > bool net_tunables_set; > > + /* procedural interface */ > > + struct lnet_lnd *net_lnd; > > }; > > > > struct lnet_ni { > > - spinlock_t ni_lock; > > - struct list_head ni_list; /* chain on ln_nis */ > > - struct list_head ni_cptlist; /* chain on ln_nis_cpt */ > > + /* chain on ln_nis */ > > + struct list_head ni_list; > > + /* chain on ln_nis_cpt */ > > + struct list_head ni_cptlist; > > + > > + spinlock_t ni_lock; > > > > /* number of CPTs */ > > int ni_ncpts; > > @@ -281,8 +286,6 @@ struct lnet_ni { > > /* instance-specific data */ > > void *ni_data; > > > > - struct lnet_lnd *ni_lnd; /* procedural interface */ > > - > > /* percpt TX queues */ > > struct lnet_tx_queue **ni_tx_queues; > > > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > index 0d17e22c4401..5e1592b398c1 100644 > > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > @@ -2830,7 +2830,7 @@ static int kiblnd_startup(struct lnet_ni *ni) > > int rc; > > int newdev; > > > > - LASSERT(ni->ni_lnd == &the_o2iblnd); > > + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); > > > > if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { > > rc = kiblnd_base_startup(); > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > index 4ad885f10235..2036a0ae5917 100644 > > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > @@ -2726,7 +2726,7 @@ ksocknal_startup(struct lnet_ni *ni) > > int rc; > > int i; > > > > - LASSERT(ni->ni_lnd == &the_ksocklnd); > > + LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); > > > > if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) { > > rc = ksocknal_base_startup(); > > diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c > > index 3ae3ca1311a1..f8c921f0221c 100644 > > --- a/drivers/staging/lustre/lnet/lnet/acceptor.c > > +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c > > @@ -306,7 +306,7 @@ lnet_accept(struct socket *sock, __u32 magic) > > return -EPERM; > > } > > > > - if (!ni->ni_lnd->lnd_accept) { > > + if (!ni->ni_net->net_lnd->lnd_accept) { > > /* This catches a request for the loopback LND */ > > lnet_ni_decref(ni); > > LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", > > @@ -317,7 +317,7 @@ lnet_accept(struct socket *sock, __u32 magic) > > CDEBUG(D_NET, "Accept %s from %pI4h\n", > > libcfs_nid2str(cr.acr_nid), &peer_ip); > > > > - rc = ni->ni_lnd->lnd_accept(ni, sock); > > + rc = ni->ni_net->net_lnd->lnd_accept(ni, sock); > > > > lnet_ni_decref(ni); > > return rc; > > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > > index cd4189fa7acb..0896e75bc3d7 100644 > > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > > @@ -799,7 +799,7 @@ lnet_count_acceptor_nis(void) > > > > cpt = lnet_net_lock_current(); > > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > > - if (ni->ni_lnd->lnd_accept) > > + if (ni->ni_net->net_lnd->lnd_accept) > > count++; > > } > > > > @@ -1098,13 +1098,13 @@ lnet_clear_zombies_nis_locked(void) > > continue; > > } > > > > - ni->ni_lnd->lnd_refcount--; > > + ni->ni_net->net_lnd->lnd_refcount--; > > lnet_net_unlock(LNET_LOCK_EX); > > > > - islo = ni->ni_lnd->lnd_type == LOLND; > > + islo = ni->ni_net->net_lnd->lnd_type == LOLND; > > > > LASSERT(!in_interrupt()); > > - ni->ni_lnd->lnd_shutdown(ni); > > + ni->ni_net->net_lnd->lnd_shutdown(ni); > > > > /* > > * can't deref lnd anymore now; it might have unregistered > > @@ -1248,7 +1248,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > > lnd->lnd_refcount++; > > lnet_net_unlock(LNET_LOCK_EX); > > > > - ni->ni_lnd = lnd; > > + ni->ni_net->net_lnd = lnd; > > > > if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) > > lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; > > @@ -1794,7 +1794,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > > if (rc) > > goto failed1; > > > > - if (ni->ni_lnd->lnd_accept) { > > + if (ni->ni_net->net_lnd->lnd_accept) { > > rc = lnet_acceptor_start(); > > if (rc < 0) { > > /* shutdown the ni that we just started */ > > @@ -2074,10 +2074,10 @@ LNetCtl(unsigned int cmd, void *arg) > > if (!ni) > > return -EINVAL; > > > > - if (!ni->ni_lnd->lnd_ctl) > > + if (!ni->ni_net->net_lnd->lnd_ctl) > > rc = -EINVAL; > > else > > - rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); > > + rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); > > > > lnet_ni_decref(ni); > > return rc; > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > > index f186e6a16d34..1bf12af87a20 100644 > > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > > @@ -406,7 +406,7 @@ lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, > > iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset); > > iov_iter_advance(&to, offset); > > } > > - rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > > + rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > > if (rc < 0) > > lnet_finalize(ni, msg, rc); > > } > > @@ -461,7 +461,7 @@ lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) > > LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || > > (msg->msg_txcredit && msg->msg_peertxcredit)); > > > > - rc = ni->ni_lnd->lnd_send(ni, priv, msg); > > + rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); > > if (rc < 0) > > lnet_finalize(ni, msg, rc); > > } > > @@ -474,10 +474,10 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) > > LASSERT(!msg->msg_sending); > > LASSERT(msg->msg_receiving); > > LASSERT(!msg->msg_rx_ready_delay); > > - LASSERT(ni->ni_lnd->lnd_eager_recv); > > + LASSERT(ni->ni_net->net_lnd->lnd_eager_recv); > > > > msg->msg_rx_ready_delay = 1; > > - rc = ni->ni_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > > + rc = ni->ni_net->net_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > > &msg->msg_private); > > if (rc) { > > CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", > > @@ -496,10 +496,10 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > > time64_t last_alive = 0; > > > > LASSERT(lnet_peer_aliveness_enabled(lp)); > > - LASSERT(ni->ni_lnd->lnd_query); > > + LASSERT(ni->ni_net->net_lnd->lnd_query); > > > > lnet_net_unlock(lp->lp_cpt); > > - ni->ni_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > > + ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > > lnet_net_lock(lp->lp_cpt); > > > > lp->lp_last_query = ktime_get_seconds(); > > @@ -1287,7 +1287,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > > info.mi_roffset = hdr->msg.put.offset; > > info.mi_mbits = hdr->msg.put.match_bits; > > > > - msg->msg_rx_ready_delay = !ni->ni_lnd->lnd_eager_recv; > > + msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > > ready_delay = msg->msg_rx_ready_delay; > > > > again: > > @@ -1518,7 +1518,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) > > > > if (msg->msg_rxpeer->lp_rtrcredits <= 0 || > > lnet_msg2bufpool(msg)->rbp_credits <= 0) { > > - if (!ni->ni_lnd->lnd_eager_recv) { > > + if (!ni->ni_net->net_lnd->lnd_eager_recv) { > > msg->msg_rx_ready_delay = 1; > > } else { > > lnet_net_unlock(msg->msg_rx_cpt); > > diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c > > index eb14146bd879..8167980c2323 100644 > > --- a/drivers/staging/lustre/lnet/lnet/lo.c > > +++ b/drivers/staging/lustre/lnet/lnet/lo.c > > @@ -83,7 +83,7 @@ lolnd_shutdown(struct lnet_ni *ni) > > static int > > lolnd_startup(struct lnet_ni *ni) > > { > > - LASSERT(ni->ni_lnd == &the_lolnd); > > + LASSERT(ni->ni_net->net_lnd == &the_lolnd); > > LASSERT(!lolnd_instanced); > > lolnd_instanced = 1; > > > > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > > index 7d61c5d71426..0c0ec0b27982 100644 > > --- a/drivers/staging/lustre/lnet/lnet/router.c > > +++ b/drivers/staging/lustre/lnet/lnet/router.c > > @@ -154,14 +154,14 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > > lp->lp_notifylnd = 0; > > lp->lp_notify = 0; > > > > - if (notifylnd && ni->ni_lnd->lnd_notify) { > > + if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { > > lnet_net_unlock(lp->lp_cpt); > > > > /* > > * A new notification could happen now; I'll handle it > > * when control returns to me > > */ > > - ni->ni_lnd->lnd_notify(ni, lp->lp_nid, alive); > > + ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); > > > > lnet_net_lock(lp->lp_cpt); > > } > > @@ -380,8 +380,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > > lnet_net_unlock(LNET_LOCK_EX); > > > > /* XXX Assume alive */ > > - if (ni->ni_lnd->lnd_notify) > > - ni->ni_lnd->lnd_notify(ni, gateway, 1); > > + if (ni->ni_net->net_lnd->lnd_notify) > > + ni->ni_net->net_lnd->lnd_notify(ni, gateway, 1); > > > > lnet_net_lock(LNET_LOCK_EX); > > } > > @@ -818,7 +818,7 @@ lnet_update_ni_status_locked(void) > > > > now = ktime_get_real_seconds(); > > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > > - if (ni->ni_lnd->lnd_type == LOLND) > > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > > continue; > > > > if (now < ni->ni_last_alive + timeout) > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > > index 19cea7076057..f3ccd6a2b70e 100644 > > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > > @@ -674,7 +674,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > > last_alive = now - ni->ni_last_alive; > > > > /* @lo forever alive */ > > - if (ni->ni_lnd->lnd_type == LOLND) > > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > > last_alive = 0; > > > > lnet_ni_lock(ni); > > > > > > From doucharek at cray.com Mon Sep 10 23:19:59 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:19:59 +0000 Subject: [lustre-devel] [PATCH 03/34] lnet: struct lnet_ni: move ni_lnd to lnet_net In-Reply-To: References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137133.8267.15885218437939976879.stgit@noble> <861CBCA6-75FF-4741-8507-00D891533522@cray.com> Message-ID: Ok. I will ignore gnilnd in my review. Doug > On Sep 10, 2018, at 4:19 PM, James Simmons wrote: > > >> Is the gnilnd module being built upstream? Just as there were changes to o2iblnd.c and socklnd.c for this change, there should be a corresponding change to gnilnd.c. > > No gnilnd in th elinux kernel :-( > > >> Doug >> >>> On Sep 6, 2018, at 5:49 PM, NeilBrown wrote: >>> >>> Also make some other minor changes to the structures. >>> >>> This is part of >>> 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 >>> LU-7734 lnet: Multi-Rail local NI split >>> >>> Signed-off-by: NeilBrown >>> --- >>> .../staging/lustre/include/linux/lnet/lib-types.h | 13 ++++++++----- >>> .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- >>> .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- >>> drivers/staging/lustre/lnet/lnet/acceptor.c | 4 ++-- >>> drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++-------- >>> drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- >>> drivers/staging/lustre/lnet/lnet/lo.c | 2 +- >>> drivers/staging/lustre/lnet/lnet/router.c | 10 +++++----- >>> drivers/staging/lustre/lnet/lnet/router_proc.c | 2 +- >>> 9 files changed, 35 insertions(+), 32 deletions(-) >>> >>> diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h >>> index ead8a4e1125a..e170eb07a5bf 100644 >>> --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h >>> +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h >>> @@ -262,12 +262,17 @@ struct lnet_net { >>> * shouldn't be reset >>> */ >>> bool net_tunables_set; >>> + /* procedural interface */ >>> + struct lnet_lnd *net_lnd; >>> }; >>> >>> struct lnet_ni { >>> - spinlock_t ni_lock; >>> - struct list_head ni_list; /* chain on ln_nis */ >>> - struct list_head ni_cptlist; /* chain on ln_nis_cpt */ >>> + /* chain on ln_nis */ >>> + struct list_head ni_list; >>> + /* chain on ln_nis_cpt */ >>> + struct list_head ni_cptlist; >>> + >>> + spinlock_t ni_lock; >>> >>> /* number of CPTs */ >>> int ni_ncpts; >>> @@ -281,8 +286,6 @@ struct lnet_ni { >>> /* instance-specific data */ >>> void *ni_data; >>> >>> - struct lnet_lnd *ni_lnd; /* procedural interface */ >>> - >>> /* percpt TX queues */ >>> struct lnet_tx_queue **ni_tx_queues; >>> >>> diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c >>> index 0d17e22c4401..5e1592b398c1 100644 >>> --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c >>> +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c >>> @@ -2830,7 +2830,7 @@ static int kiblnd_startup(struct lnet_ni *ni) >>> int rc; >>> int newdev; >>> >>> - LASSERT(ni->ni_lnd == &the_o2iblnd); >>> + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); >>> >>> if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { >>> rc = kiblnd_base_startup(); >>> diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c >>> index 4ad885f10235..2036a0ae5917 100644 >>> --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c >>> +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c >>> @@ -2726,7 +2726,7 @@ ksocknal_startup(struct lnet_ni *ni) >>> int rc; >>> int i; >>> >>> - LASSERT(ni->ni_lnd == &the_ksocklnd); >>> + LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); >>> >>> if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) { >>> rc = ksocknal_base_startup(); >>> diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c >>> index 3ae3ca1311a1..f8c921f0221c 100644 >>> --- a/drivers/staging/lustre/lnet/lnet/acceptor.c >>> +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c >>> @@ -306,7 +306,7 @@ lnet_accept(struct socket *sock, __u32 magic) >>> return -EPERM; >>> } >>> >>> - if (!ni->ni_lnd->lnd_accept) { >>> + if (!ni->ni_net->net_lnd->lnd_accept) { >>> /* This catches a request for the loopback LND */ >>> lnet_ni_decref(ni); >>> LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", >>> @@ -317,7 +317,7 @@ lnet_accept(struct socket *sock, __u32 magic) >>> CDEBUG(D_NET, "Accept %s from %pI4h\n", >>> libcfs_nid2str(cr.acr_nid), &peer_ip); >>> >>> - rc = ni->ni_lnd->lnd_accept(ni, sock); >>> + rc = ni->ni_net->net_lnd->lnd_accept(ni, sock); >>> >>> lnet_ni_decref(ni); >>> return rc; >>> diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c >>> index cd4189fa7acb..0896e75bc3d7 100644 >>> --- a/drivers/staging/lustre/lnet/lnet/api-ni.c >>> +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c >>> @@ -799,7 +799,7 @@ lnet_count_acceptor_nis(void) >>> >>> cpt = lnet_net_lock_current(); >>> list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { >>> - if (ni->ni_lnd->lnd_accept) >>> + if (ni->ni_net->net_lnd->lnd_accept) >>> count++; >>> } >>> >>> @@ -1098,13 +1098,13 @@ lnet_clear_zombies_nis_locked(void) >>> continue; >>> } >>> >>> - ni->ni_lnd->lnd_refcount--; >>> + ni->ni_net->net_lnd->lnd_refcount--; >>> lnet_net_unlock(LNET_LOCK_EX); >>> >>> - islo = ni->ni_lnd->lnd_type == LOLND; >>> + islo = ni->ni_net->net_lnd->lnd_type == LOLND; >>> >>> LASSERT(!in_interrupt()); >>> - ni->ni_lnd->lnd_shutdown(ni); >>> + ni->ni_net->net_lnd->lnd_shutdown(ni); >>> >>> /* >>> * can't deref lnd anymore now; it might have unregistered >>> @@ -1248,7 +1248,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) >>> lnd->lnd_refcount++; >>> lnet_net_unlock(LNET_LOCK_EX); >>> >>> - ni->ni_lnd = lnd; >>> + ni->ni_net->net_lnd = lnd; >>> >>> if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) >>> lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; >>> @@ -1794,7 +1794,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) >>> if (rc) >>> goto failed1; >>> >>> - if (ni->ni_lnd->lnd_accept) { >>> + if (ni->ni_net->net_lnd->lnd_accept) { >>> rc = lnet_acceptor_start(); >>> if (rc < 0) { >>> /* shutdown the ni that we just started */ >>> @@ -2074,10 +2074,10 @@ LNetCtl(unsigned int cmd, void *arg) >>> if (!ni) >>> return -EINVAL; >>> >>> - if (!ni->ni_lnd->lnd_ctl) >>> + if (!ni->ni_net->net_lnd->lnd_ctl) >>> rc = -EINVAL; >>> else >>> - rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); >>> + rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); >>> >>> lnet_ni_decref(ni); >>> return rc; >>> diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c >>> index f186e6a16d34..1bf12af87a20 100644 >>> --- a/drivers/staging/lustre/lnet/lnet/lib-move.c >>> +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c >>> @@ -406,7 +406,7 @@ lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, >>> iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset); >>> iov_iter_advance(&to, offset); >>> } >>> - rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); >>> + rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); >>> if (rc < 0) >>> lnet_finalize(ni, msg, rc); >>> } >>> @@ -461,7 +461,7 @@ lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) >>> LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || >>> (msg->msg_txcredit && msg->msg_peertxcredit)); >>> >>> - rc = ni->ni_lnd->lnd_send(ni, priv, msg); >>> + rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); >>> if (rc < 0) >>> lnet_finalize(ni, msg, rc); >>> } >>> @@ -474,10 +474,10 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) >>> LASSERT(!msg->msg_sending); >>> LASSERT(msg->msg_receiving); >>> LASSERT(!msg->msg_rx_ready_delay); >>> - LASSERT(ni->ni_lnd->lnd_eager_recv); >>> + LASSERT(ni->ni_net->net_lnd->lnd_eager_recv); >>> >>> msg->msg_rx_ready_delay = 1; >>> - rc = ni->ni_lnd->lnd_eager_recv(ni, msg->msg_private, msg, >>> + rc = ni->ni_net->net_lnd->lnd_eager_recv(ni, msg->msg_private, msg, >>> &msg->msg_private); >>> if (rc) { >>> CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", >>> @@ -496,10 +496,10 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) >>> time64_t last_alive = 0; >>> >>> LASSERT(lnet_peer_aliveness_enabled(lp)); >>> - LASSERT(ni->ni_lnd->lnd_query); >>> + LASSERT(ni->ni_net->net_lnd->lnd_query); >>> >>> lnet_net_unlock(lp->lp_cpt); >>> - ni->ni_lnd->lnd_query(ni, lp->lp_nid, &last_alive); >>> + ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); >>> lnet_net_lock(lp->lp_cpt); >>> >>> lp->lp_last_query = ktime_get_seconds(); >>> @@ -1287,7 +1287,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) >>> info.mi_roffset = hdr->msg.put.offset; >>> info.mi_mbits = hdr->msg.put.match_bits; >>> >>> - msg->msg_rx_ready_delay = !ni->ni_lnd->lnd_eager_recv; >>> + msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; >>> ready_delay = msg->msg_rx_ready_delay; >>> >>> again: >>> @@ -1518,7 +1518,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) >>> >>> if (msg->msg_rxpeer->lp_rtrcredits <= 0 || >>> lnet_msg2bufpool(msg)->rbp_credits <= 0) { >>> - if (!ni->ni_lnd->lnd_eager_recv) { >>> + if (!ni->ni_net->net_lnd->lnd_eager_recv) { >>> msg->msg_rx_ready_delay = 1; >>> } else { >>> lnet_net_unlock(msg->msg_rx_cpt); >>> diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c >>> index eb14146bd879..8167980c2323 100644 >>> --- a/drivers/staging/lustre/lnet/lnet/lo.c >>> +++ b/drivers/staging/lustre/lnet/lnet/lo.c >>> @@ -83,7 +83,7 @@ lolnd_shutdown(struct lnet_ni *ni) >>> static int >>> lolnd_startup(struct lnet_ni *ni) >>> { >>> - LASSERT(ni->ni_lnd == &the_lolnd); >>> + LASSERT(ni->ni_net->net_lnd == &the_lolnd); >>> LASSERT(!lolnd_instanced); >>> lolnd_instanced = 1; >>> >>> diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c >>> index 7d61c5d71426..0c0ec0b27982 100644 >>> --- a/drivers/staging/lustre/lnet/lnet/router.c >>> +++ b/drivers/staging/lustre/lnet/lnet/router.c >>> @@ -154,14 +154,14 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) >>> lp->lp_notifylnd = 0; >>> lp->lp_notify = 0; >>> >>> - if (notifylnd && ni->ni_lnd->lnd_notify) { >>> + if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { >>> lnet_net_unlock(lp->lp_cpt); >>> >>> /* >>> * A new notification could happen now; I'll handle it >>> * when control returns to me >>> */ >>> - ni->ni_lnd->lnd_notify(ni, lp->lp_nid, alive); >>> + ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); >>> >>> lnet_net_lock(lp->lp_cpt); >>> } >>> @@ -380,8 +380,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, >>> lnet_net_unlock(LNET_LOCK_EX); >>> >>> /* XXX Assume alive */ >>> - if (ni->ni_lnd->lnd_notify) >>> - ni->ni_lnd->lnd_notify(ni, gateway, 1); >>> + if (ni->ni_net->net_lnd->lnd_notify) >>> + ni->ni_net->net_lnd->lnd_notify(ni, gateway, 1); >>> >>> lnet_net_lock(LNET_LOCK_EX); >>> } >>> @@ -818,7 +818,7 @@ lnet_update_ni_status_locked(void) >>> >>> now = ktime_get_real_seconds(); >>> list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { >>> - if (ni->ni_lnd->lnd_type == LOLND) >>> + if (ni->ni_net->net_lnd->lnd_type == LOLND) >>> continue; >>> >>> if (now < ni->ni_last_alive + timeout) >>> diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c >>> index 19cea7076057..f3ccd6a2b70e 100644 >>> --- a/drivers/staging/lustre/lnet/lnet/router_proc.c >>> +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c >>> @@ -674,7 +674,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, >>> last_alive = now - ni->ni_last_alive; >>> >>> /* @lo forever alive */ >>> - if (ni->ni_lnd->lnd_type == LOLND) >>> + if (ni->ni_net->net_lnd->lnd_type == LOLND) >>> last_alive = 0; >>> >>> lnet_ni_lock(ni); >>> >>> >> >> From jsimmons at infradead.org Mon Sep 10 23:23:49 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:23:49 +0100 (BST) Subject: [lustre-devel] [PATCH 02/34] lnet: Create struct lnet_net In-Reply-To: <153628137129.8267.345070695068208597.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137129.8267.345070695068208597.stgit@noble> Message-ID: > This will contain some fields from lnet_ni, to be shared > between multiple ni on the one network. > > For now, only tunables are moved across, using > struct lnet_ioctl_config_lnd_cmn_tunables > which is changed to use signed values so -1 can be stored. > -1 means "no value" > If the tunables haven't been initialised, then net_tunables_set is > false. Previously a NULL pointer had this meaning. > > A 'struct lnet_net' is allocated as part of lnet_ni_alloc(), and freed > by lnet_ni_free(). Acked-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 25 ++++++-- > .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 8 +-- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 - > .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 61 +++++++++++--------- > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 19 ++++-- > drivers/staging/lustre/lnet/lnet/api-ni.c | 45 +++++++++------ > drivers/staging/lustre/lnet/lnet/config.c | 24 ++++++-- > drivers/staging/lustre/lnet/lnet/lib-move.c | 5 +- > drivers/staging/lustre/lnet/lnet/peer.c | 9 ++- > drivers/staging/lustre/lnet/lnet/router.c | 8 ++- > drivers/staging/lustre/lnet/lnet/router_proc.c | 6 +- > 11 files changed, 129 insertions(+), 83 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 078bc97a9ebf..ead8a4e1125a 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -43,6 +43,7 @@ > > #include > #include > +#include > > /* Max payload size */ > #define LNET_MAX_PAYLOAD CONFIG_LNET_MAX_PAYLOAD > @@ -252,17 +253,22 @@ struct lnet_tx_queue { > struct list_head tq_delayed; /* delayed TXs */ > }; > > +struct lnet_net { > + /* network tunables */ > + struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; > + > + /* > + * boolean to indicate that the tunables have been set and > + * shouldn't be reset > + */ > + bool net_tunables_set; > +}; > + > struct lnet_ni { > spinlock_t ni_lock; > struct list_head ni_list; /* chain on ln_nis */ > struct list_head ni_cptlist; /* chain on ln_nis_cpt */ > - int ni_maxtxcredits; /* # tx credits */ > - /* # per-peer send credits */ > - int ni_peertxcredits; > - /* # per-peer router buffer credits */ > - int ni_peerrtrcredits; > - /* seconds to consider peer dead */ > - int ni_peertimeout; > + > /* number of CPTs */ > int ni_ncpts; > > @@ -286,6 +292,9 @@ struct lnet_ni { > /* when I was last alive */ > time64_t ni_last_alive; > > + /* pointer to parent network */ > + struct lnet_net *ni_net; > + > /* my health status */ > struct lnet_ni_status *ni_status; > > @@ -397,7 +406,7 @@ struct lnet_peer_table { > * lnet_ni::ni_peertimeout has been set to a positive value > */ > #define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing && \ > - (lp)->lp_ni->ni_peertimeout > 0) > + (lp)->lp_ni->ni_net->net_tunables.lct_peer_timeout > 0) > > struct lnet_route { > struct list_head lr_list; /* chain on net */ > diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h > index c1619f411d81..a8eb3b8f9fd7 100644 > --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h > +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h > @@ -39,10 +39,10 @@ > > struct lnet_ioctl_config_lnd_cmn_tunables { > __u32 lct_version; > - __u32 lct_peer_timeout; > - __u32 lct_peer_tx_credits; > - __u32 lct_peer_rtr_credits; > - __u32 lct_max_tx_credits; > + __s32 lct_peer_timeout; > + __s32 lct_peer_tx_credits; > + __s32 lct_peer_rtr_credits; > + __s32 lct_max_tx_credits; > }; > > struct lnet_ioctl_config_o2iblnd_tunables { > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index f496e6fcc416..0d17e22c4401 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -337,7 +337,7 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, > peer->ibp_error = 0; > peer->ibp_last_alive = 0; > peer->ibp_max_frags = kiblnd_cfg_rdma_frags(peer->ibp_ni); > - peer->ibp_queue_depth = ni->ni_peertxcredits; > + peer->ibp_queue_depth = ni->ni_net->net_tunables.lct_peer_tx_credits; > atomic_set(&peer->ibp_refcount, 1); /* 1 ref for caller */ > > INIT_LIST_HEAD(&peer->ibp_list); /* not in the peer table yet */ > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c > index 39d07926d603..a1aca4dda38f 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c > @@ -171,7 +171,7 @@ int kiblnd_msg_queue_size(int version, struct lnet_ni *ni) > if (version == IBLND_MSG_VERSION_1) > return IBLND_MSG_QUEUE_SIZE_V1; > else if (ni) > - return ni->ni_peertxcredits; > + return ni->ni_net->net_tunables.lct_peer_tx_credits; > else > return peer_credits; > } > @@ -179,6 +179,7 @@ int kiblnd_msg_queue_size(int version, struct lnet_ni *ni) > int kiblnd_tunables_setup(struct lnet_ni *ni) > { > struct lnet_ioctl_config_o2iblnd_tunables *tunables; > + struct lnet_ioctl_config_lnd_cmn_tunables *net_tunables; > > /* > * if there was no tunables specified, setup the tunables to be > @@ -204,35 +205,39 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) > return -EINVAL; > } > > - if (!ni->ni_peertimeout) > - ni->ni_peertimeout = peer_timeout; > + net_tunables = &ni->ni_net->net_tunables; > > - if (!ni->ni_maxtxcredits) > - ni->ni_maxtxcredits = credits; > + if (net_tunables->lct_peer_timeout == -1) > + net_tunables->lct_peer_timeout = peer_timeout; > > - if (!ni->ni_peertxcredits) > - ni->ni_peertxcredits = peer_credits; > + if (net_tunables->lct_max_tx_credits == -1) > + net_tunables->lct_max_tx_credits = credits; > > - if (!ni->ni_peerrtrcredits) > - ni->ni_peerrtrcredits = peer_buffer_credits; > + if (net_tunables->lct_peer_tx_credits == -1) > + net_tunables->lct_peer_tx_credits = peer_credits; > > - if (ni->ni_peertxcredits < IBLND_CREDITS_DEFAULT) > - ni->ni_peertxcredits = IBLND_CREDITS_DEFAULT; > + if (net_tunables->lct_peer_rtr_credits == -1) > + net_tunables->lct_peer_rtr_credits = peer_buffer_credits; > > - if (ni->ni_peertxcredits > IBLND_CREDITS_MAX) > - ni->ni_peertxcredits = IBLND_CREDITS_MAX; > + if (net_tunables->lct_peer_tx_credits < IBLND_CREDITS_DEFAULT) > + net_tunables->lct_peer_tx_credits = IBLND_CREDITS_DEFAULT; > > - if (ni->ni_peertxcredits > credits) > - ni->ni_peertxcredits = credits; > + if (net_tunables->lct_peer_tx_credits > IBLND_CREDITS_MAX) > + net_tunables->lct_peer_tx_credits = IBLND_CREDITS_MAX; > + > + if (net_tunables->lct_peer_tx_credits > > + net_tunables->lct_max_tx_credits) > + net_tunables->lct_peer_tx_credits = > + net_tunables->lct_max_tx_credits; > > if (!tunables->lnd_peercredits_hiw) > tunables->lnd_peercredits_hiw = peer_credits_hiw; > > - if (tunables->lnd_peercredits_hiw < ni->ni_peertxcredits / 2) > - tunables->lnd_peercredits_hiw = ni->ni_peertxcredits / 2; > + if (tunables->lnd_peercredits_hiw < net_tunables->lct_peer_tx_credits / 2) > + tunables->lnd_peercredits_hiw = net_tunables->lct_peer_tx_credits / 2; > > - if (tunables->lnd_peercredits_hiw >= ni->ni_peertxcredits) > - tunables->lnd_peercredits_hiw = ni->ni_peertxcredits - 1; > + if (tunables->lnd_peercredits_hiw >= net_tunables->lct_peer_tx_credits) > + tunables->lnd_peercredits_hiw = net_tunables->lct_peer_tx_credits - 1; > > if (tunables->lnd_map_on_demand <= 0 || > tunables->lnd_map_on_demand > IBLND_MAX_RDMA_FRAGS) { > @@ -252,21 +257,23 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) > if (tunables->lnd_map_on_demand > 0 && > tunables->lnd_map_on_demand <= IBLND_MAX_RDMA_FRAGS / 8) { > tunables->lnd_concurrent_sends = > - ni->ni_peertxcredits * 2; > + net_tunables->lct_peer_tx_credits * 2; > } else { > - tunables->lnd_concurrent_sends = ni->ni_peertxcredits; > + tunables->lnd_concurrent_sends = > + net_tunables->lct_peer_tx_credits; > } > } > > - if (tunables->lnd_concurrent_sends > ni->ni_peertxcredits * 2) > - tunables->lnd_concurrent_sends = ni->ni_peertxcredits * 2; > + if (tunables->lnd_concurrent_sends > net_tunables->lct_peer_tx_credits * 2) > + tunables->lnd_concurrent_sends = net_tunables->lct_peer_tx_credits * 2; > > - if (tunables->lnd_concurrent_sends < ni->ni_peertxcredits / 2) > - tunables->lnd_concurrent_sends = ni->ni_peertxcredits / 2; > + if (tunables->lnd_concurrent_sends < net_tunables->lct_peer_tx_credits / 2) > + tunables->lnd_concurrent_sends = net_tunables->lct_peer_tx_credits / 2; > > - if (tunables->lnd_concurrent_sends < ni->ni_peertxcredits) { > + if (tunables->lnd_concurrent_sends < net_tunables->lct_peer_tx_credits) { > CWARN("Concurrent sends %d is lower than message queue size: %d, performance may drop slightly.\n", > - tunables->lnd_concurrent_sends, ni->ni_peertxcredits); > + tunables->lnd_concurrent_sends, > + net_tunables->lct_peer_tx_credits); > } > > if (!tunables->lnd_fmr_pool_size) > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 4dde158451ea..4ad885f10235 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -2739,12 +2739,19 @@ ksocknal_startup(struct lnet_ni *ni) > goto fail_0; > > spin_lock_init(&net->ksnn_lock); > - net->ksnn_incarnation = ktime_get_real_ns(); > - ni->ni_data = net; > - ni->ni_peertimeout = *ksocknal_tunables.ksnd_peertimeout; > - ni->ni_maxtxcredits = *ksocknal_tunables.ksnd_credits; > - ni->ni_peertxcredits = *ksocknal_tunables.ksnd_peertxcredits; > - ni->ni_peerrtrcredits = *ksocknal_tunables.ksnd_peerrtrcredits; > + net->ksnn_incarnation = ktime_get_real_ns(); > + ni->ni_data = net; > + if (!ni->ni_net->net_tunables_set) { > + ni->ni_net->net_tunables.lct_peer_timeout = > + *ksocknal_tunables.ksnd_peertimeout; > + ni->ni_net->net_tunables.lct_max_tx_credits = > + *ksocknal_tunables.ksnd_credits; > + ni->ni_net->net_tunables.lct_peer_tx_credits = > + *ksocknal_tunables.ksnd_peertxcredits; > + ni->ni_net->net_tunables.lct_peer_rtr_credits = > + *ksocknal_tunables.ksnd_peerrtrcredits; > + ni->ni_net->net_tunables_set = true; > + } > > net->ksnn_ninterfaces = 0; > if (!ni->ni_interfaces[0]) { > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index f9fcce2a5643..cd4189fa7acb 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -1036,11 +1036,11 @@ lnet_ni_tq_credits(struct lnet_ni *ni) > LASSERT(ni->ni_ncpts >= 1); > > if (ni->ni_ncpts == 1) > - return ni->ni_maxtxcredits; > + return ni->ni_net->net_tunables.lct_max_tx_credits; > > - credits = ni->ni_maxtxcredits / ni->ni_ncpts; > - credits = max(credits, 8 * ni->ni_peertxcredits); > - credits = min(credits, ni->ni_maxtxcredits); > + credits = ni->ni_net->net_tunables.lct_max_tx_credits / ni->ni_ncpts; > + credits = max(credits, 8 * ni->ni_net->net_tunables.lct_peer_tx_credits); > + credits = min(credits, ni->ni_net->net_tunables.lct_max_tx_credits); > > return credits; > } > @@ -1271,16 +1271,16 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > */ > if (conf) { > if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) > - ni->ni_peerrtrcredits = > + ni->ni_net->net_tunables.lct_peer_rtr_credits = > conf->cfg_config_u.cfg_net.net_peer_rtr_credits; > if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) > - ni->ni_peertimeout = > + ni->ni_net->net_tunables.lct_peer_timeout = > conf->cfg_config_u.cfg_net.net_peer_timeout; > if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) > - ni->ni_peertxcredits = > + ni->ni_net->net_tunables.lct_peer_tx_credits = > conf->cfg_config_u.cfg_net.net_peer_tx_credits; > if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) > - ni->ni_maxtxcredits = > + ni->ni_net->net_tunables.lct_max_tx_credits = > conf->cfg_config_u.cfg_net.net_max_tx_credits; > } > > @@ -1297,8 +1297,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > goto failed0; > } > > - LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query); > - > lnet_net_lock(LNET_LOCK_EX); > /* refcount for ln_nis */ > lnet_ni_addref_locked(ni, 0); > @@ -1314,13 +1312,18 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > lnet_ni_addref(ni); > LASSERT(!the_lnet.ln_loni); > the_lnet.ln_loni = ni; > + ni->ni_net->net_tunables.lct_peer_tx_credits = 0; > + ni->ni_net->net_tunables.lct_peer_rtr_credits = 0; > + ni->ni_net->net_tunables.lct_max_tx_credits = 0; > + ni->ni_net->net_tunables.lct_peer_timeout = 0; > return 0; > } > > - if (!ni->ni_peertxcredits || !ni->ni_maxtxcredits) { > + if (!ni->ni_net->net_tunables.lct_peer_tx_credits || > + !ni->ni_net->net_tunables.lct_max_tx_credits) { > LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n", > libcfs_lnd2str(lnd->lnd_type), > - !ni->ni_peertxcredits ? > + !ni->ni_net->net_tunables.lct_peer_tx_credits ? > "" : "per-peer "); > /* > * shutdown the NI since if we get here then it must've already > @@ -1343,9 +1346,11 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > add_device_randomness(&seed, sizeof(seed)); > > CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n", > - libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits, > + libcfs_nid2str(ni->ni_nid), > + ni->ni_net->net_tunables.lct_peer_tx_credits, > lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER, > - ni->ni_peerrtrcredits, ni->ni_peertimeout); > + ni->ni_net->net_tunables.lct_peer_rtr_credits, > + ni->ni_net->net_tunables.lct_peer_timeout); > > return 0; > failed0: > @@ -1667,10 +1672,14 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) > } > > config->cfg_nid = ni->ni_nid; > - config->cfg_config_u.cfg_net.net_peer_timeout = ni->ni_peertimeout; > - config->cfg_config_u.cfg_net.net_max_tx_credits = ni->ni_maxtxcredits; > - config->cfg_config_u.cfg_net.net_peer_tx_credits = ni->ni_peertxcredits; > - config->cfg_config_u.cfg_net.net_peer_rtr_credits = ni->ni_peerrtrcredits; > + config->cfg_config_u.cfg_net.net_peer_timeout = > + ni->ni_net->net_tunables.lct_peer_timeout; > + config->cfg_config_u.cfg_net.net_max_tx_credits = > + ni->ni_net->net_tunables.lct_max_tx_credits; > + config->cfg_config_u.cfg_net.net_peer_tx_credits = > + ni->ni_net->net_tunables.lct_peer_tx_credits; > + config->cfg_config_u.cfg_net.net_peer_rtr_credits = > + ni->ni_net->net_tunables.lct_peer_rtr_credits; > > net_config->ni_status = ni->ni_status->ns_status; > > diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c > index 091c4f714e84..86a53854e427 100644 > --- a/drivers/staging/lustre/lnet/lnet/config.c > +++ b/drivers/staging/lustre/lnet/lnet/config.c > @@ -114,29 +114,38 @@ lnet_ni_free(struct lnet_ni *ni) > if (ni->ni_net_ns) > put_net(ni->ni_net_ns); > > + kvfree(ni->ni_net); > kfree(ni); > } > > struct lnet_ni * > -lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) > +lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > { > struct lnet_tx_queue *tq; > struct lnet_ni *ni; > int rc; > int i; > + struct lnet_net *net; > > - if (!lnet_net_unique(net, nilist)) { > + if (!lnet_net_unique(net_id, nilist)) { > LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", > - libcfs_net2str(net)); > + libcfs_net2str(net_id)); > return NULL; > } > > ni = kzalloc(sizeof(*ni), GFP_NOFS); > - if (!ni) { > + net = kzalloc(sizeof(*net), GFP_NOFS); > + if (!ni || !net) { > + kfree(ni); kfree(net); > CERROR("Out of memory creating network %s\n", > - libcfs_net2str(net)); > + libcfs_net2str(net_id)); > return NULL; > } > + /* initialize global paramters to undefiend */ > + net->net_tunables.lct_peer_timeout = -1; > + net->net_tunables.lct_max_tx_credits = -1; > + net->net_tunables.lct_peer_tx_credits = -1; > + net->net_tunables.lct_peer_rtr_credits = -1; > > spin_lock_init(&ni->ni_lock); > INIT_LIST_HEAD(&ni->ni_cptlist); > @@ -160,7 +169,7 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) > 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); > + libcfs_net2str(net_id), rc); > goto failed; > } > > @@ -173,8 +182,9 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) > ni->ni_ncpts = rc; > } > > + ni->ni_net = net; > /* LND will fill in the address part of the NID */ > - ni->ni_nid = LNET_MKNID(net, 0); > + ni->ni_nid = LNET_MKNID(net_id, 0); > > /* Store net namespace in which current ni is being created */ > if (current->nsproxy->net_ns) > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index edcafac055ed..f186e6a16d34 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -524,7 +524,8 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) > lp->lp_timestamp >= lp->lp_last_alive) > return 0; > > - deadline = lp->lp_last_alive + lp->lp_ni->ni_peertimeout; > + deadline = lp->lp_last_alive + > + lp->lp_ni->ni_net->net_tunables.lct_peer_timeout; > alive = deadline > now; > > /* Update obsolete lp_alive except for routers assumed to be dead > @@ -569,7 +570,7 @@ lnet_peer_alive_locked(struct lnet_peer *lp) > libcfs_nid2str(lp->lp_nid), > now, next_query, > lnet_queryinterval, > - lp->lp_ni->ni_peertimeout); > + lp->lp_ni->ni_net->net_tunables.lct_peer_timeout); > return 0; > } > } > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index d9452c322e4d..b76ac3e051d9 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -342,8 +342,8 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > goto out; > } > > - lp->lp_txcredits = lp->lp_ni->ni_peertxcredits; > - lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits; > + lp->lp_txcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > + lp->lp_mintxcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > lp->lp_rtrcredits = lnet_peer_buffer_credits(lp->lp_ni); > lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni); > > @@ -383,7 +383,7 @@ lnet_debug_peer(lnet_nid_t nid) > > CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", > libcfs_nid2str(lp->lp_nid), lp->lp_refcount, > - aliveness, lp->lp_ni->ni_peertxcredits, > + aliveness, lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits, > lp->lp_rtrcredits, lp->lp_minrtrcredits, > lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob); > > @@ -438,7 +438,8 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, > > *nid = lp->lp_nid; > *refcount = lp->lp_refcount; > - *ni_peer_tx_credits = lp->lp_ni->ni_peertxcredits; > + *ni_peer_tx_credits = > + lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > *peer_tx_credits = lp->lp_txcredits; > *peer_rtr_credits = lp->lp_rtrcredits; > *peer_min_rtr_credits = lp->lp_mintxcredits; > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 02241fbc9eaa..7d61c5d71426 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -57,9 +57,11 @@ MODULE_PARM_DESC(auto_down, "Automatically mark peers down on comms error"); > int > lnet_peer_buffer_credits(struct lnet_ni *ni) > { > + struct lnet_net *net = ni->ni_net; > + > /* NI option overrides LNet default */ > - if (ni->ni_peerrtrcredits > 0) > - return ni->ni_peerrtrcredits; > + if (net->net_tunables.lct_peer_rtr_credits > 0) > + return net->net_tunables.lct_peer_rtr_credits; > if (peer_buffer_credits > 0) > return peer_buffer_credits; > > @@ -67,7 +69,7 @@ lnet_peer_buffer_credits(struct lnet_ni *ni) > * As an approximation, allow this peer the same number of router > * buffers as it is allowed outstanding sends > */ > - return ni->ni_peertxcredits; > + return net->net_tunables.lct_peer_tx_credits; > } > > /* forward ref's */ > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 31f4982f7f17..19cea7076057 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -489,7 +489,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > int nrefs = peer->lp_refcount; > time64_t lastalive = -1; > char *aliveness = "NA"; > - int maxcr = peer->lp_ni->ni_peertxcredits; > + int maxcr = peer->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; > int txcr = peer->lp_txcredits; > int mintxcr = peer->lp_mintxcredits; > int rtrcr = peer->lp_rtrcredits; > @@ -704,8 +704,8 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > "%-24s %6s %5lld %4d %4d %4d %5d %5d %5d\n", > libcfs_nid2str(ni->ni_nid), stat, > last_alive, *ni->ni_refs[i], > - ni->ni_peertxcredits, > - ni->ni_peerrtrcredits, > + ni->ni_net->net_tunables.lct_peer_tx_credits, > + ni->ni_net->net_tunables.lct_peer_rtr_credits, > tq->tq_credits_max, > tq->tq_credits, > tq->tq_credits_min); > > > From doucharek at cray.com Mon Sep 10 23:24:11 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:24:11 +0000 Subject: [lustre-devel] [PATCH 06/34] lnet: store separate xmit/recv net-interface in each message. In-Reply-To: <153628137147.8267.3706504130592682241.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137147.8267.3706504130592682241.stgit@noble> Message-ID: <893D4121-C4E5-4FEF-8B9C-081615998706@cray.com> Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: Currently we store the net-interface in the peer, but the peer should identify just the network, not the particular interface. To help track which actual interface is used for each message, store them explicitly. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split and includes commit 63c3e5129873 ("LU-7734 lnet: Fix lnet_msg_free()") Signed-off-by: NeilBrown > --- .../staging/lustre/include/linux/lnet/lib-types.h | 3 +++ drivers/staging/lustre/lnet/lnet/lib-move.c | 21 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 5f0d4703bf86..16a493529a46 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -98,6 +98,9 @@ struct lnet_msg { void *msg_private; struct lnet_libmd *msg_md; + /* the NI the message was sent or received over */ + struct lnet_ni *msg_txni; + struct lnet_ni *msg_rxni; unsigned int msg_len; unsigned int msg_wanted; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 1c874025fa74..b2a52ddcefcb 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -782,6 +782,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) { struct lnet_peer *txpeer = msg->msg_txpeer; struct lnet_msg *msg2; + struct lnet_ni *txni = msg->msg_txni; if (msg->msg_txcredit) { struct lnet_ni *ni = txpeer->lp_ni; @@ -829,6 +830,11 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) } } + if (txni != NULL) { + msg->msg_txni = NULL; + lnet_ni_decref_locked(txni, msg->msg_tx_cpt); + } + if (txpeer) { msg->msg_txpeer = NULL; lnet_peer_decref_locked(txpeer); @@ -876,6 +882,7 @@ void lnet_return_rx_credits_locked(struct lnet_msg *msg) { struct lnet_peer *rxpeer = msg->msg_rxpeer; + struct lnet_ni *rxni = msg->msg_rxni; struct lnet_msg *msg2; if (msg->msg_rtrcredit) { @@ -951,6 +958,10 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) (void)lnet_post_routed_recv_locked(msg2, 1); } } + if (rxni != NULL) { + msg->msg_rxni = NULL; + lnet_ni_decref_locked(rxni, msg->msg_rx_cpt); + } if (rxpeer) { msg->msg_rxpeer = NULL; lnet_peer_decref_locked(rxpeer); @@ -1218,9 +1229,12 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) LASSERT(!msg->msg_peertxcredit); LASSERT(!msg->msg_txcredit); - LASSERT(!msg->msg_txpeer); + LASSERT(msg->msg_txpeer == NULL); - msg->msg_txpeer = lp; /* msg takes my ref on lp */ + msg->msg_txpeer = lp; /* msg takes my ref on lp */ + /* set the NI for this message */ + msg->msg_txni = src_ni; + lnet_ni_addref_locked(msg->msg_txni, cpt); rc = lnet_post_send_locked(msg, 0); lnet_net_unlock(cpt); @@ -1818,6 +1832,8 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, return 0; goto drop; } + msg->msg_rxni = ni; + lnet_ni_addref_locked(ni, cpt); if (lnet_isrouter(msg->msg_rxpeer)) { lnet_peer_set_alive(msg->msg_rxpeer); @@ -1934,6 +1950,7 @@ lnet_recv_delayed_msg_list(struct list_head *head) LASSERT(msg->msg_rx_delayed); LASSERT(msg->msg_md); LASSERT(msg->msg_rxpeer); + LASSERT(msg->msg_rxni); LASSERT(msg->msg_hdr.type == LNET_MSG_PUT); CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d match %llu offset %d length %d.\n", -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Mon Sep 10 23:24:28 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:24:28 +0100 (BST) Subject: [lustre-devel] [PATCH 03/34] lnet: struct lnet_ni: move ni_lnd to lnet_net In-Reply-To: <153628137133.8267.15885218437939976879.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137133.8267.15885218437939976879.stgit@noble> Message-ID: > Also make some other minor changes to the structures. > Acked-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 13 ++++++++----- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- > drivers/staging/lustre/lnet/lnet/acceptor.c | 4 ++-- > drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++-------- > drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- > drivers/staging/lustre/lnet/lnet/lo.c | 2 +- > drivers/staging/lustre/lnet/lnet/router.c | 10 +++++----- > drivers/staging/lustre/lnet/lnet/router_proc.c | 2 +- > 9 files changed, 35 insertions(+), 32 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index ead8a4e1125a..e170eb07a5bf 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -262,12 +262,17 @@ struct lnet_net { > * shouldn't be reset > */ > bool net_tunables_set; > + /* procedural interface */ > + struct lnet_lnd *net_lnd; > }; > > struct lnet_ni { > - spinlock_t ni_lock; > - struct list_head ni_list; /* chain on ln_nis */ > - struct list_head ni_cptlist; /* chain on ln_nis_cpt */ > + /* chain on ln_nis */ > + struct list_head ni_list; > + /* chain on ln_nis_cpt */ > + struct list_head ni_cptlist; > + > + spinlock_t ni_lock; > > /* number of CPTs */ > int ni_ncpts; > @@ -281,8 +286,6 @@ struct lnet_ni { > /* instance-specific data */ > void *ni_data; > > - struct lnet_lnd *ni_lnd; /* procedural interface */ > - > /* percpt TX queues */ > struct lnet_tx_queue **ni_tx_queues; > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index 0d17e22c4401..5e1592b398c1 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -2830,7 +2830,7 @@ static int kiblnd_startup(struct lnet_ni *ni) > int rc; > int newdev; > > - LASSERT(ni->ni_lnd == &the_o2iblnd); > + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); > > if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { > rc = kiblnd_base_startup(); > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 4ad885f10235..2036a0ae5917 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -2726,7 +2726,7 @@ ksocknal_startup(struct lnet_ni *ni) > int rc; > int i; > > - LASSERT(ni->ni_lnd == &the_ksocklnd); > + LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); > > if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) { > rc = ksocknal_base_startup(); > diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c > index 3ae3ca1311a1..f8c921f0221c 100644 > --- a/drivers/staging/lustre/lnet/lnet/acceptor.c > +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c > @@ -306,7 +306,7 @@ lnet_accept(struct socket *sock, __u32 magic) > return -EPERM; > } > > - if (!ni->ni_lnd->lnd_accept) { > + if (!ni->ni_net->net_lnd->lnd_accept) { > /* This catches a request for the loopback LND */ > lnet_ni_decref(ni); > LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", > @@ -317,7 +317,7 @@ lnet_accept(struct socket *sock, __u32 magic) > CDEBUG(D_NET, "Accept %s from %pI4h\n", > libcfs_nid2str(cr.acr_nid), &peer_ip); > > - rc = ni->ni_lnd->lnd_accept(ni, sock); > + rc = ni->ni_net->net_lnd->lnd_accept(ni, sock); > > lnet_ni_decref(ni); > return rc; > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index cd4189fa7acb..0896e75bc3d7 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -799,7 +799,7 @@ lnet_count_acceptor_nis(void) > > cpt = lnet_net_lock_current(); > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_lnd->lnd_accept) > + if (ni->ni_net->net_lnd->lnd_accept) > count++; > } > > @@ -1098,13 +1098,13 @@ lnet_clear_zombies_nis_locked(void) > continue; > } > > - ni->ni_lnd->lnd_refcount--; > + ni->ni_net->net_lnd->lnd_refcount--; > lnet_net_unlock(LNET_LOCK_EX); > > - islo = ni->ni_lnd->lnd_type == LOLND; > + islo = ni->ni_net->net_lnd->lnd_type == LOLND; > > LASSERT(!in_interrupt()); > - ni->ni_lnd->lnd_shutdown(ni); > + ni->ni_net->net_lnd->lnd_shutdown(ni); > > /* > * can't deref lnd anymore now; it might have unregistered > @@ -1248,7 +1248,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > lnd->lnd_refcount++; > lnet_net_unlock(LNET_LOCK_EX); > > - ni->ni_lnd = lnd; > + ni->ni_net->net_lnd = lnd; > > if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) > lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; > @@ -1794,7 +1794,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > if (rc) > goto failed1; > > - if (ni->ni_lnd->lnd_accept) { > + if (ni->ni_net->net_lnd->lnd_accept) { > rc = lnet_acceptor_start(); > if (rc < 0) { > /* shutdown the ni that we just started */ > @@ -2074,10 +2074,10 @@ LNetCtl(unsigned int cmd, void *arg) > if (!ni) > return -EINVAL; > > - if (!ni->ni_lnd->lnd_ctl) > + if (!ni->ni_net->net_lnd->lnd_ctl) > rc = -EINVAL; > else > - rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); > + rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); > > lnet_ni_decref(ni); > return rc; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index f186e6a16d34..1bf12af87a20 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -406,7 +406,7 @@ lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, > iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset); > iov_iter_advance(&to, offset); > } > - rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > + rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > if (rc < 0) > lnet_finalize(ni, msg, rc); > } > @@ -461,7 +461,7 @@ lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) > LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || > (msg->msg_txcredit && msg->msg_peertxcredit)); > > - rc = ni->ni_lnd->lnd_send(ni, priv, msg); > + rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); > if (rc < 0) > lnet_finalize(ni, msg, rc); > } > @@ -474,10 +474,10 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) > LASSERT(!msg->msg_sending); > LASSERT(msg->msg_receiving); > LASSERT(!msg->msg_rx_ready_delay); > - LASSERT(ni->ni_lnd->lnd_eager_recv); > + LASSERT(ni->ni_net->net_lnd->lnd_eager_recv); > > msg->msg_rx_ready_delay = 1; > - rc = ni->ni_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > + rc = ni->ni_net->net_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > &msg->msg_private); > if (rc) { > CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", > @@ -496,10 +496,10 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > time64_t last_alive = 0; > > LASSERT(lnet_peer_aliveness_enabled(lp)); > - LASSERT(ni->ni_lnd->lnd_query); > + LASSERT(ni->ni_net->net_lnd->lnd_query); > > lnet_net_unlock(lp->lp_cpt); > - ni->ni_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > + ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > lnet_net_lock(lp->lp_cpt); > > lp->lp_last_query = ktime_get_seconds(); > @@ -1287,7 +1287,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > info.mi_roffset = hdr->msg.put.offset; > info.mi_mbits = hdr->msg.put.match_bits; > > - msg->msg_rx_ready_delay = !ni->ni_lnd->lnd_eager_recv; > + msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > ready_delay = msg->msg_rx_ready_delay; > > again: > @@ -1518,7 +1518,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) > > if (msg->msg_rxpeer->lp_rtrcredits <= 0 || > lnet_msg2bufpool(msg)->rbp_credits <= 0) { > - if (!ni->ni_lnd->lnd_eager_recv) { > + if (!ni->ni_net->net_lnd->lnd_eager_recv) { > msg->msg_rx_ready_delay = 1; > } else { > lnet_net_unlock(msg->msg_rx_cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c > index eb14146bd879..8167980c2323 100644 > --- a/drivers/staging/lustre/lnet/lnet/lo.c > +++ b/drivers/staging/lustre/lnet/lnet/lo.c > @@ -83,7 +83,7 @@ lolnd_shutdown(struct lnet_ni *ni) > static int > lolnd_startup(struct lnet_ni *ni) > { > - LASSERT(ni->ni_lnd == &the_lolnd); > + LASSERT(ni->ni_net->net_lnd == &the_lolnd); > LASSERT(!lolnd_instanced); > lolnd_instanced = 1; > > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 7d61c5d71426..0c0ec0b27982 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -154,14 +154,14 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > lp->lp_notifylnd = 0; > lp->lp_notify = 0; > > - if (notifylnd && ni->ni_lnd->lnd_notify) { > + if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { > lnet_net_unlock(lp->lp_cpt); > > /* > * A new notification could happen now; I'll handle it > * when control returns to me > */ > - ni->ni_lnd->lnd_notify(ni, lp->lp_nid, alive); > + ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); > > lnet_net_lock(lp->lp_cpt); > } > @@ -380,8 +380,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > lnet_net_unlock(LNET_LOCK_EX); > > /* XXX Assume alive */ > - if (ni->ni_lnd->lnd_notify) > - ni->ni_lnd->lnd_notify(ni, gateway, 1); > + if (ni->ni_net->net_lnd->lnd_notify) > + ni->ni_net->net_lnd->lnd_notify(ni, gateway, 1); > > lnet_net_lock(LNET_LOCK_EX); > } > @@ -818,7 +818,7 @@ lnet_update_ni_status_locked(void) > > now = ktime_get_real_seconds(); > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_lnd->lnd_type == LOLND) > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > continue; > > if (now < ni->ni_last_alive + timeout) > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 19cea7076057..f3ccd6a2b70e 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -674,7 +674,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > last_alive = now - ni->ni_last_alive; > > /* @lo forever alive */ > - if (ni->ni_lnd->lnd_type == LOLND) > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > last_alive = 0; > > lnet_ni_lock(ni); > > > From jsimmons at infradead.org Mon Sep 10 23:25:24 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:25:24 +0100 (BST) Subject: [lustre-devel] [PATCH 03/34] lnet: struct lnet_ni: move ni_lnd to lnet_net In-Reply-To: <153628137133.8267.15885218437939976879.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137133.8267.15885218437939976879.stgit@noble> Message-ID: > Also make some other minor changes to the structures. > Reviewed-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 13 ++++++++----- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- > drivers/staging/lustre/lnet/lnet/acceptor.c | 4 ++-- > drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++-------- > drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++-------- > drivers/staging/lustre/lnet/lnet/lo.c | 2 +- > drivers/staging/lustre/lnet/lnet/router.c | 10 +++++----- > drivers/staging/lustre/lnet/lnet/router_proc.c | 2 +- > 9 files changed, 35 insertions(+), 32 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index ead8a4e1125a..e170eb07a5bf 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -262,12 +262,17 @@ struct lnet_net { > * shouldn't be reset > */ > bool net_tunables_set; > + /* procedural interface */ > + struct lnet_lnd *net_lnd; > }; > > struct lnet_ni { > - spinlock_t ni_lock; > - struct list_head ni_list; /* chain on ln_nis */ > - struct list_head ni_cptlist; /* chain on ln_nis_cpt */ > + /* chain on ln_nis */ > + struct list_head ni_list; > + /* chain on ln_nis_cpt */ > + struct list_head ni_cptlist; > + > + spinlock_t ni_lock; > > /* number of CPTs */ > int ni_ncpts; > @@ -281,8 +286,6 @@ struct lnet_ni { > /* instance-specific data */ > void *ni_data; > > - struct lnet_lnd *ni_lnd; /* procedural interface */ > - > /* percpt TX queues */ > struct lnet_tx_queue **ni_tx_queues; > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index 0d17e22c4401..5e1592b398c1 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -2830,7 +2830,7 @@ static int kiblnd_startup(struct lnet_ni *ni) > int rc; > int newdev; > > - LASSERT(ni->ni_lnd == &the_o2iblnd); > + LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); > > if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) { > rc = kiblnd_base_startup(); > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 4ad885f10235..2036a0ae5917 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -2726,7 +2726,7 @@ ksocknal_startup(struct lnet_ni *ni) > int rc; > int i; > > - LASSERT(ni->ni_lnd == &the_ksocklnd); > + LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); > > if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) { > rc = ksocknal_base_startup(); > diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c > index 3ae3ca1311a1..f8c921f0221c 100644 > --- a/drivers/staging/lustre/lnet/lnet/acceptor.c > +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c > @@ -306,7 +306,7 @@ lnet_accept(struct socket *sock, __u32 magic) > return -EPERM; > } > > - if (!ni->ni_lnd->lnd_accept) { > + if (!ni->ni_net->net_lnd->lnd_accept) { > /* This catches a request for the loopback LND */ > lnet_ni_decref(ni); > LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", > @@ -317,7 +317,7 @@ lnet_accept(struct socket *sock, __u32 magic) > CDEBUG(D_NET, "Accept %s from %pI4h\n", > libcfs_nid2str(cr.acr_nid), &peer_ip); > > - rc = ni->ni_lnd->lnd_accept(ni, sock); > + rc = ni->ni_net->net_lnd->lnd_accept(ni, sock); > > lnet_ni_decref(ni); > return rc; > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index cd4189fa7acb..0896e75bc3d7 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -799,7 +799,7 @@ lnet_count_acceptor_nis(void) > > cpt = lnet_net_lock_current(); > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_lnd->lnd_accept) > + if (ni->ni_net->net_lnd->lnd_accept) > count++; > } > > @@ -1098,13 +1098,13 @@ lnet_clear_zombies_nis_locked(void) > continue; > } > > - ni->ni_lnd->lnd_refcount--; > + ni->ni_net->net_lnd->lnd_refcount--; > lnet_net_unlock(LNET_LOCK_EX); > > - islo = ni->ni_lnd->lnd_type == LOLND; > + islo = ni->ni_net->net_lnd->lnd_type == LOLND; > > LASSERT(!in_interrupt()); > - ni->ni_lnd->lnd_shutdown(ni); > + ni->ni_net->net_lnd->lnd_shutdown(ni); > > /* > * can't deref lnd anymore now; it might have unregistered > @@ -1248,7 +1248,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > lnd->lnd_refcount++; > lnet_net_unlock(LNET_LOCK_EX); > > - ni->ni_lnd = lnd; > + ni->ni_net->net_lnd = lnd; > > if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) > lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; > @@ -1794,7 +1794,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > if (rc) > goto failed1; > > - if (ni->ni_lnd->lnd_accept) { > + if (ni->ni_net->net_lnd->lnd_accept) { > rc = lnet_acceptor_start(); > if (rc < 0) { > /* shutdown the ni that we just started */ > @@ -2074,10 +2074,10 @@ LNetCtl(unsigned int cmd, void *arg) > if (!ni) > return -EINVAL; > > - if (!ni->ni_lnd->lnd_ctl) > + if (!ni->ni_net->net_lnd->lnd_ctl) > rc = -EINVAL; > else > - rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); > + rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); > > lnet_ni_decref(ni); > return rc; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index f186e6a16d34..1bf12af87a20 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -406,7 +406,7 @@ lnet_ni_recv(struct lnet_ni *ni, void *private, struct lnet_msg *msg, > iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset); > iov_iter_advance(&to, offset); > } > - rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > + rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > if (rc < 0) > lnet_finalize(ni, msg, rc); > } > @@ -461,7 +461,7 @@ lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg) > LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND || > (msg->msg_txcredit && msg->msg_peertxcredit)); > > - rc = ni->ni_lnd->lnd_send(ni, priv, msg); > + rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); > if (rc < 0) > lnet_finalize(ni, msg, rc); > } > @@ -474,10 +474,10 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) > LASSERT(!msg->msg_sending); > LASSERT(msg->msg_receiving); > LASSERT(!msg->msg_rx_ready_delay); > - LASSERT(ni->ni_lnd->lnd_eager_recv); > + LASSERT(ni->ni_net->net_lnd->lnd_eager_recv); > > msg->msg_rx_ready_delay = 1; > - rc = ni->ni_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > + rc = ni->ni_net->net_lnd->lnd_eager_recv(ni, msg->msg_private, msg, > &msg->msg_private); > if (rc) { > CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", > @@ -496,10 +496,10 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > time64_t last_alive = 0; > > LASSERT(lnet_peer_aliveness_enabled(lp)); > - LASSERT(ni->ni_lnd->lnd_query); > + LASSERT(ni->ni_net->net_lnd->lnd_query); > > lnet_net_unlock(lp->lp_cpt); > - ni->ni_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > + ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > lnet_net_lock(lp->lp_cpt); > > lp->lp_last_query = ktime_get_seconds(); > @@ -1287,7 +1287,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > info.mi_roffset = hdr->msg.put.offset; > info.mi_mbits = hdr->msg.put.match_bits; > > - msg->msg_rx_ready_delay = !ni->ni_lnd->lnd_eager_recv; > + msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > ready_delay = msg->msg_rx_ready_delay; > > again: > @@ -1518,7 +1518,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) > > if (msg->msg_rxpeer->lp_rtrcredits <= 0 || > lnet_msg2bufpool(msg)->rbp_credits <= 0) { > - if (!ni->ni_lnd->lnd_eager_recv) { > + if (!ni->ni_net->net_lnd->lnd_eager_recv) { > msg->msg_rx_ready_delay = 1; > } else { > lnet_net_unlock(msg->msg_rx_cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c > index eb14146bd879..8167980c2323 100644 > --- a/drivers/staging/lustre/lnet/lnet/lo.c > +++ b/drivers/staging/lustre/lnet/lnet/lo.c > @@ -83,7 +83,7 @@ lolnd_shutdown(struct lnet_ni *ni) > static int > lolnd_startup(struct lnet_ni *ni) > { > - LASSERT(ni->ni_lnd == &the_lolnd); > + LASSERT(ni->ni_net->net_lnd == &the_lolnd); > LASSERT(!lolnd_instanced); > lolnd_instanced = 1; > > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 7d61c5d71426..0c0ec0b27982 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -154,14 +154,14 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > lp->lp_notifylnd = 0; > lp->lp_notify = 0; > > - if (notifylnd && ni->ni_lnd->lnd_notify) { > + if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { > lnet_net_unlock(lp->lp_cpt); > > /* > * A new notification could happen now; I'll handle it > * when control returns to me > */ > - ni->ni_lnd->lnd_notify(ni, lp->lp_nid, alive); > + ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); > > lnet_net_lock(lp->lp_cpt); > } > @@ -380,8 +380,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > lnet_net_unlock(LNET_LOCK_EX); > > /* XXX Assume alive */ > - if (ni->ni_lnd->lnd_notify) > - ni->ni_lnd->lnd_notify(ni, gateway, 1); > + if (ni->ni_net->net_lnd->lnd_notify) > + ni->ni_net->net_lnd->lnd_notify(ni, gateway, 1); > > lnet_net_lock(LNET_LOCK_EX); > } > @@ -818,7 +818,7 @@ lnet_update_ni_status_locked(void) > > now = ktime_get_real_seconds(); > list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_lnd->lnd_type == LOLND) > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > continue; > > if (now < ni->ni_last_alive + timeout) > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 19cea7076057..f3ccd6a2b70e 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -674,7 +674,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > last_alive = now - ni->ni_last_alive; > > /* @lo forever alive */ > - if (ni->ni_lnd->lnd_type == LOLND) > + if (ni->ni_net->net_lnd->lnd_type == LOLND) > last_alive = 0; > > lnet_ni_lock(ni); > > > From doucharek at cray.com Mon Sep 10 23:25:43 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:25:43 +0000 Subject: [lustre-devel] [PATCH 08/34] lnet: add cpt to lnet_match_info. In-Reply-To: <153628137155.8267.2566576537174390617.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137155.8267.2566576537174390617.stgit@noble> Message-ID: Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: This seems to be a more direct way to get the cpt needed in lnet_mt_of_match(). This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown > --- .../staging/lustre/include/linux/lnet/lib-types.h | 1 + drivers/staging/lustre/lnet/lnet/lib-move.c | 1 + drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 255c6c4bbb89..2d2c066a11ba 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -511,6 +511,7 @@ enum lnet_match_flags { struct lnet_match_info { __u64 mi_mbits; struct lnet_process_id mi_id; + unsigned int mi_cpt; unsigned int mi_opc; unsigned int mi_portal; unsigned int mi_rlength; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b8b15f56a275..b6e81a693fc3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1303,6 +1303,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) info.mi_rlength = hdr->payload_length; info.mi_roffset = hdr->msg.put.offset; info.mi_mbits = hdr->msg.put.match_bits; + info.mi_cpt = msg->msg_rxpeer->lp_cpt; msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; ready_delay = msg->msg_rx_ready_delay; diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 4c5737083422..90ce51801726 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -292,7 +292,7 @@ lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg) rotor = ptl->ptl_rotor++; /* get round-robin factor */ if (portal_rotor == LNET_PTL_ROTOR_HASH_RT && routed) - cpt = lnet_cpt_of_nid(msg->msg_hdr.src_nid); + cpt = info->mi_cpt; else cpt = rotor % LNET_CPT_NUMBER; -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Mon Sep 10 23:27:40 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:27:40 +0100 (BST) Subject: [lustre-devel] [PATCH 05/34] lnet: begin separating "networks" from "network interfaces". In-Reply-To: <153628137142.8267.15402125903541546660.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137142.8267.15402125903541546660.stgit@noble> Message-ID: On Fri, 7 Sep 2018, NeilBrown wrote: > We already have "struct lnet_net" separate from "struct lnet_ni", > but they are currently allocated together and freed together and > it is assumed that they are 1-to-1. > > This patch starts breaking that assumption. We have separate > lnet_net_alloc() and lnet_net_free() to alloc/free the new lnet_net, > though they is currently called only when lnet_ni_alloc/free are > called. > > The netid is now stored in the lnet_net and fetched directly from > there, rather than extracting it from the net-interface-id ni_nid. > > The linkage between these two structures is now richer, lnet_net > can link to a list of lnet_ni. lnet_net now has a list of lnet_net, > so to find all the lnet_ni, we need to walk a list of lists. > This need to walk a list-of-lists occurs in several places, and new > helpers like lnet_get_ni_idx_locked() and lnet_get_next_ni_locked are > introduced. > > Previously a list_head was passed to lnet_ni_alloc() for the new > lnet_ni to be attached to. > Now a list is passed to lnet_net_alloc() for the net to be attached > to, and a lnet_net is passed to lnet_ni_alloc() for the ni to attach > to. > lnet_ni_alloc() also receives an interface name, but this is currently > unused. Reviewed-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 15 + > .../staging/lustre/include/linux/lnet/lib-types.h | 23 +- > drivers/staging/lustre/lnet/lnet/acceptor.c | 2 > drivers/staging/lustre/lnet/lnet/api-ni.c | 255 ++++++++++++++------ > drivers/staging/lustre/lnet/lnet/config.c | 135 +++++++---- > drivers/staging/lustre/lnet/lnet/lib-move.c | 6 > drivers/staging/lustre/lnet/lnet/router.c | 15 - > drivers/staging/lustre/lnet/lnet/router_proc.c | 16 - > 8 files changed, 308 insertions(+), 159 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 0fecf0d32c58..4440b87299c4 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -369,8 +369,14 @@ lnet_ni_decref(struct lnet_ni *ni) > } > > void lnet_ni_free(struct lnet_ni *ni); > +void lnet_net_free(struct lnet_net *net); > + > +struct lnet_net * > +lnet_net_alloc(__u32 net_type, struct list_head *netlist); > + > struct lnet_ni * > -lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist); > +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, > + char *iface); > > static inline int > lnet_nid2peerhash(lnet_nid_t nid) > @@ -412,6 +418,9 @@ void lnet_destroy_routes(void); > int lnet_get_route(int idx, __u32 *net, __u32 *hops, > lnet_nid_t *gateway, __u32 *alive, __u32 *priority); > int lnet_get_rtr_pool_cfg(int idx, struct lnet_ioctl_pool_cfg *pool_cfg); > +struct lnet_ni *lnet_get_next_ni_locked(struct lnet_net *mynet, > + struct lnet_ni *prev); > +struct lnet_ni *lnet_get_ni_idx_locked(int idx); > > void lnet_router_debugfs_init(void); > void lnet_router_debugfs_fini(void); > @@ -584,7 +593,7 @@ int lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, > __u32 local_ip, __u32 peer_ip, int peer_port); > void lnet_connect_console_error(int rc, lnet_nid_t peer_nid, > __u32 peer_ip, int port); > -int lnet_count_acceptor_nis(void); > +int lnet_count_acceptor_nets(void); > int lnet_acceptor_timeout(void); > int lnet_acceptor_port(void); > > @@ -618,7 +627,7 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); > int lnet_parse_ip2nets(char **networksp, char *ip2nets); > int lnet_parse_routes(char *route_str, int *im_a_router); > int lnet_parse_networks(struct list_head *nilist, char *networks); > -int lnet_net_unique(__u32 net, struct list_head *nilist); > +bool lnet_net_unique(__u32 net, struct list_head *nilist); > > int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); > struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index c5e3363de727..5f0d4703bf86 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -254,6 +254,15 @@ struct lnet_tx_queue { > }; > > struct lnet_net { > + /* chain on the ln_nets */ > + struct list_head net_list; > + > + /* net ID, which is compoed of > + * (net_type << 16) | net_num. > + * net_type can be one of the enumarated types defined in > + * lnet/include/lnet/nidstr.h */ > + __u32 net_id; > + > /* network tunables */ > struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; > > @@ -264,11 +273,13 @@ struct lnet_net { > bool net_tunables_set; > /* procedural interface */ > struct lnet_lnd *net_lnd; > + /* list of NIs on this net */ > + struct list_head net_ni_list; > }; > > struct lnet_ni { > - /* chain on ln_nis */ > - struct list_head ni_list; > + /* chain on the lnet_net structure */ > + struct list_head ni_netlist; > /* chain on ln_nis_cpt */ > struct list_head ni_cptlist; > > @@ -626,14 +637,16 @@ struct lnet { > /* failure simulation */ > struct list_head ln_test_peers; > struct list_head ln_drop_rules; > - struct list_head ln_delay_rules; > + struct list_head ln_delay_rules; > > - struct list_head ln_nis; /* LND instances */ > + /* LND instances */ > + struct list_head ln_nets; > /* NIs bond on specific CPT(s) */ > struct list_head ln_nis_cpt; > /* dying LND instances */ > struct list_head ln_nis_zombie; > - struct lnet_ni *ln_loni; /* the loopback NI */ > + /* the loopback NI */ > + struct lnet_ni *ln_loni; > > /* remote networks with routes to them */ > struct list_head *ln_remote_nets_hash; > diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c > index f8c921f0221c..88b90c1fdbaf 100644 > --- a/drivers/staging/lustre/lnet/lnet/acceptor.c > +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c > @@ -454,7 +454,7 @@ lnet_acceptor_start(void) > if (rc <= 0) > return rc; > > - if (!lnet_count_acceptor_nis()) /* not required */ > + if (lnet_count_acceptor_nets() == 0) /* not required */ > return 0; > > task = kthread_run(lnet_acceptor, (void *)(uintptr_t)secure, > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index c944fbb155c8..05687278334a 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -537,7 +537,7 @@ lnet_prepare(lnet_pid_t requested_pid) > the_lnet.ln_pid = requested_pid; > > INIT_LIST_HEAD(&the_lnet.ln_test_peers); > - INIT_LIST_HEAD(&the_lnet.ln_nis); > + INIT_LIST_HEAD(&the_lnet.ln_nets); > INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); > INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); > INIT_LIST_HEAD(&the_lnet.ln_routers); > @@ -616,7 +616,7 @@ lnet_unprepare(void) > > LASSERT(!the_lnet.ln_refcount); > LASSERT(list_empty(&the_lnet.ln_test_peers)); > - LASSERT(list_empty(&the_lnet.ln_nis)); > + LASSERT(list_empty(&the_lnet.ln_nets)); > LASSERT(list_empty(&the_lnet.ln_nis_cpt)); > LASSERT(list_empty(&the_lnet.ln_nis_zombie)); > > @@ -648,14 +648,17 @@ lnet_unprepare(void) > } > > struct lnet_ni * > -lnet_net2ni_locked(__u32 net, int cpt) > +lnet_net2ni_locked(__u32 net_id, int cpt) > { > - struct lnet_ni *ni; > + struct lnet_ni *ni; > + struct lnet_net *net; > > LASSERT(cpt != LNET_LOCK_EX); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (LNET_NIDNET(ni->ni_nid) == net) { > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + if (net->net_id == net_id) { > + ni = list_entry(net->net_ni_list.next, struct lnet_ni, > + ni_netlist); > lnet_ni_addref_locked(ni, cpt); > return ni; > } > @@ -760,14 +763,17 @@ lnet_islocalnet(__u32 net) > struct lnet_ni * > lnet_nid2ni_locked(lnet_nid_t nid, int cpt) > { > - struct lnet_ni *ni; > + struct lnet_net *net; > + struct lnet_ni *ni; > > LASSERT(cpt != LNET_LOCK_EX); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_nid == nid) { > - lnet_ni_addref_locked(ni, cpt); > - return ni; > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + if (ni->ni_nid == nid) { > + lnet_ni_addref_locked(ni, cpt); > + return ni; > + } > } > } > > @@ -790,16 +796,18 @@ lnet_islocalnid(lnet_nid_t nid) > } > > int > -lnet_count_acceptor_nis(void) > +lnet_count_acceptor_nets(void) > { > /* Return the # of NIs that need the acceptor. */ > - int count = 0; > - struct lnet_ni *ni; > - int cpt; > + int count = 0; > + struct lnet_net *net; > + int cpt; > > cpt = lnet_net_lock_current(); > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_net->net_lnd->lnd_accept) > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + /* all socklnd type networks should have the acceptor > + * thread started */ > + if (net->net_lnd->lnd_accept) > count++; > } > > @@ -832,13 +840,16 @@ lnet_ping_info_create(int num_ni) > static inline int > lnet_get_ni_count(void) > { > - struct lnet_ni *ni; > - int count = 0; > + struct lnet_ni *ni; > + struct lnet_net *net; > + int count = 0; > > lnet_net_lock(0); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) > - count++; > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) > + count++; > + } > > lnet_net_unlock(0); > > @@ -854,14 +865,17 @@ lnet_ping_info_free(struct lnet_ping_info *pinfo) > static void > lnet_ping_info_destroy(void) > { > + struct lnet_net *net; > struct lnet_ni *ni; > > lnet_net_lock(LNET_LOCK_EX); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - lnet_ni_lock(ni); > - ni->ni_status = NULL; > - lnet_ni_unlock(ni); > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + lnet_ni_lock(ni); > + ni->ni_status = NULL; > + lnet_ni_unlock(ni); > + } > } > > lnet_ping_info_free(the_lnet.ln_ping_info); > @@ -963,24 +977,28 @@ lnet_ping_md_unlink(struct lnet_ping_info *pinfo, > static void > lnet_ping_info_install_locked(struct lnet_ping_info *ping_info) > { > + int i = 0; > struct lnet_ni_status *ns; > struct lnet_ni *ni; > - int i = 0; > + struct lnet_net *net; > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - LASSERT(i < ping_info->pi_nnis); > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + LASSERT(i < ping_info->pi_nnis); > > - ns = &ping_info->pi_ni[i]; > + ns = &ping_info->pi_ni[i]; > > - ns->ns_nid = ni->ni_nid; > + ns->ns_nid = ni->ni_nid; > > - lnet_ni_lock(ni); > - ns->ns_status = (ni->ni_status) ? > - ni->ni_status->ns_status : LNET_NI_STATUS_UP; > - ni->ni_status = ns; > - lnet_ni_unlock(ni); > + lnet_ni_lock(ni); > + ns->ns_status = ni->ni_status ? > + ni->ni_status->ns_status : > + LNET_NI_STATUS_UP; > + ni->ni_status = ns; > + lnet_ni_unlock(ni); > > - i++; > + i++; > + } > } > } > > @@ -1054,9 +1072,9 @@ lnet_ni_unlink_locked(struct lnet_ni *ni) > } > > /* move it to zombie list and nobody can find it anymore */ > - LASSERT(!list_empty(&ni->ni_list)); > - list_move(&ni->ni_list, &the_lnet.ln_nis_zombie); > - lnet_ni_decref_locked(ni, 0); /* drop ln_nis' ref */ > + LASSERT(!list_empty(&ni->ni_netlist)); > + list_move(&ni->ni_netlist, &the_lnet.ln_nis_zombie); > + lnet_ni_decref_locked(ni, 0); > } > > static void > @@ -1076,17 +1094,17 @@ lnet_clear_zombies_nis_locked(void) > int j; > > ni = list_entry(the_lnet.ln_nis_zombie.next, > - struct lnet_ni, ni_list); > - list_del_init(&ni->ni_list); > + struct lnet_ni, ni_netlist); > + list_del_init(&ni->ni_netlist); > cfs_percpt_for_each(ref, j, ni->ni_refs) { > if (!*ref) > continue; > /* still busy, add it back to zombie list */ > - list_add(&ni->ni_list, &the_lnet.ln_nis_zombie); > + list_add(&ni->ni_netlist, &the_lnet.ln_nis_zombie); > break; > } > > - if (!list_empty(&ni->ni_list)) { > + if (!list_empty(&ni->ni_netlist)) { > lnet_net_unlock(LNET_LOCK_EX); > ++i; > if ((i & (-i)) == i) { > @@ -1126,6 +1144,7 @@ lnet_shutdown_lndnis(void) > { > struct lnet_ni *ni; > int i; > + struct lnet_net *net; > > /* NB called holding the global mutex */ > > @@ -1138,10 +1157,14 @@ lnet_shutdown_lndnis(void) > the_lnet.ln_shutdown = 1; /* flag shutdown */ > > /* Unlink NIs from the global table */ > - while (!list_empty(&the_lnet.ln_nis)) { > - ni = list_entry(the_lnet.ln_nis.next, > - struct lnet_ni, ni_list); > - lnet_ni_unlink_locked(ni); > + while (!list_empty(&the_lnet.ln_nets)) { > + net = list_entry(the_lnet.ln_nets.next, > + struct lnet_net, net_list); > + while (!list_empty(&net->net_ni_list)) { > + ni = list_entry(net->net_ni_list.next, > + struct lnet_ni, ni_netlist); > + lnet_ni_unlink_locked(ni); > + } > } > > /* Drop the cached loopback NI. */ > @@ -1212,7 +1235,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > > /* Make sure this new NI is unique. */ > lnet_net_lock(LNET_LOCK_EX); > - rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis); > + rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nets); > lnet_net_unlock(LNET_LOCK_EX); > if (!rc) { > if (lnd_type == LOLND) { > @@ -1297,7 +1320,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > lnet_net_lock(LNET_LOCK_EX); > /* refcount for ln_nis */ > lnet_ni_addref_locked(ni, 0); > - list_add_tail(&ni->ni_list, &the_lnet.ln_nis); > + list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); > if (ni->ni_cpts) { > lnet_ni_addref_locked(ni, 0); > list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); > @@ -1363,8 +1386,8 @@ lnet_startup_lndnis(struct list_head *nilist) > int ni_count = 0; > > while (!list_empty(nilist)) { > - ni = list_entry(nilist->next, struct lnet_ni, ni_list); > - list_del(&ni->ni_list); > + ni = list_entry(nilist->next, struct lnet_ni, ni_netlist); > + list_del(&ni->ni_netlist); > rc = lnet_startup_lndni(ni, NULL); > > if (rc < 0) > @@ -1486,6 +1509,7 @@ LNetNIInit(lnet_pid_t requested_pid) > struct lnet_ping_info *pinfo; > struct lnet_handle_md md_handle; > struct list_head net_head; > + struct lnet_net *net; > > INIT_LIST_HEAD(&net_head); > > @@ -1505,8 +1529,15 @@ LNetNIInit(lnet_pid_t requested_pid) > return rc; > } > > - /* Add in the loopback network */ > - if (!lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head)) { > + /* create a network for Loopback network */ > + net = lnet_net_alloc(LNET_MKNET(LOLND, 0), &net_head); > + if (net == NULL) { > + rc = -ENOMEM; > + goto err_empty_list; > + } > + > + /* Add in the loopback NI */ > + if (lnet_ni_alloc(net, NULL, NULL) == NULL) { > rc = -ENOMEM; > goto err_empty_list; > } > @@ -1584,11 +1615,11 @@ LNetNIInit(lnet_pid_t requested_pid) > LASSERT(rc < 0); > mutex_unlock(&the_lnet.ln_api_mutex); > while (!list_empty(&net_head)) { > - struct lnet_ni *ni; > + struct lnet_net *net; > > - ni = list_entry(net_head.next, struct lnet_ni, ni_list); > - list_del_init(&ni->ni_list); > - lnet_ni_free(ni); > + net = list_entry(net_head.next, struct lnet_net, net_list); > + list_del_init(&net->net_list); > + lnet_net_free(net); > } > return rc; > } > @@ -1714,25 +1745,83 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) > } > } > > +struct lnet_ni * > +lnet_get_ni_idx_locked(int idx) > +{ > + struct lnet_ni *ni; > + struct lnet_net *net; > + > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + if (idx-- == 0) > + return ni; > + } > + } > + > + return NULL; > +} > + > +struct lnet_ni * > +lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev) > +{ > + struct lnet_ni *ni; > + struct lnet_net *net = mynet; > + > + if (prev == NULL) { > + if (net == NULL) > + net = list_entry(the_lnet.ln_nets.next, struct lnet_net, > + net_list); > + ni = list_entry(net->net_ni_list.next, struct lnet_ni, > + ni_netlist); > + > + return ni; > + } > + > + if (prev->ni_netlist.next == &prev->ni_net->net_ni_list) { > + /* if you reached the end of the ni list and the net is > + * specified, then there are no more nis in that net */ > + if (net != NULL) > + return NULL; > + > + /* we reached the end of this net ni list. move to the > + * next net */ > + if (prev->ni_net->net_list.next == &the_lnet.ln_nets) > + /* no more nets and no more NIs. */ > + return NULL; > + > + /* get the next net */ > + net = list_entry(prev->ni_net->net_list.next, struct lnet_net, > + net_list); > + /* get the ni on it */ > + ni = list_entry(net->net_ni_list.next, struct lnet_ni, > + ni_netlist); > + > + return ni; > + } > + > + /* there are more nis left */ > + ni = list_entry(prev->ni_netlist.next, struct lnet_ni, ni_netlist); > + > + return ni; > +} > + > static int > lnet_get_net_config(struct lnet_ioctl_config_data *config) > { > struct lnet_ni *ni; > + int cpt; > int idx = config->cfg_count; > - int cpt, i = 0; > int rc = -ENOENT; > > cpt = lnet_net_lock_current(); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (i++ != idx) > - continue; > + ni = lnet_get_ni_idx_locked(idx); > > + if (ni != NULL) { > + rc = 0; > lnet_ni_lock(ni); > lnet_fill_ni_info(ni, config); > lnet_ni_unlock(ni); > - rc = 0; > - break; > } > > lnet_net_unlock(cpt); > @@ -1745,6 +1834,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > char *nets = conf->cfg_config_u.cfg_net.net_intf; > struct lnet_ping_info *pinfo; > struct lnet_handle_md md_handle; > + struct lnet_net *net; > struct lnet_ni *ni; > struct list_head net_head; > struct lnet_remotenet *rnet; > @@ -1752,7 +1842,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > > INIT_LIST_HEAD(&net_head); > > - /* Create a ni structure for the network string */ > + /* Create a net/ni structures for the network string */ > rc = lnet_parse_networks(&net_head, nets); > if (rc <= 0) > return !rc ? -EINVAL : rc; > @@ -1760,14 +1850,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > mutex_lock(&the_lnet.ln_api_mutex); > > if (rc > 1) { > - rc = -EINVAL; /* only add one interface per call */ > + rc = -EINVAL; /* only add one network per call */ > goto failed0; > } > > - ni = list_entry(net_head.next, struct lnet_ni, ni_list); > + net = list_entry(net_head.next, struct lnet_net, net_list); > > lnet_net_lock(LNET_LOCK_EX); > - rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid)); > + rnet = lnet_find_net_locked(net->net_id); > lnet_net_unlock(LNET_LOCK_EX); > /* > * make sure that the net added doesn't invalidate the current > @@ -1785,8 +1875,8 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > if (rc) > goto failed0; > > - list_del_init(&ni->ni_list); > - > + list_del_init(&net->net_list); > + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); > rc = lnet_startup_lndni(ni, conf); > if (rc) > goto failed1; > @@ -1812,9 +1902,9 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > failed0: > mutex_unlock(&the_lnet.ln_api_mutex); > while (!list_empty(&net_head)) { > - ni = list_entry(net_head.next, struct lnet_ni, ni_list); > - list_del_init(&ni->ni_list); > - lnet_ni_free(ni); > + net = list_entry(net_head.next, struct lnet_net, net_list); > + list_del_init(&net->net_list); > + lnet_net_free(net); > } > return rc; > } > @@ -1849,7 +1939,7 @@ lnet_dyn_del_ni(__u32 net) > > lnet_shutdown_lndni(ni); > > - if (!lnet_count_acceptor_nis()) > + if (!lnet_count_acceptor_nets()) > lnet_acceptor_stop(); > > lnet_ping_target_update(pinfo, md_handle); > @@ -2103,7 +2193,8 @@ EXPORT_SYMBOL(LNetDebugPeer); > int > LNetGetId(unsigned int index, struct lnet_process_id *id) > { > - struct lnet_ni *ni; > + struct lnet_ni *ni; > + struct lnet_net *net; > int cpt; > int rc = -ENOENT; > > @@ -2111,14 +2202,16 @@ LNetGetId(unsigned int index, struct lnet_process_id *id) > > cpt = lnet_net_lock_current(); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (index--) > - continue; > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + if (index-- != 0) > + continue; > > - id->nid = ni->ni_nid; > - id->pid = the_lnet.ln_pid; > - rc = 0; > - break; > + id->nid = ni->ni_nid; > + id->pid = the_lnet.ln_pid; > + rc = 0; > + break; > + } > } > > lnet_net_unlock(cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c > index 5646feeb433e..e83bdbec11e3 100644 > --- a/drivers/staging/lustre/lnet/lnet/config.c > +++ b/drivers/staging/lustre/lnet/lnet/config.c > @@ -78,17 +78,17 @@ lnet_issep(char c) > } > } > > -int > -lnet_net_unique(__u32 net, struct list_head *nilist) > +bool > +lnet_net_unique(__u32 net, struct list_head *netlist) > { > - struct lnet_ni *ni; > + struct lnet_net *net_l; > > - list_for_each_entry(ni, nilist, ni_list) { > - if (LNET_NIDNET(ni->ni_nid) == net) > - return 0; > + list_for_each_entry(net_l, netlist, net_list) { > + if (net_l->net_id == net) > + return false; > } > > - return 1; > + return true; > } > > void > @@ -112,41 +112,78 @@ lnet_ni_free(struct lnet_ni *ni) > if (ni->ni_net_ns) > put_net(ni->ni_net_ns); > > - kvfree(ni->ni_net); > kfree(ni); > } > > -struct lnet_ni * > -lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > +void > +lnet_net_free(struct lnet_net *net) > { > - struct lnet_tx_queue *tq; > + struct list_head *tmp, *tmp2; > struct lnet_ni *ni; > - int rc; > - int i; > + > + /* delete any nis which have been started. */ > + list_for_each_safe(tmp, tmp2, &net->net_ni_list) { > + ni = list_entry(tmp, struct lnet_ni, ni_netlist); > + list_del_init(&ni->ni_netlist); > + lnet_ni_free(ni); > + } > + > + kfree(net); > +} > + > +struct lnet_net * > +lnet_net_alloc(__u32 net_id, struct list_head *net_list) > +{ > struct lnet_net *net; > > - if (!lnet_net_unique(net_id, nilist)) { > - LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", > - libcfs_net2str(net_id)); > + if (!lnet_net_unique(net_id, net_list)) { > + CERROR("Duplicate net %s. Ignore\n", > + libcfs_net2str(net_id)); > return NULL; > } > > - ni = kzalloc(sizeof(*ni), GFP_NOFS); > net = kzalloc(sizeof(*net), GFP_NOFS); > - if (!ni || !net) { > - kfree(ni); kfree(net); > + if (!net) { > CERROR("Out of memory creating network %s\n", > libcfs_net2str(net_id)); > return NULL; > } > + > + INIT_LIST_HEAD(&net->net_list); > + INIT_LIST_HEAD(&net->net_ni_list); > + > + net->net_id = net_id; > + > /* initialize global paramters to undefiend */ > net->net_tunables.lct_peer_timeout = -1; > net->net_tunables.lct_max_tx_credits = -1; > net->net_tunables.lct_peer_tx_credits = -1; > net->net_tunables.lct_peer_rtr_credits = -1; > > + list_add_tail(&net->net_list, net_list); > + > + return net; > +} > + > +struct lnet_ni * > +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) > +{ > + struct lnet_tx_queue *tq; > + struct lnet_ni *ni; > + int rc; > + int i; > + > + ni = kzalloc(sizeof(*ni), GFP_KERNEL); > + if (ni == NULL) { > + CERROR("Out of memory creating network interface %s%s\n", > + libcfs_net2str(net->net_id), > + (iface != NULL) ? iface : ""); > + return NULL; > + } > + > spin_lock_init(&ni->ni_lock); > INIT_LIST_HEAD(&ni->ni_cptlist); > + INIT_LIST_HEAD(&ni->ni_netlist); > ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(), > sizeof(*ni->ni_refs[0])); > if (!ni->ni_refs) > @@ -166,8 +203,9 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > } 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_id), rc); > + CERROR("Failed to set CPTs for NI %s(%s): %d\n", > + libcfs_net2str(net->net_id), > + (iface != NULL) ? iface : "", rc); > goto failed; > } > > @@ -182,7 +220,7 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > > ni->ni_net = net; > /* LND will fill in the address part of the NID */ > - ni->ni_nid = LNET_MKNID(net_id, 0); > + ni->ni_nid = LNET_MKNID(net->net_id, 0); > > /* Store net namespace in which current ni is being created */ > if (current->nsproxy->net_ns) > @@ -191,22 +229,24 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > ni->ni_net_ns = NULL; > > ni->ni_last_alive = ktime_get_real_seconds(); > - list_add_tail(&ni->ni_list, nilist); > + list_add_tail(&ni->ni_netlist, &net->net_ni_list); > + > return ni; > - failed: > +failed: > lnet_ni_free(ni); > return NULL; > } > > int > -lnet_parse_networks(struct list_head *nilist, char *networks) > +lnet_parse_networks(struct list_head *netlist, char *networks) > { > struct cfs_expr_list *el = NULL; > char *tokens; > char *str; > char *tmp; > - struct lnet_ni *ni; > - __u32 net; > + struct lnet_net *net; > + struct lnet_ni *ni = NULL; > + __u32 net_id; > int nnets = 0; > struct list_head *temp_node; > > @@ -275,18 +315,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > > if (comma) > *comma++ = 0; > - net = libcfs_str2net(strim(str)); > + net_id = libcfs_str2net(strim(str)); > > - if (net == LNET_NIDNET(LNET_NID_ANY)) { > + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { > LCONSOLE_ERROR_MSG(0x113, > "Unrecognised network type\n"); > tmp = str; > goto failed_syntax; > } > > - if (LNET_NETTYP(net) != LOLND && /* LO is implicit */ > - !lnet_ni_alloc(net, el, nilist)) > - goto failed; > + if (LNET_NETTYP(net_id) != LOLND) { /* LO is implicit */ > + net = lnet_net_alloc(net_id, netlist); > + if (!net || > + !lnet_ni_alloc(net, el, NULL)) > + goto failed; > + } > > if (el) { > cfs_expr_list_free(el); > @@ -298,14 +341,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > } > > *bracket = 0; > - net = libcfs_str2net(strim(str)); > - if (net == LNET_NIDNET(LNET_NID_ANY)) { > + net_id = libcfs_str2net(strim(str)); > + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { > tmp = str; > goto failed_syntax; > } > > - ni = lnet_ni_alloc(net, el, nilist); > - if (!ni) > + /* always allocate a net, since we will eventually add an > + * interface to it, or we will fail, in which case we'll > + * just delete it */ > + net = lnet_net_alloc(net_id, netlist); > + if (IS_ERR_OR_NULL(net)) > + goto failed; > + > + ni = lnet_ni_alloc(net, el, NULL); > + if (IS_ERR_OR_NULL(ni)) > goto failed; > > if (el) { > @@ -337,7 +387,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > if (niface == LNET_MAX_INTERFACES) { > LCONSOLE_ERROR_MSG(0x115, > "Too many interfaces for net %s\n", > - libcfs_net2str(net)); > + libcfs_net2str(net_id)); > goto failed; > } > > @@ -378,7 +428,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > } > } > > - list_for_each(temp_node, nilist) > + list_for_each(temp_node, netlist) > nnets++; > > kfree(tokens); > @@ -387,11 +437,12 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > failed_syntax: > lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp)); > failed: > - while (!list_empty(nilist)) { > - ni = list_entry(nilist->next, struct lnet_ni, ni_list); > + /* free the net list and all the nis on each net */ > + while (!list_empty(netlist)) { > + net = list_entry(netlist->next, struct lnet_net, net_list); > > - list_del(&ni->ni_list); > - lnet_ni_free(ni); > + list_del_init(&net->net_list); > + lnet_net_free(net); > } > > if (el) > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index 1bf12af87a20..1c874025fa74 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -2289,7 +2289,7 @@ EXPORT_SYMBOL(LNetGet); > int > LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) > { > - struct lnet_ni *ni; > + struct lnet_ni *ni = NULL; > struct lnet_remotenet *rnet; > __u32 dstnet = LNET_NIDNET(dstnid); > int hops; > @@ -2307,9 +2307,9 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) > > cpt = lnet_net_lock_current(); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { > if (ni->ni_nid == dstnid) { > - if (srcnidp) > + if (srcnidp != NULL) > *srcnidp = dstnid; > if (orderp) { > if (LNET_NETTYP(LNET_NIDNET(dstnid)) == LOLND) > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 0c0ec0b27982..135dfe793b0b 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -245,13 +245,10 @@ static void lnet_shuffle_seed(void) > if (seeded) > return; > > - /* > - * Nodes with small feet have little entropy > - * the NID for this node gives the most entropy in the low bits > - */ > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > + /* Nodes with small feet have little entropy > + * the NID for this node gives the most entropy in the low bits */ > + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { > __u32 lnd_type, seed; > - > lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); > if (lnd_type != LOLND) { > seed = (LNET_NIDADDR(ni->ni_nid) | lnd_type); > @@ -807,8 +804,8 @@ lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) > static void > lnet_update_ni_status_locked(void) > { > - struct lnet_ni *ni; > - time64_t now; > + struct lnet_ni *ni = NULL; > + time64_t now; > time64_t timeout; > > LASSERT(the_lnet.ln_routing); > @@ -817,7 +814,7 @@ lnet_update_ni_status_locked(void) > max(live_router_check_interval, dead_router_check_interval); > > now = ktime_get_real_seconds(); > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { > if (ni->ni_net->net_lnd->lnd_type == LOLND) > continue; > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index f3ccd6a2b70e..2a366e9a8627 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -641,26 +641,12 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > "rtr", "max", "tx", "min"); > LASSERT(tmpstr + tmpsiz - s > 0); > } else { > - struct list_head *n; > struct lnet_ni *ni = NULL; > int skip = *ppos - 1; > > lnet_net_lock(0); > > - n = the_lnet.ln_nis.next; > - > - while (n != &the_lnet.ln_nis) { > - struct lnet_ni *a_ni; > - > - a_ni = list_entry(n, struct lnet_ni, ni_list); > - if (!skip) { > - ni = a_ni; > - break; > - } > - > - skip--; > - n = n->next; > - } > + ni = lnet_get_ni_idx_locked(skip); > > if (ni) { > struct lnet_tx_queue *tq; > > > From doucharek at cray.com Mon Sep 10 23:28:43 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:28:43 +0000 Subject: [lustre-devel] [PATCH 09/34] lnet: add list of cpts to lnet_net. In-Reply-To: <153628137159.8267.921309094971745898.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137159.8267.921309094971745898.stgit@noble> Message-ID: <5BB5FEA0-B2F8-4F61-8697-EB96B1CAAC92@cray.com> I agree with a comment from James Simmons: __u32 should only be used when the variable is being shared with user space. We need to start converting all uses of __uXX in LNet to just uXX. Perhaps that should be a set of future patches once all of MR/DD has landed? Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: struct lnet_net now has a list of cpts, which is the union of the cpts for each lnet_ni. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown > --- .../staging/lustre/include/linux/lnet/lib-types.h | 6 + drivers/staging/lustre/lnet/lnet/config.c | 164 ++++++++++++++++++++ 2 files changed, 170 insertions(+) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 2d2c066a11ba..22957d142cc0 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -266,6 +266,12 @@ struct lnet_net { * lnet/include/lnet/nidstr.h */ __u32 net_id; + /* total number of CPTs in the array */ + __u32 net_ncpts; + + /* cumulative CPTs of all NIs in this net */ + __u32 *net_cpts; + /* network tunables */ struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index e83bdbec11e3..380a3fb1caba 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -91,11 +91,169 @@ lnet_net_unique(__u32 net, struct list_head *netlist) return true; } +static bool +in_array(__u32 *array, __u32 size, __u32 value) +{ + int i; + + for (i = 0; i < size; i++) { + if (array[i] == value) + return false; + } + + return true; +} + +static int +lnet_net_append_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net) +{ + __u32 *added_cpts = NULL; + int i, j = 0, rc = 0; + + /* + * no need to go futher since a subset of the NIs already exist on + * all CPTs + */ + if (net->net_ncpts == LNET_CPT_NUMBER) + return 0; + + if (cpts == NULL) { + /* there is an NI which will exist on all CPTs */ + if (net->net_cpts != NULL) + kvfree(net->net_cpts); + net->net_cpts = NULL; + net->net_ncpts = LNET_CPT_NUMBER; + return 0; + } + + if (net->net_cpts == NULL) { + net->net_cpts = kmalloc_array(ncpts, sizeof(net->net_cpts), + GFP_KERNEL); + if (net->net_cpts == NULL) + return -ENOMEM; + memcpy(net->net_cpts, cpts, ncpts); + return 0; + } + + added_cpts = kmalloc_array(LNET_CPT_NUMBER, sizeof(*added_cpts), + GFP_KERNEL); + if (added_cpts == NULL) + return -ENOMEM; + + for (i = 0; i < ncpts; i++) { + if (!in_array(net->net_cpts, net->net_ncpts, cpts[i])) { + added_cpts[j] = cpts[i]; + j++; + } + } + + /* append the new cpts if any to the list of cpts in the net */ + if (j > 0) { + __u32 *array = NULL, *loc; + __u32 total_entries = j + net->net_ncpts; + + array = kmalloc_array(total_entries, sizeof(*net->net_cpts), + GFP_KERNEL); + if (array == NULL) { + rc = -ENOMEM; + goto failed; + } + + memcpy(array, net->net_cpts, + net->net_ncpts * sizeof(*net->net_cpts)); + loc = array + net->net_ncpts; + memcpy(loc, added_cpts, j * sizeof(*net->net_cpts)); + + kfree(net->net_cpts); + net->net_ncpts = total_entries; + net->net_cpts = array; + } + +failed: + kfree(added_cpts); + + return rc; +} + +static void +lnet_net_remove_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net) +{ + struct lnet_ni *ni; + int rc; + + /* + * Operation Assumption: + * This function is called after an NI has been removed from + * its parent net. + * + * if we're removing an NI which exists on all CPTs then + * we have to check if any of the other NIs on this net also + * exists on all CPTs. If none, then we need to build our Net CPT + * list based on the remaining NIs. + * + * If the NI being removed exist on a subset of the CPTs then we + * alo rebuild the Net CPT list based on the remaining NIs, which + * should resutl in the expected Net CPT list. + */ + + /* + * sometimes this function can be called due to some failure + * creating an NI, before any of the cpts are allocated, so check + * for that case and don't do anything + */ + if (ncpts == 0) + return; + + if (ncpts == LNET_CPT_NUMBER) { + /* + * first iteration through the NI list in the net to see + * if any of the NIs exist on all the CPTs. If one is + * found then our job is done. + */ + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (ni->ni_ncpts == LNET_CPT_NUMBER) + return; + } + } + + /* + * Rebuild the Net CPT list again, thereby only including only the + * CPTs which the remaining NIs are associated with. + */ + if (net->net_cpts != NULL) { + kfree(net->net_cpts); + net->net_cpts = NULL; + } + + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, + net); + if (rc != 0) { + CERROR("Out of Memory\n"); + /* + * do our best to keep on going. Delete + * the net cpts and set it to NULL. This + * way we can keep on going but less + * efficiently, since memory accesses might be + * accross CPT lines. + */ + if (net->net_cpts != NULL) { + kfree(net->net_cpts); + net->net_cpts = NULL; + net->net_ncpts = LNET_CPT_NUMBER; + } + return; + } + } +} + void lnet_ni_free(struct lnet_ni *ni) { int i; + lnet_net_remove_cpts(ni->ni_cpts, ni->ni_ncpts, ni->ni_net); + if (ni->ni_refs) cfs_percpt_free(ni->ni_refs); @@ -128,6 +286,9 @@ lnet_net_free(struct lnet_net *net) lnet_ni_free(ni); } + if (net->net_cpts != NULL) + kfree(net->net_cpts); + kfree(net); } @@ -229,6 +390,9 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) ni->ni_net_ns = NULL; ni->ni_last_alive = ktime_get_real_seconds(); + rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); + if (rc != 0) + goto failed; list_add_tail(&ni->ni_netlist, &net->net_ni_list); return ni; -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Mon Sep 10 23:29:31 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:29:31 +0100 (BST) Subject: [lustre-devel] [PATCH 06/34] lnet: store separate xmit/recv net-interface in each message. In-Reply-To: <153628137147.8267.3706504130592682241.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137147.8267.3706504130592682241.stgit@noble> Message-ID: > Currently we store the net-interface in the peer, but the > peer should identify just the network, not the particular interface. > To help track which actual interface is used for each > message, store them explicitly. Reviewed-by: James Simmons The below needs fixing based on response to cover letter. With a combo patch the following works well. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18274 Reviewed-on: http://review.whamcloud.com/20729 Reviewed-by: Doug Oucharek Reviewed-by: Olaf Weber Signed-off-by: NeilBrown > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > and includes commit 63c3e5129873 ("LU-7734 lnet: Fix lnet_msg_free()") > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 3 +++ > drivers/staging/lustre/lnet/lnet/lib-move.c | 21 ++++++++++++++++++-- > 2 files changed, 22 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 5f0d4703bf86..16a493529a46 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -98,6 +98,9 @@ struct lnet_msg { > > void *msg_private; > struct lnet_libmd *msg_md; > + /* the NI the message was sent or received over */ > + struct lnet_ni *msg_txni; > + struct lnet_ni *msg_rxni; > > unsigned int msg_len; > unsigned int msg_wanted; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index 1c874025fa74..b2a52ddcefcb 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -782,6 +782,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > { > struct lnet_peer *txpeer = msg->msg_txpeer; > struct lnet_msg *msg2; > + struct lnet_ni *txni = msg->msg_txni; > > if (msg->msg_txcredit) { > struct lnet_ni *ni = txpeer->lp_ni; > @@ -829,6 +830,11 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > } > } > > + if (txni != NULL) { > + msg->msg_txni = NULL; > + lnet_ni_decref_locked(txni, msg->msg_tx_cpt); > + } > + > if (txpeer) { > msg->msg_txpeer = NULL; > lnet_peer_decref_locked(txpeer); > @@ -876,6 +882,7 @@ void > lnet_return_rx_credits_locked(struct lnet_msg *msg) > { > struct lnet_peer *rxpeer = msg->msg_rxpeer; > + struct lnet_ni *rxni = msg->msg_rxni; > struct lnet_msg *msg2; > > if (msg->msg_rtrcredit) { > @@ -951,6 +958,10 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) > (void)lnet_post_routed_recv_locked(msg2, 1); > } > } > + if (rxni != NULL) { > + msg->msg_rxni = NULL; > + lnet_ni_decref_locked(rxni, msg->msg_rx_cpt); > + } > if (rxpeer) { > msg->msg_rxpeer = NULL; > lnet_peer_decref_locked(rxpeer); > @@ -1218,9 +1229,12 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > > LASSERT(!msg->msg_peertxcredit); > LASSERT(!msg->msg_txcredit); > - LASSERT(!msg->msg_txpeer); > + LASSERT(msg->msg_txpeer == NULL); > > - msg->msg_txpeer = lp; /* msg takes my ref on lp */ > + msg->msg_txpeer = lp; /* msg takes my ref on lp */ > + /* set the NI for this message */ > + msg->msg_txni = src_ni; > + lnet_ni_addref_locked(msg->msg_txni, cpt); > > rc = lnet_post_send_locked(msg, 0); > lnet_net_unlock(cpt); > @@ -1818,6 +1832,8 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, > return 0; > goto drop; > } > + msg->msg_rxni = ni; > + lnet_ni_addref_locked(ni, cpt); > > if (lnet_isrouter(msg->msg_rxpeer)) { > lnet_peer_set_alive(msg->msg_rxpeer); > @@ -1934,6 +1950,7 @@ lnet_recv_delayed_msg_list(struct list_head *head) > LASSERT(msg->msg_rx_delayed); > LASSERT(msg->msg_md); > LASSERT(msg->msg_rxpeer); > + LASSERT(msg->msg_rxni); > LASSERT(msg->msg_hdr.type == LNET_MSG_PUT); > > CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d match %llu offset %d length %d.\n", > > > From doucharek at cray.com Mon Sep 10 23:32:41 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:32:41 +0000 Subject: [lustre-devel] [PATCH 10/34] lnet: add ni arg to lnet_cpt_of_nid() In-Reply-To: <153628137163.8267.8668023630519839070.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137163.8267.8668023630519839070.stgit@noble> Message-ID: Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: When choosing a cpt to use for a given network (identified by nid), the choice might depend on a particular interface which has already been identified - different interfaces can have different sets of cpts. So add an 'ni' arg to lnet_cpt_of_nid(). If given, choose a cpt from the cpts of that interface. If not given, choose one from the set of all cpts associated with any interface on the network. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown > --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 4 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 4 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 2 - .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 4 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 41 ++++++++++++-------- drivers/staging/lustre/lnet/lnet/lib-move.c | 12 +++--- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 - drivers/staging/lustre/lnet/lnet/peer.c | 4 +- drivers/staging/lustre/lnet/lnet/router.c | 4 +- drivers/staging/lustre/lnet/selftest/brw_test.c | 2 - drivers/staging/lustre/lnet/selftest/framework.c | 3 + drivers/staging/lustre/lnet/selftest/selftest.h | 2 - 12 files changed, 48 insertions(+), 36 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 34509e52bac7..e32dbb854d80 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -395,8 +395,8 @@ lnet_net2rnethash(__u32 net) extern struct lnet_lnd the_lolnd; extern int avoid_asym_router_failure; -int lnet_cpt_of_nid_locked(lnet_nid_t nid); -int lnet_cpt_of_nid(lnet_nid_t nid); +int lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni); +int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); struct lnet_ni *lnet_net2ni(__u32 net); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index ade566d20c69..958ac9a99045 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -320,7 +320,7 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, { struct kib_peer *peer; struct kib_net *net = ni->ni_data; - int cpt = lnet_cpt_of_nid(nid); + int cpt = lnet_cpt_of_nid(nid, ni); unsigned long flags; LASSERT(net); @@ -643,7 +643,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm dev = net->ibn_dev; - cpt = lnet_cpt_of_nid(peer->ibp_nid); + cpt = lnet_cpt_of_nid(peer->ibp_nid, peer->ibp_ni); sched = kiblnd_data.kib_scheds[cpt]; LASSERT(sched->ibs_nthreads > 0); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index c266940cb2ae..e64c14914924 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -119,7 +119,7 @@ kiblnd_get_idle_tx(struct lnet_ni *ni, lnet_nid_t target) struct kib_tx *tx; struct kib_tx_poolset *tps; - tps = net->ibn_tx_ps[lnet_cpt_of_nid(target)]; + tps = net->ibn_tx_ps[lnet_cpt_of_nid(target, ni)]; node = kiblnd_pool_alloc_node(&tps->tps_poolset); if (!node) return NULL; diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 2036a0ae5917..ba68bcee90bc 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -101,7 +101,7 @@ static int ksocknal_create_peer(struct ksock_peer **peerp, struct lnet_ni *ni, struct lnet_process_id id) { - int cpt = lnet_cpt_of_nid(id.nid); + int cpt = lnet_cpt_of_nid(id.nid, ni); struct ksock_net *net = ni->ni_data; struct ksock_peer *peer; @@ -1099,7 +1099,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, LASSERT(conn->ksnc_proto); LASSERT(peerid.nid != LNET_NID_ANY); - cpt = lnet_cpt_of_nid(peerid.nid); + cpt = lnet_cpt_of_nid(peerid.nid, ni); if (active) { ksocknal_peer_addref(peer); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index c21aef32cdde..6e0b8310574d 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -713,31 +713,41 @@ lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) } int -lnet_cpt_of_nid_locked(lnet_nid_t nid) +lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni) { - struct lnet_ni *ni; + struct lnet_net *net; /* must called with hold of lnet_net_lock */ if (LNET_CPT_NUMBER == 1) return 0; /* the only one */ - /* take lnet_net_lock(any) would be OK */ - if (!list_empty(&the_lnet.ln_nis_cpt)) { - list_for_each_entry(ni, &the_lnet.ln_nis_cpt, ni_cptlist) { - if (LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid)) - continue; + /* + * If NI is provided then use the CPT identified in the NI cpt + * list if one exists. If one doesn't exist, then that NI is + * associated with all CPTs and it follows that the net it belongs + * to is implicitly associated with all CPTs, so just hash the nid + * and return that. + */ + if (ni != NULL) { + if (ni->ni_cpts != NULL) + return ni->ni_cpts[lnet_nid_cpt_hash(nid, + ni->ni_ncpts)]; + else + return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); + } - LASSERT(ni->ni_cpts); - return ni->ni_cpts[lnet_nid_cpt_hash - (nid, ni->ni_ncpts)]; - } + /* no NI provided so look at the net */ + net = lnet_get_net_locked(LNET_NIDNET(nid)); + + if (net != NULL && net->net_cpts) { + return net->net_cpts[lnet_nid_cpt_hash(nid, net->net_ncpts)]; } return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); } int -lnet_cpt_of_nid(lnet_nid_t nid) +lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni) { int cpt; int cpt2; @@ -745,11 +755,10 @@ lnet_cpt_of_nid(lnet_nid_t nid) if (LNET_CPT_NUMBER == 1) return 0; /* the only one */ - if (list_empty(&the_lnet.ln_nis_cpt)) - return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); - cpt = lnet_net_lock_current(); - cpt2 = lnet_cpt_of_nid_locked(nid); + + cpt2 = lnet_cpt_of_nid_locked(nid, ni); + lnet_net_unlock(cpt); return cpt2; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b6e81a693fc3..02cd1a5a466f 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1095,7 +1095,9 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) msg->msg_sending = 1; LASSERT(!msg->msg_tx_committed); - cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid); + local_ni = lnet_net2ni(LNET_NIDNET(dst_nid)); + cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid, + local_ni); again: lnet_net_lock(cpt); @@ -1188,7 +1190,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) * was changed when we release the lock */ if (rtr_nid != lp->lp_nid) { - cpt2 = lnet_cpt_of_nid_locked(lp->lp_nid); + cpt2 = lp->lp_cpt; if (cpt2 != cpt) { if (src_ni) lnet_ni_decref_locked(src_ni, cpt); @@ -1677,7 +1679,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, payload_length = le32_to_cpu(hdr->payload_length); for_me = (ni->ni_nid == dest_nid); - cpt = lnet_cpt_of_nid(from_nid); + cpt = lnet_cpt_of_nid(from_nid, ni); switch (type) { case LNET_MSG_ACK: @@ -2149,7 +2151,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) lnet_msg_attach_md(msg, getmd, getmd->md_offset, getmd->md_length); lnet_res_unlock(cpt); - cpt = lnet_cpt_of_nid(peer_id.nid); + cpt = lnet_cpt_of_nid(peer_id.nid, ni); lnet_net_lock(cpt); lnet_msg_commit(msg, cpt); @@ -2160,7 +2162,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) return msg; drop: - cpt = lnet_cpt_of_nid(peer_id.nid); + cpt = lnet_cpt_of_nid(peer_id.nid, ni); lnet_net_lock(cpt); the_lnet.ln_counters[cpt]->drop_count++; diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 90ce51801726..c8d8162cc706 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -220,7 +220,7 @@ lnet_match2mt(struct lnet_portal *ptl, struct lnet_process_id id, __u64 mbits) /* if it's a unique portal, return match-table hashed by NID */ return lnet_ptl_is_unique(ptl) ? - ptl->ptl_mtables[lnet_cpt_of_nid(id.nid)] : NULL; + ptl->ptl_mtables[lnet_cpt_of_nid(id.nid, NULL)] : NULL; } struct lnet_match_table * diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index ed29124ebded..808ce25f1f00 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -270,7 +270,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) return -ESHUTDOWN; /* cpt can be LNET_LOCK_EX if it's called from router functions */ - cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid); + cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid, NULL); ptable = the_lnet.ln_peer_tables[cpt2]; lp = lnet_find_peer_locked(ptable, nid); @@ -362,7 +362,7 @@ lnet_debug_peer(lnet_nid_t nid) int rc; int cpt; - cpt = lnet_cpt_of_nid(nid); + cpt = lnet_cpt_of_nid(nid, NULL); lnet_net_lock(cpt); rc = lnet_nid2peer_locked(&lp, nid, cpt); diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 72b8ca2b0fc6..5493d13de6d9 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -1207,7 +1207,7 @@ lnet_router_checker(void *arg) version = the_lnet.ln_routers_version; list_for_each_entry(rtr, &the_lnet.ln_routers, lp_rtr_list) { - cpt2 = lnet_cpt_of_nid_locked(rtr->lp_nid); + cpt2 = rtr->lp_cpt; if (cpt != cpt2) { lnet_net_unlock(cpt); cpt = cpt2; @@ -1693,7 +1693,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) { struct lnet_peer *lp = NULL; time64_t now = ktime_get_seconds(); - int cpt = lnet_cpt_of_nid(nid); + int cpt = lnet_cpt_of_nid(nid, ni); LASSERT(!in_interrupt()); diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c index f1ee219bc8f3..e372ff3044c8 100644 --- a/drivers/staging/lustre/lnet/selftest/brw_test.c +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c @@ -124,7 +124,7 @@ brw_client_init(struct sfw_test_instance *tsi) return -EINVAL; list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) { - bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid), + bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid, NULL), off, npg, len, opc == LST_BRW_READ); if (!bulk) { brw_client_fini(tsi); diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index 944a2a6598fa..a82efc394659 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -1013,7 +1013,8 @@ sfw_run_batch(struct sfw_batch *tsb) tsu->tsu_loop = tsi->tsi_loop; wi = &tsu->tsu_worker; swi_init_workitem(wi, sfw_run_test, - lst_test_wq[lnet_cpt_of_nid(tsu->tsu_dest.nid)]); + lst_test_wq[lnet_cpt_of_nid(tsu->tsu_dest.nid, + NULL)]); swi_schedule_workitem(wi); } } diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index 9dbb0a51d430..edf783af90e8 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -527,7 +527,7 @@ srpc_init_client_rpc(struct srpc_client_rpc *rpc, struct lnet_process_id peer, INIT_LIST_HEAD(&rpc->crpc_list); swi_init_workitem(&rpc->crpc_wi, srpc_send_rpc, - lst_test_wq[lnet_cpt_of_nid(peer.nid)]); + lst_test_wq[lnet_cpt_of_nid(peer.nid, NULL)]); spin_lock_init(&rpc->crpc_lock); atomic_set(&rpc->crpc_refcount, 1); /* 1 ref for caller */ -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Mon Sep 10 23:36:33 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 00:36:33 +0100 (BST) Subject: [lustre-devel] [PATCH 06/34] lnet: store separate xmit/recv net-interface in each message. In-Reply-To: <153628137147.8267.3706504130592682241.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137147.8267.3706504130592682241.stgit@noble> Message-ID: > Currently we store the net-interface in the peer, but the > peer should identify just the network, not the particular interface. > To help track which actual interface is used for each > message, store them explicitly. Reviewed-by: James Simmons The below needs fixing based on response to cover letter. With a combo patch the following works well. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18274 Reviewed-on: http://review.whamcloud.com/20729 Reviewed-by: Doug Oucharek Reviewed-by: Olaf Weber Signed-off-by: NeilBrown > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > and includes commit 63c3e5129873 ("LU-7734 lnet: Fix lnet_msg_free()") > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 3 +++ > drivers/staging/lustre/lnet/lnet/lib-move.c | 21 ++++++++++++++++++-- > 2 files changed, 22 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 5f0d4703bf86..16a493529a46 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -98,6 +98,9 @@ struct lnet_msg { > > void *msg_private; > struct lnet_libmd *msg_md; > + /* the NI the message was sent or received over */ > + struct lnet_ni *msg_txni; > + struct lnet_ni *msg_rxni; > > unsigned int msg_len; > unsigned int msg_wanted; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index 1c874025fa74..b2a52ddcefcb 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -782,6 +782,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > { > struct lnet_peer *txpeer = msg->msg_txpeer; > struct lnet_msg *msg2; > + struct lnet_ni *txni = msg->msg_txni; > > if (msg->msg_txcredit) { > struct lnet_ni *ni = txpeer->lp_ni; > @@ -829,6 +830,11 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > } > } > > + if (txni != NULL) { > + msg->msg_txni = NULL; > + lnet_ni_decref_locked(txni, msg->msg_tx_cpt); > + } > + > if (txpeer) { > msg->msg_txpeer = NULL; > lnet_peer_decref_locked(txpeer); > @@ -876,6 +882,7 @@ void > lnet_return_rx_credits_locked(struct lnet_msg *msg) > { > struct lnet_peer *rxpeer = msg->msg_rxpeer; > + struct lnet_ni *rxni = msg->msg_rxni; > struct lnet_msg *msg2; > > if (msg->msg_rtrcredit) { > @@ -951,6 +958,10 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) > (void)lnet_post_routed_recv_locked(msg2, 1); > } > } > + if (rxni != NULL) { > + msg->msg_rxni = NULL; > + lnet_ni_decref_locked(rxni, msg->msg_rx_cpt); > + } > if (rxpeer) { > msg->msg_rxpeer = NULL; > lnet_peer_decref_locked(rxpeer); > @@ -1218,9 +1229,12 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > > LASSERT(!msg->msg_peertxcredit); > LASSERT(!msg->msg_txcredit); > - LASSERT(!msg->msg_txpeer); > + LASSERT(msg->msg_txpeer == NULL); > > - msg->msg_txpeer = lp; /* msg takes my ref on lp */ > + msg->msg_txpeer = lp; /* msg takes my ref on lp */ > + /* set the NI for this message */ > + msg->msg_txni = src_ni; > + lnet_ni_addref_locked(msg->msg_txni, cpt); > > rc = lnet_post_send_locked(msg, 0); > lnet_net_unlock(cpt); > @@ -1818,6 +1832,8 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, > return 0; > goto drop; > } > + msg->msg_rxni = ni; > + lnet_ni_addref_locked(ni, cpt); > > if (lnet_isrouter(msg->msg_rxpeer)) { > lnet_peer_set_alive(msg->msg_rxpeer); > @@ -1934,6 +1950,7 @@ lnet_recv_delayed_msg_list(struct list_head *head) > LASSERT(msg->msg_rx_delayed); > LASSERT(msg->msg_md); > LASSERT(msg->msg_rxpeer); > + LASSERT(msg->msg_rxni); > LASSERT(msg->msg_hdr.type == LNET_MSG_PUT); > > CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d match %llu offset %d length %d.\n", > > > From jsimmons at infradead.org Tue Sep 11 01:01:37 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 02:01:37 +0100 (BST) Subject: [lustre-devel] [PATCH 08/34] lnet: add cpt to lnet_match_info. In-Reply-To: <153628137155.8267.2566576537174390617.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137155.8267.2566576537174390617.stgit@noble> Message-ID: > This seems to be a more direct way to get the cpt > needed in lnet_mt_of_match(). Talking to Doug a better comment would be: This allows LNet to handle a change to a different CPT if the peer changes. The NID we are sending to can change based on multirail behavior. I CC Olaf as well for his comment. Code wise its good. Reviewed-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 1 + > drivers/staging/lustre/lnet/lnet/lib-move.c | 1 + > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 +- > 3 files changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 255c6c4bbb89..2d2c066a11ba 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -511,6 +511,7 @@ enum lnet_match_flags { > struct lnet_match_info { > __u64 mi_mbits; > struct lnet_process_id mi_id; > + unsigned int mi_cpt; > unsigned int mi_opc; > unsigned int mi_portal; > unsigned int mi_rlength; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index b8b15f56a275..b6e81a693fc3 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -1303,6 +1303,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > info.mi_rlength = hdr->payload_length; > info.mi_roffset = hdr->msg.put.offset; > info.mi_mbits = hdr->msg.put.match_bits; > + info.mi_cpt = msg->msg_rxpeer->lp_cpt; > > msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > ready_delay = msg->msg_rx_ready_delay; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > index 4c5737083422..90ce51801726 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > @@ -292,7 +292,7 @@ lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg) > > rotor = ptl->ptl_rotor++; /* get round-robin factor */ > if (portal_rotor == LNET_PTL_ROTOR_HASH_RT && routed) > - cpt = lnet_cpt_of_nid(msg->msg_hdr.src_nid); > + cpt = info->mi_cpt; > else > cpt = rotor % LNET_CPT_NUMBER; > > > > From jsimmons at infradead.org Tue Sep 11 01:01:58 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 02:01:58 +0100 (BST) Subject: [lustre-devel] BRe: [PATCH 08/34] lnet: add cpt to lnet_match_info. In-Reply-To: <153628137155.8267.2566576537174390617.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137155.8267.2566576537174390617.stgit@noble> Message-ID: > This seems to be a more direct way to get the cpt > needed in lnet_mt_of_match(). Talking to Doug a better comment would be: This allows LNet to handle a change to a different CPT if the peer changes. The NID we are sending to can change based on multirail behavior. I CC Olaf as well for his comment. Code wise its good. Reviewed-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 1 + > drivers/staging/lustre/lnet/lnet/lib-move.c | 1 + > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 +- > 3 files changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 255c6c4bbb89..2d2c066a11ba 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -511,6 +511,7 @@ enum lnet_match_flags { > struct lnet_match_info { > __u64 mi_mbits; > struct lnet_process_id mi_id; > + unsigned int mi_cpt; > unsigned int mi_opc; > unsigned int mi_portal; > unsigned int mi_rlength; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index b8b15f56a275..b6e81a693fc3 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -1303,6 +1303,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > info.mi_rlength = hdr->payload_length; > info.mi_roffset = hdr->msg.put.offset; > info.mi_mbits = hdr->msg.put.match_bits; > + info.mi_cpt = msg->msg_rxpeer->lp_cpt; > > msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > ready_delay = msg->msg_rx_ready_delay; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > index 4c5737083422..90ce51801726 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > @@ -292,7 +292,7 @@ lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg) > > rotor = ptl->ptl_rotor++; /* get round-robin factor */ > if (portal_rotor == LNET_PTL_ROTOR_HASH_RT && routed) > - cpt = lnet_cpt_of_nid(msg->msg_hdr.src_nid); > + cpt = info->mi_cpt; > else > cpt = rotor % LNET_CPT_NUMBER; > > > > From jsimmons at infradead.org Tue Sep 11 01:02:58 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 02:02:58 +0100 (BST) Subject: [lustre-devel] [PATCH 09/34] lnet: add list of cpts to lnet_net. In-Reply-To: <153628137159.8267.921309094971745898.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137159.8267.921309094971745898.stgit@noble> Message-ID: > struct lnet_net now has a list of cpts, which is the union > of the cpts for each lnet_ni. Reviewed-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 6 + > drivers/staging/lustre/lnet/lnet/config.c | 164 ++++++++++++++++++++ > 2 files changed, 170 insertions(+) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 2d2c066a11ba..22957d142cc0 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -266,6 +266,12 @@ struct lnet_net { > * lnet/include/lnet/nidstr.h */ > __u32 net_id; > > + /* total number of CPTs in the array */ > + __u32 net_ncpts; > + > + /* cumulative CPTs of all NIs in this net */ > + __u32 *net_cpts; > + > /* network tunables */ > struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; > > diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c > index e83bdbec11e3..380a3fb1caba 100644 > --- a/drivers/staging/lustre/lnet/lnet/config.c > +++ b/drivers/staging/lustre/lnet/lnet/config.c > @@ -91,11 +91,169 @@ lnet_net_unique(__u32 net, struct list_head *netlist) > return true; > } > > +static bool > +in_array(__u32 *array, __u32 size, __u32 value) > +{ > + int i; > + > + for (i = 0; i < size; i++) { > + if (array[i] == value) > + return false; > + } > + > + return true; > +} > + > +static int > +lnet_net_append_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net) > +{ > + __u32 *added_cpts = NULL; > + int i, j = 0, rc = 0; > + > + /* > + * no need to go futher since a subset of the NIs already exist on > + * all CPTs > + */ > + if (net->net_ncpts == LNET_CPT_NUMBER) > + return 0; > + > + if (cpts == NULL) { > + /* there is an NI which will exist on all CPTs */ > + if (net->net_cpts != NULL) > + kvfree(net->net_cpts); > + net->net_cpts = NULL; > + net->net_ncpts = LNET_CPT_NUMBER; > + return 0; > + } > + > + if (net->net_cpts == NULL) { > + net->net_cpts = kmalloc_array(ncpts, sizeof(net->net_cpts), > + GFP_KERNEL); > + if (net->net_cpts == NULL) > + return -ENOMEM; > + memcpy(net->net_cpts, cpts, ncpts); > + return 0; > + } > + > + added_cpts = kmalloc_array(LNET_CPT_NUMBER, sizeof(*added_cpts), > + GFP_KERNEL); > + if (added_cpts == NULL) > + return -ENOMEM; > + > + for (i = 0; i < ncpts; i++) { > + if (!in_array(net->net_cpts, net->net_ncpts, cpts[i])) { > + added_cpts[j] = cpts[i]; > + j++; > + } > + } > + > + /* append the new cpts if any to the list of cpts in the net */ > + if (j > 0) { > + __u32 *array = NULL, *loc; > + __u32 total_entries = j + net->net_ncpts; > + > + array = kmalloc_array(total_entries, sizeof(*net->net_cpts), > + GFP_KERNEL); > + if (array == NULL) { > + rc = -ENOMEM; > + goto failed; > + } > + > + memcpy(array, net->net_cpts, > + net->net_ncpts * sizeof(*net->net_cpts)); > + loc = array + net->net_ncpts; > + memcpy(loc, added_cpts, j * sizeof(*net->net_cpts)); > + > + kfree(net->net_cpts); > + net->net_ncpts = total_entries; > + net->net_cpts = array; > + } > + > +failed: > + kfree(added_cpts); > + > + return rc; > +} > + > +static void > +lnet_net_remove_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net) > +{ > + struct lnet_ni *ni; > + int rc; > + > + /* > + * Operation Assumption: > + * This function is called after an NI has been removed from > + * its parent net. > + * > + * if we're removing an NI which exists on all CPTs then > + * we have to check if any of the other NIs on this net also > + * exists on all CPTs. If none, then we need to build our Net CPT > + * list based on the remaining NIs. > + * > + * If the NI being removed exist on a subset of the CPTs then we > + * alo rebuild the Net CPT list based on the remaining NIs, which > + * should resutl in the expected Net CPT list. > + */ > + > + /* > + * sometimes this function can be called due to some failure > + * creating an NI, before any of the cpts are allocated, so check > + * for that case and don't do anything > + */ > + if (ncpts == 0) > + return; > + > + if (ncpts == LNET_CPT_NUMBER) { > + /* > + * first iteration through the NI list in the net to see > + * if any of the NIs exist on all the CPTs. If one is > + * found then our job is done. > + */ > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + if (ni->ni_ncpts == LNET_CPT_NUMBER) > + return; > + } > + } > + > + /* > + * Rebuild the Net CPT list again, thereby only including only the > + * CPTs which the remaining NIs are associated with. > + */ > + if (net->net_cpts != NULL) { > + kfree(net->net_cpts); > + net->net_cpts = NULL; > + } > + > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, > + net); > + if (rc != 0) { > + CERROR("Out of Memory\n"); > + /* > + * do our best to keep on going. Delete > + * the net cpts and set it to NULL. This > + * way we can keep on going but less > + * efficiently, since memory accesses might be > + * accross CPT lines. > + */ > + if (net->net_cpts != NULL) { > + kfree(net->net_cpts); > + net->net_cpts = NULL; > + net->net_ncpts = LNET_CPT_NUMBER; > + } > + return; > + } > + } > +} > + > void > lnet_ni_free(struct lnet_ni *ni) > { > int i; > > + lnet_net_remove_cpts(ni->ni_cpts, ni->ni_ncpts, ni->ni_net); > + > if (ni->ni_refs) > cfs_percpt_free(ni->ni_refs); > > @@ -128,6 +286,9 @@ lnet_net_free(struct lnet_net *net) > lnet_ni_free(ni); > } > > + if (net->net_cpts != NULL) > + kfree(net->net_cpts); > + > kfree(net); > } > > @@ -229,6 +390,9 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) > ni->ni_net_ns = NULL; > > ni->ni_last_alive = ktime_get_real_seconds(); > + rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); > + if (rc != 0) > + goto failed; > list_add_tail(&ni->ni_netlist, &net->net_ni_list); > > return ni; > > > From jsimmons at infradead.org Tue Sep 11 01:03:37 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 11 Sep 2018 02:03:37 +0100 (BST) Subject: [lustre-devel] [PATCH 10/34] lnet: add ni arg to lnet_cpt_of_nid() In-Reply-To: <153628137163.8267.8668023630519839070.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137163.8267.8668023630519839070.stgit@noble> Message-ID: > When choosing a cpt to use for a given network (identified by nid), > the choice might depend on a particular interface which has > already been identified - different interfaces can have different > sets of cpts. > > So add an 'ni' arg to lnet_cpt_of_nid(). If given, choose a cpt > from the cpts of that interface. If not given, choose one from > the set of all cpts associated with any interface on the network. Reviewed-by: James Simmons The below needs fixing based on response to cover letter. > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 4 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 4 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 2 - > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 4 +- > drivers/staging/lustre/lnet/lnet/api-ni.c | 41 ++++++++++++-------- > drivers/staging/lustre/lnet/lnet/lib-move.c | 12 +++--- > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 2 - > drivers/staging/lustre/lnet/lnet/peer.c | 4 +- > drivers/staging/lustre/lnet/lnet/router.c | 4 +- > drivers/staging/lustre/lnet/selftest/brw_test.c | 2 - > drivers/staging/lustre/lnet/selftest/framework.c | 3 + > drivers/staging/lustre/lnet/selftest/selftest.h | 2 - > 12 files changed, 48 insertions(+), 36 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 34509e52bac7..e32dbb854d80 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -395,8 +395,8 @@ lnet_net2rnethash(__u32 net) > extern struct lnet_lnd the_lolnd; > extern int avoid_asym_router_failure; > > -int lnet_cpt_of_nid_locked(lnet_nid_t nid); > -int lnet_cpt_of_nid(lnet_nid_t nid); > +int lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni); > +int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); > struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); > struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); > struct lnet_ni *lnet_net2ni(__u32 net); > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index ade566d20c69..958ac9a99045 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -320,7 +320,7 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, > { > struct kib_peer *peer; > struct kib_net *net = ni->ni_data; > - int cpt = lnet_cpt_of_nid(nid); > + int cpt = lnet_cpt_of_nid(nid, ni); > unsigned long flags; > > LASSERT(net); > @@ -643,7 +643,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm > > dev = net->ibn_dev; > > - cpt = lnet_cpt_of_nid(peer->ibp_nid); > + cpt = lnet_cpt_of_nid(peer->ibp_nid, peer->ibp_ni); > sched = kiblnd_data.kib_scheds[cpt]; > > LASSERT(sched->ibs_nthreads > 0); > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > index c266940cb2ae..e64c14914924 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > @@ -119,7 +119,7 @@ kiblnd_get_idle_tx(struct lnet_ni *ni, lnet_nid_t target) > struct kib_tx *tx; > struct kib_tx_poolset *tps; > > - tps = net->ibn_tx_ps[lnet_cpt_of_nid(target)]; > + tps = net->ibn_tx_ps[lnet_cpt_of_nid(target, ni)]; > node = kiblnd_pool_alloc_node(&tps->tps_poolset); > if (!node) > return NULL; > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 2036a0ae5917..ba68bcee90bc 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -101,7 +101,7 @@ static int > ksocknal_create_peer(struct ksock_peer **peerp, struct lnet_ni *ni, > struct lnet_process_id id) > { > - int cpt = lnet_cpt_of_nid(id.nid); > + int cpt = lnet_cpt_of_nid(id.nid, ni); > struct ksock_net *net = ni->ni_data; > struct ksock_peer *peer; > > @@ -1099,7 +1099,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, > LASSERT(conn->ksnc_proto); > LASSERT(peerid.nid != LNET_NID_ANY); > > - cpt = lnet_cpt_of_nid(peerid.nid); > + cpt = lnet_cpt_of_nid(peerid.nid, ni); > > if (active) { > ksocknal_peer_addref(peer); > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index c21aef32cdde..6e0b8310574d 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -713,31 +713,41 @@ lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) > } > > int > -lnet_cpt_of_nid_locked(lnet_nid_t nid) > +lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni) > { > - struct lnet_ni *ni; > + struct lnet_net *net; > > /* must called with hold of lnet_net_lock */ > if (LNET_CPT_NUMBER == 1) > return 0; /* the only one */ > > - /* take lnet_net_lock(any) would be OK */ > - if (!list_empty(&the_lnet.ln_nis_cpt)) { > - list_for_each_entry(ni, &the_lnet.ln_nis_cpt, ni_cptlist) { > - if (LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid)) > - continue; > + /* > + * If NI is provided then use the CPT identified in the NI cpt > + * list if one exists. If one doesn't exist, then that NI is > + * associated with all CPTs and it follows that the net it belongs > + * to is implicitly associated with all CPTs, so just hash the nid > + * and return that. > + */ > + if (ni != NULL) { > + if (ni->ni_cpts != NULL) > + return ni->ni_cpts[lnet_nid_cpt_hash(nid, > + ni->ni_ncpts)]; > + else > + return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); > + } > > - LASSERT(ni->ni_cpts); > - return ni->ni_cpts[lnet_nid_cpt_hash > - (nid, ni->ni_ncpts)]; > - } > + /* no NI provided so look at the net */ > + net = lnet_get_net_locked(LNET_NIDNET(nid)); > + > + if (net != NULL && net->net_cpts) { > + return net->net_cpts[lnet_nid_cpt_hash(nid, net->net_ncpts)]; > } > > return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); > } > > int > -lnet_cpt_of_nid(lnet_nid_t nid) > +lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni) > { > int cpt; > int cpt2; > @@ -745,11 +755,10 @@ lnet_cpt_of_nid(lnet_nid_t nid) > if (LNET_CPT_NUMBER == 1) > return 0; /* the only one */ > > - if (list_empty(&the_lnet.ln_nis_cpt)) > - return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); > - > cpt = lnet_net_lock_current(); > - cpt2 = lnet_cpt_of_nid_locked(nid); > + > + cpt2 = lnet_cpt_of_nid_locked(nid, ni); > + > lnet_net_unlock(cpt); > > return cpt2; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index b6e81a693fc3..02cd1a5a466f 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -1095,7 +1095,9 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > msg->msg_sending = 1; > > LASSERT(!msg->msg_tx_committed); > - cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid); > + local_ni = lnet_net2ni(LNET_NIDNET(dst_nid)); > + cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid, > + local_ni); > again: > lnet_net_lock(cpt); > > @@ -1188,7 +1190,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > * was changed when we release the lock > */ > if (rtr_nid != lp->lp_nid) { > - cpt2 = lnet_cpt_of_nid_locked(lp->lp_nid); > + cpt2 = lp->lp_cpt; > if (cpt2 != cpt) { > if (src_ni) > lnet_ni_decref_locked(src_ni, cpt); > @@ -1677,7 +1679,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, > payload_length = le32_to_cpu(hdr->payload_length); > > for_me = (ni->ni_nid == dest_nid); > - cpt = lnet_cpt_of_nid(from_nid); > + cpt = lnet_cpt_of_nid(from_nid, ni); > > switch (type) { > case LNET_MSG_ACK: > @@ -2149,7 +2151,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) > lnet_msg_attach_md(msg, getmd, getmd->md_offset, getmd->md_length); > lnet_res_unlock(cpt); > > - cpt = lnet_cpt_of_nid(peer_id.nid); > + cpt = lnet_cpt_of_nid(peer_id.nid, ni); > > lnet_net_lock(cpt); > lnet_msg_commit(msg, cpt); > @@ -2160,7 +2162,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) > return msg; > > drop: > - cpt = lnet_cpt_of_nid(peer_id.nid); > + cpt = lnet_cpt_of_nid(peer_id.nid, ni); > > lnet_net_lock(cpt); > the_lnet.ln_counters[cpt]->drop_count++; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > index 90ce51801726..c8d8162cc706 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > @@ -220,7 +220,7 @@ lnet_match2mt(struct lnet_portal *ptl, struct lnet_process_id id, __u64 mbits) > > /* if it's a unique portal, return match-table hashed by NID */ > return lnet_ptl_is_unique(ptl) ? > - ptl->ptl_mtables[lnet_cpt_of_nid(id.nid)] : NULL; > + ptl->ptl_mtables[lnet_cpt_of_nid(id.nid, NULL)] : NULL; > } > > struct lnet_match_table * > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index ed29124ebded..808ce25f1f00 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -270,7 +270,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > return -ESHUTDOWN; > > /* cpt can be LNET_LOCK_EX if it's called from router functions */ > - cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid); > + cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid, NULL); > > ptable = the_lnet.ln_peer_tables[cpt2]; > lp = lnet_find_peer_locked(ptable, nid); > @@ -362,7 +362,7 @@ lnet_debug_peer(lnet_nid_t nid) > int rc; > int cpt; > > - cpt = lnet_cpt_of_nid(nid); > + cpt = lnet_cpt_of_nid(nid, NULL); > lnet_net_lock(cpt); > > rc = lnet_nid2peer_locked(&lp, nid, cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 72b8ca2b0fc6..5493d13de6d9 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -1207,7 +1207,7 @@ lnet_router_checker(void *arg) > version = the_lnet.ln_routers_version; > > list_for_each_entry(rtr, &the_lnet.ln_routers, lp_rtr_list) { > - cpt2 = lnet_cpt_of_nid_locked(rtr->lp_nid); > + cpt2 = rtr->lp_cpt; > if (cpt != cpt2) { > lnet_net_unlock(cpt); > cpt = cpt2; > @@ -1693,7 +1693,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) > { > struct lnet_peer *lp = NULL; > time64_t now = ktime_get_seconds(); > - int cpt = lnet_cpt_of_nid(nid); > + int cpt = lnet_cpt_of_nid(nid, ni); > > LASSERT(!in_interrupt()); > > diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c > index f1ee219bc8f3..e372ff3044c8 100644 > --- a/drivers/staging/lustre/lnet/selftest/brw_test.c > +++ b/drivers/staging/lustre/lnet/selftest/brw_test.c > @@ -124,7 +124,7 @@ brw_client_init(struct sfw_test_instance *tsi) > return -EINVAL; > > list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) { > - bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid), > + bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid, NULL), > off, npg, len, opc == LST_BRW_READ); > if (!bulk) { > brw_client_fini(tsi); > diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c > index 944a2a6598fa..a82efc394659 100644 > --- a/drivers/staging/lustre/lnet/selftest/framework.c > +++ b/drivers/staging/lustre/lnet/selftest/framework.c > @@ -1013,7 +1013,8 @@ sfw_run_batch(struct sfw_batch *tsb) > tsu->tsu_loop = tsi->tsi_loop; > wi = &tsu->tsu_worker; > swi_init_workitem(wi, sfw_run_test, > - lst_test_wq[lnet_cpt_of_nid(tsu->tsu_dest.nid)]); > + lst_test_wq[lnet_cpt_of_nid(tsu->tsu_dest.nid, > + NULL)]); > swi_schedule_workitem(wi); > } > } > diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h > index 9dbb0a51d430..edf783af90e8 100644 > --- a/drivers/staging/lustre/lnet/selftest/selftest.h > +++ b/drivers/staging/lustre/lnet/selftest/selftest.h > @@ -527,7 +527,7 @@ srpc_init_client_rpc(struct srpc_client_rpc *rpc, struct lnet_process_id peer, > > INIT_LIST_HEAD(&rpc->crpc_list); > swi_init_workitem(&rpc->crpc_wi, srpc_send_rpc, > - lst_test_wq[lnet_cpt_of_nid(peer.nid)]); > + lst_test_wq[lnet_cpt_of_nid(peer.nid, NULL)]); > spin_lock_init(&rpc->crpc_lock); > atomic_set(&rpc->crpc_refcount, 1); /* 1 ref for caller */ > > > > From doucharek at cray.com Mon Sep 10 23:18:41 2018 From: doucharek at cray.com (Doug Oucharek) Date: Mon, 10 Sep 2018 23:18:41 +0000 Subject: [lustre-devel] [PATCH 05/34] lnet: begin separating "networks" from "network interfaces". In-Reply-To: <153628137142.8267.15402125903541546660.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137142.8267.15402125903541546660.stgit@noble> Message-ID: <702B7D05-03FF-49F9-8584-D251CD896C75@cray.com> This patch is fine and can land, just one request: Please keep style improvement like how comments look in separate patches from functional changes. Keeping them separate makes it much easier to review. Style patches take a different reviewer mindset than functional changes. The original MR patches mixes these and that made them hard to review too. Reviewed-by: Doug Oucharek > Doug On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: We already have "struct lnet_net" separate from "struct lnet_ni", but they are currently allocated together and freed together and it is assumed that they are 1-to-1. This patch starts breaking that assumption. We have separate lnet_net_alloc() and lnet_net_free() to alloc/free the new lnet_net, though they is currently called only when lnet_ni_alloc/free are called. The netid is now stored in the lnet_net and fetched directly from there, rather than extracting it from the net-interface-id ni_nid. The linkage between these two structures is now richer, lnet_net can link to a list of lnet_ni. lnet_net now has a list of lnet_net, so to find all the lnet_ni, we need to walk a list of lists. This need to walk a list-of-lists occurs in several places, and new helpers like lnet_get_ni_idx_locked() and lnet_get_next_ni_locked are introduced. Previously a list_head was passed to lnet_ni_alloc() for the new lnet_ni to be attached to. Now a list is passed to lnet_net_alloc() for the net to be attached to, and a lnet_net is passed to lnet_ni_alloc() for the ni to attach to. lnet_ni_alloc() also receives an interface name, but this is currently unused. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown > --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 15 + .../staging/lustre/include/linux/lnet/lib-types.h | 23 +- drivers/staging/lustre/lnet/lnet/acceptor.c | 2 drivers/staging/lustre/lnet/lnet/api-ni.c | 255 ++++++++++++++------ drivers/staging/lustre/lnet/lnet/config.c | 135 +++++++---- drivers/staging/lustre/lnet/lnet/lib-move.c | 6 drivers/staging/lustre/lnet/lnet/router.c | 15 - drivers/staging/lustre/lnet/lnet/router_proc.c | 16 - 8 files changed, 308 insertions(+), 159 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 0fecf0d32c58..4440b87299c4 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -369,8 +369,14 @@ lnet_ni_decref(struct lnet_ni *ni) } void lnet_ni_free(struct lnet_ni *ni); +void lnet_net_free(struct lnet_net *net); + +struct lnet_net * +lnet_net_alloc(__u32 net_type, struct list_head *netlist); + struct lnet_ni * -lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist); +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, + char *iface); static inline int lnet_nid2peerhash(lnet_nid_t nid) @@ -412,6 +418,9 @@ void lnet_destroy_routes(void); int lnet_get_route(int idx, __u32 *net, __u32 *hops, lnet_nid_t *gateway, __u32 *alive, __u32 *priority); int lnet_get_rtr_pool_cfg(int idx, struct lnet_ioctl_pool_cfg *pool_cfg); +struct lnet_ni *lnet_get_next_ni_locked(struct lnet_net *mynet, + struct lnet_ni *prev); +struct lnet_ni *lnet_get_ni_idx_locked(int idx); void lnet_router_debugfs_init(void); void lnet_router_debugfs_fini(void); @@ -584,7 +593,7 @@ int lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, __u32 local_ip, __u32 peer_ip, int peer_port); void lnet_connect_console_error(int rc, lnet_nid_t peer_nid, __u32 peer_ip, int port); -int lnet_count_acceptor_nis(void); +int lnet_count_acceptor_nets(void); int lnet_acceptor_timeout(void); int lnet_acceptor_port(void); @@ -618,7 +627,7 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); int lnet_parse_routes(char *route_str, int *im_a_router); int lnet_parse_networks(struct list_head *nilist, char *networks); -int lnet_net_unique(__u32 net, struct list_head *nilist); +bool lnet_net_unique(__u32 net, struct list_head *nilist); int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index c5e3363de727..5f0d4703bf86 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -254,6 +254,15 @@ struct lnet_tx_queue { }; struct lnet_net { + /* chain on the ln_nets */ + struct list_head net_list; + + /* net ID, which is compoed of + * (net_type << 16) | net_num. + * net_type can be one of the enumarated types defined in + * lnet/include/lnet/nidstr.h */ + __u32 net_id; + /* network tunables */ struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; @@ -264,11 +273,13 @@ struct lnet_net { bool net_tunables_set; /* procedural interface */ struct lnet_lnd *net_lnd; + /* list of NIs on this net */ + struct list_head net_ni_list; }; struct lnet_ni { - /* chain on ln_nis */ - struct list_head ni_list; + /* chain on the lnet_net structure */ + struct list_head ni_netlist; /* chain on ln_nis_cpt */ struct list_head ni_cptlist; @@ -626,14 +637,16 @@ struct lnet { /* failure simulation */ struct list_head ln_test_peers; struct list_head ln_drop_rules; - struct list_head ln_delay_rules; + struct list_head ln_delay_rules; - struct list_head ln_nis; /* LND instances */ + /* LND instances */ + struct list_head ln_nets; /* NIs bond on specific CPT(s) */ struct list_head ln_nis_cpt; /* dying LND instances */ struct list_head ln_nis_zombie; - struct lnet_ni *ln_loni; /* the loopback NI */ + /* the loopback NI */ + struct lnet_ni *ln_loni; /* remote networks with routes to them */ struct list_head *ln_remote_nets_hash; diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index f8c921f0221c..88b90c1fdbaf 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -454,7 +454,7 @@ lnet_acceptor_start(void) if (rc <= 0) return rc; - if (!lnet_count_acceptor_nis()) /* not required */ + if (lnet_count_acceptor_nets() == 0) /* not required */ return 0; task = kthread_run(lnet_acceptor, (void *)(uintptr_t)secure, diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index c944fbb155c8..05687278334a 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -537,7 +537,7 @@ lnet_prepare(lnet_pid_t requested_pid) the_lnet.ln_pid = requested_pid; INIT_LIST_HEAD(&the_lnet.ln_test_peers); - INIT_LIST_HEAD(&the_lnet.ln_nis); + INIT_LIST_HEAD(&the_lnet.ln_nets); INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); INIT_LIST_HEAD(&the_lnet.ln_routers); @@ -616,7 +616,7 @@ lnet_unprepare(void) LASSERT(!the_lnet.ln_refcount); LASSERT(list_empty(&the_lnet.ln_test_peers)); - LASSERT(list_empty(&the_lnet.ln_nis)); + LASSERT(list_empty(&the_lnet.ln_nets)); LASSERT(list_empty(&the_lnet.ln_nis_cpt)); LASSERT(list_empty(&the_lnet.ln_nis_zombie)); @@ -648,14 +648,17 @@ lnet_unprepare(void) } struct lnet_ni * -lnet_net2ni_locked(__u32 net, int cpt) +lnet_net2ni_locked(__u32 net_id, int cpt) { - struct lnet_ni *ni; + struct lnet_ni *ni; + struct lnet_net *net; LASSERT(cpt != LNET_LOCK_EX); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (LNET_NIDNET(ni->ni_nid) == net) { + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + if (net->net_id == net_id) { + ni = list_entry(net->net_ni_list.next, struct lnet_ni, + ni_netlist); lnet_ni_addref_locked(ni, cpt); return ni; } @@ -760,14 +763,17 @@ lnet_islocalnet(__u32 net) struct lnet_ni * lnet_nid2ni_locked(lnet_nid_t nid, int cpt) { - struct lnet_ni *ni; + struct lnet_net *net; + struct lnet_ni *ni; LASSERT(cpt != LNET_LOCK_EX); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (ni->ni_nid == nid) { - lnet_ni_addref_locked(ni, cpt); - return ni; + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (ni->ni_nid == nid) { + lnet_ni_addref_locked(ni, cpt); + return ni; + } } } @@ -790,16 +796,18 @@ lnet_islocalnid(lnet_nid_t nid) } int -lnet_count_acceptor_nis(void) +lnet_count_acceptor_nets(void) { /* Return the # of NIs that need the acceptor. */ - int count = 0; - struct lnet_ni *ni; - int cpt; + int count = 0; + struct lnet_net *net; + int cpt; cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (ni->ni_net->net_lnd->lnd_accept) + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + /* all socklnd type networks should have the acceptor + * thread started */ + if (net->net_lnd->lnd_accept) count++; } @@ -832,13 +840,16 @@ lnet_ping_info_create(int num_ni) static inline int lnet_get_ni_count(void) { - struct lnet_ni *ni; - int count = 0; + struct lnet_ni *ni; + struct lnet_net *net; + int count = 0; lnet_net_lock(0); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) - count++; + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) + count++; + } lnet_net_unlock(0); @@ -854,14 +865,17 @@ lnet_ping_info_free(struct lnet_ping_info *pinfo) static void lnet_ping_info_destroy(void) { + struct lnet_net *net; struct lnet_ni *ni; lnet_net_lock(LNET_LOCK_EX); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - lnet_ni_lock(ni); - ni->ni_status = NULL; - lnet_ni_unlock(ni); + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + lnet_ni_lock(ni); + ni->ni_status = NULL; + lnet_ni_unlock(ni); + } } lnet_ping_info_free(the_lnet.ln_ping_info); @@ -963,24 +977,28 @@ lnet_ping_md_unlink(struct lnet_ping_info *pinfo, static void lnet_ping_info_install_locked(struct lnet_ping_info *ping_info) { + int i = 0; struct lnet_ni_status *ns; struct lnet_ni *ni; - int i = 0; + struct lnet_net *net; - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - LASSERT(i < ping_info->pi_nnis); + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + LASSERT(i < ping_info->pi_nnis); - ns = &ping_info->pi_ni[i]; + ns = &ping_info->pi_ni[i]; - ns->ns_nid = ni->ni_nid; + ns->ns_nid = ni->ni_nid; - lnet_ni_lock(ni); - ns->ns_status = (ni->ni_status) ? - ni->ni_status->ns_status : LNET_NI_STATUS_UP; - ni->ni_status = ns; - lnet_ni_unlock(ni); + lnet_ni_lock(ni); + ns->ns_status = ni->ni_status ? + ni->ni_status->ns_status : + LNET_NI_STATUS_UP; + ni->ni_status = ns; + lnet_ni_unlock(ni); - i++; + i++; + } } } @@ -1054,9 +1072,9 @@ lnet_ni_unlink_locked(struct lnet_ni *ni) } /* move it to zombie list and nobody can find it anymore */ - LASSERT(!list_empty(&ni->ni_list)); - list_move(&ni->ni_list, &the_lnet.ln_nis_zombie); - lnet_ni_decref_locked(ni, 0); /* drop ln_nis' ref */ + LASSERT(!list_empty(&ni->ni_netlist)); + list_move(&ni->ni_netlist, &the_lnet.ln_nis_zombie); + lnet_ni_decref_locked(ni, 0); } static void @@ -1076,17 +1094,17 @@ lnet_clear_zombies_nis_locked(void) int j; ni = list_entry(the_lnet.ln_nis_zombie.next, - struct lnet_ni, ni_list); - list_del_init(&ni->ni_list); + struct lnet_ni, ni_netlist); + list_del_init(&ni->ni_netlist); cfs_percpt_for_each(ref, j, ni->ni_refs) { if (!*ref) continue; /* still busy, add it back to zombie list */ - list_add(&ni->ni_list, &the_lnet.ln_nis_zombie); + list_add(&ni->ni_netlist, &the_lnet.ln_nis_zombie); break; } - if (!list_empty(&ni->ni_list)) { + if (!list_empty(&ni->ni_netlist)) { lnet_net_unlock(LNET_LOCK_EX); ++i; if ((i & (-i)) == i) { @@ -1126,6 +1144,7 @@ lnet_shutdown_lndnis(void) { struct lnet_ni *ni; int i; + struct lnet_net *net; /* NB called holding the global mutex */ @@ -1138,10 +1157,14 @@ lnet_shutdown_lndnis(void) the_lnet.ln_shutdown = 1; /* flag shutdown */ /* Unlink NIs from the global table */ - while (!list_empty(&the_lnet.ln_nis)) { - ni = list_entry(the_lnet.ln_nis.next, - struct lnet_ni, ni_list); - lnet_ni_unlink_locked(ni); + while (!list_empty(&the_lnet.ln_nets)) { + net = list_entry(the_lnet.ln_nets.next, + struct lnet_net, net_list); + while (!list_empty(&net->net_ni_list)) { + ni = list_entry(net->net_ni_list.next, + struct lnet_ni, ni_netlist); + lnet_ni_unlink_locked(ni); + } } /* Drop the cached loopback NI. */ @@ -1212,7 +1235,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) /* Make sure this new NI is unique. */ lnet_net_lock(LNET_LOCK_EX); - rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis); + rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nets); lnet_net_unlock(LNET_LOCK_EX); if (!rc) { if (lnd_type == LOLND) { @@ -1297,7 +1320,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) lnet_net_lock(LNET_LOCK_EX); /* refcount for ln_nis */ lnet_ni_addref_locked(ni, 0); - list_add_tail(&ni->ni_list, &the_lnet.ln_nis); + list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); if (ni->ni_cpts) { lnet_ni_addref_locked(ni, 0); list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); @@ -1363,8 +1386,8 @@ lnet_startup_lndnis(struct list_head *nilist) int ni_count = 0; while (!list_empty(nilist)) { - ni = list_entry(nilist->next, struct lnet_ni, ni_list); - list_del(&ni->ni_list); + ni = list_entry(nilist->next, struct lnet_ni, ni_netlist); + list_del(&ni->ni_netlist); rc = lnet_startup_lndni(ni, NULL); if (rc < 0) @@ -1486,6 +1509,7 @@ LNetNIInit(lnet_pid_t requested_pid) struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; struct list_head net_head; + struct lnet_net *net; INIT_LIST_HEAD(&net_head); @@ -1505,8 +1529,15 @@ LNetNIInit(lnet_pid_t requested_pid) return rc; } - /* Add in the loopback network */ - if (!lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head)) { + /* create a network for Loopback network */ + net = lnet_net_alloc(LNET_MKNET(LOLND, 0), &net_head); + if (net == NULL) { + rc = -ENOMEM; + goto err_empty_list; + } + + /* Add in the loopback NI */ + if (lnet_ni_alloc(net, NULL, NULL) == NULL) { rc = -ENOMEM; goto err_empty_list; } @@ -1584,11 +1615,11 @@ LNetNIInit(lnet_pid_t requested_pid) LASSERT(rc < 0); mutex_unlock(&the_lnet.ln_api_mutex); while (!list_empty(&net_head)) { - struct lnet_ni *ni; + struct lnet_net *net; - ni = list_entry(net_head.next, struct lnet_ni, ni_list); - list_del_init(&ni->ni_list); - lnet_ni_free(ni); + net = list_entry(net_head.next, struct lnet_net, net_list); + list_del_init(&net->net_list); + lnet_net_free(net); } return rc; } @@ -1714,25 +1745,83 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) } } +struct lnet_ni * +lnet_get_ni_idx_locked(int idx) +{ + struct lnet_ni *ni; + struct lnet_net *net; + + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (idx-- == 0) + return ni; + } + } + + return NULL; +} + +struct lnet_ni * +lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev) +{ + struct lnet_ni *ni; + struct lnet_net *net = mynet; + + if (prev == NULL) { + if (net == NULL) + net = list_entry(the_lnet.ln_nets.next, struct lnet_net, + net_list); + ni = list_entry(net->net_ni_list.next, struct lnet_ni, + ni_netlist); + + return ni; + } + + if (prev->ni_netlist.next == &prev->ni_net->net_ni_list) { + /* if you reached the end of the ni list and the net is + * specified, then there are no more nis in that net */ + if (net != NULL) + return NULL; + + /* we reached the end of this net ni list. move to the + * next net */ + if (prev->ni_net->net_list.next == &the_lnet.ln_nets) + /* no more nets and no more NIs. */ + return NULL; + + /* get the next net */ + net = list_entry(prev->ni_net->net_list.next, struct lnet_net, + net_list); + /* get the ni on it */ + ni = list_entry(net->net_ni_list.next, struct lnet_ni, + ni_netlist); + + return ni; + } + + /* there are more nis left */ + ni = list_entry(prev->ni_netlist.next, struct lnet_ni, ni_netlist); + + return ni; +} + static int lnet_get_net_config(struct lnet_ioctl_config_data *config) { struct lnet_ni *ni; + int cpt; int idx = config->cfg_count; - int cpt, i = 0; int rc = -ENOENT; cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (i++ != idx) - continue; + ni = lnet_get_ni_idx_locked(idx); + if (ni != NULL) { + rc = 0; lnet_ni_lock(ni); lnet_fill_ni_info(ni, config); lnet_ni_unlock(ni); - rc = 0; - break; } lnet_net_unlock(cpt); @@ -1745,6 +1834,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) char *nets = conf->cfg_config_u.cfg_net.net_intf; struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; + struct lnet_net *net; struct lnet_ni *ni; struct list_head net_head; struct lnet_remotenet *rnet; @@ -1752,7 +1842,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) INIT_LIST_HEAD(&net_head); - /* Create a ni structure for the network string */ + /* Create a net/ni structures for the network string */ rc = lnet_parse_networks(&net_head, nets); if (rc <= 0) return !rc ? -EINVAL : rc; @@ -1760,14 +1850,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) mutex_lock(&the_lnet.ln_api_mutex); if (rc > 1) { - rc = -EINVAL; /* only add one interface per call */ + rc = -EINVAL; /* only add one network per call */ goto failed0; } - ni = list_entry(net_head.next, struct lnet_ni, ni_list); + net = list_entry(net_head.next, struct lnet_net, net_list); lnet_net_lock(LNET_LOCK_EX); - rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid)); + rnet = lnet_find_net_locked(net->net_id); lnet_net_unlock(LNET_LOCK_EX); /* * make sure that the net added doesn't invalidate the current @@ -1785,8 +1875,8 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) if (rc) goto failed0; - list_del_init(&ni->ni_list); - + list_del_init(&net->net_list); + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); rc = lnet_startup_lndni(ni, conf); if (rc) goto failed1; @@ -1812,9 +1902,9 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) failed0: mutex_unlock(&the_lnet.ln_api_mutex); while (!list_empty(&net_head)) { - ni = list_entry(net_head.next, struct lnet_ni, ni_list); - list_del_init(&ni->ni_list); - lnet_ni_free(ni); + net = list_entry(net_head.next, struct lnet_net, net_list); + list_del_init(&net->net_list); + lnet_net_free(net); } return rc; } @@ -1849,7 +1939,7 @@ lnet_dyn_del_ni(__u32 net) lnet_shutdown_lndni(ni); - if (!lnet_count_acceptor_nis()) + if (!lnet_count_acceptor_nets()) lnet_acceptor_stop(); lnet_ping_target_update(pinfo, md_handle); @@ -2103,7 +2193,8 @@ EXPORT_SYMBOL(LNetDebugPeer); int LNetGetId(unsigned int index, struct lnet_process_id *id) { - struct lnet_ni *ni; + struct lnet_ni *ni; + struct lnet_net *net; int cpt; int rc = -ENOENT; @@ -2111,14 +2202,16 @@ LNetGetId(unsigned int index, struct lnet_process_id *id) cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - if (index--) - continue; + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (index-- != 0) + continue; - id->nid = ni->ni_nid; - id->pid = the_lnet.ln_pid; - rc = 0; - break; + id->nid = ni->ni_nid; + id->pid = the_lnet.ln_pid; + rc = 0; + break; + } } lnet_net_unlock(cpt); diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 5646feeb433e..e83bdbec11e3 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -78,17 +78,17 @@ lnet_issep(char c) } } -int -lnet_net_unique(__u32 net, struct list_head *nilist) +bool +lnet_net_unique(__u32 net, struct list_head *netlist) { - struct lnet_ni *ni; + struct lnet_net *net_l; - list_for_each_entry(ni, nilist, ni_list) { - if (LNET_NIDNET(ni->ni_nid) == net) - return 0; + list_for_each_entry(net_l, netlist, net_list) { + if (net_l->net_id == net) + return false; } - return 1; + return true; } void @@ -112,41 +112,78 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_net_ns) put_net(ni->ni_net_ns); - kvfree(ni->ni_net); kfree(ni); } -struct lnet_ni * -lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) +void +lnet_net_free(struct lnet_net *net) { - struct lnet_tx_queue *tq; + struct list_head *tmp, *tmp2; struct lnet_ni *ni; - int rc; - int i; + + /* delete any nis which have been started. */ + list_for_each_safe(tmp, tmp2, &net->net_ni_list) { + ni = list_entry(tmp, struct lnet_ni, ni_netlist); + list_del_init(&ni->ni_netlist); + lnet_ni_free(ni); + } + + kfree(net); +} + +struct lnet_net * +lnet_net_alloc(__u32 net_id, struct list_head *net_list) +{ struct lnet_net *net; - if (!lnet_net_unique(net_id, nilist)) { - LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", - libcfs_net2str(net_id)); + if (!lnet_net_unique(net_id, net_list)) { + CERROR("Duplicate net %s. Ignore\n", + libcfs_net2str(net_id)); return NULL; } - ni = kzalloc(sizeof(*ni), GFP_NOFS); net = kzalloc(sizeof(*net), GFP_NOFS); - if (!ni || !net) { - kfree(ni); kfree(net); + if (!net) { CERROR("Out of memory creating network %s\n", libcfs_net2str(net_id)); return NULL; } + + INIT_LIST_HEAD(&net->net_list); + INIT_LIST_HEAD(&net->net_ni_list); + + net->net_id = net_id; + /* initialize global paramters to undefiend */ net->net_tunables.lct_peer_timeout = -1; net->net_tunables.lct_max_tx_credits = -1; net->net_tunables.lct_peer_tx_credits = -1; net->net_tunables.lct_peer_rtr_credits = -1; + list_add_tail(&net->net_list, net_list); + + return net; +} + +struct lnet_ni * +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) +{ + struct lnet_tx_queue *tq; + struct lnet_ni *ni; + int rc; + int i; + + ni = kzalloc(sizeof(*ni), GFP_KERNEL); + if (ni == NULL) { + CERROR("Out of memory creating network interface %s%s\n", + libcfs_net2str(net->net_id), + (iface != NULL) ? iface : ""); + return NULL; + } + spin_lock_init(&ni->ni_lock); INIT_LIST_HEAD(&ni->ni_cptlist); + INIT_LIST_HEAD(&ni->ni_netlist); ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*ni->ni_refs[0])); if (!ni->ni_refs) @@ -166,8 +203,9 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) } 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_id), rc); + CERROR("Failed to set CPTs for NI %s(%s): %d\n", + libcfs_net2str(net->net_id), + (iface != NULL) ? iface : "", rc); goto failed; } @@ -182,7 +220,7 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) ni->ni_net = net; /* LND will fill in the address part of the NID */ - ni->ni_nid = LNET_MKNID(net_id, 0); + ni->ni_nid = LNET_MKNID(net->net_id, 0); /* Store net namespace in which current ni is being created */ if (current->nsproxy->net_ns) @@ -191,22 +229,24 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) ni->ni_net_ns = NULL; ni->ni_last_alive = ktime_get_real_seconds(); - list_add_tail(&ni->ni_list, nilist); + list_add_tail(&ni->ni_netlist, &net->net_ni_list); + return ni; - failed: +failed: lnet_ni_free(ni); return NULL; } int -lnet_parse_networks(struct list_head *nilist, char *networks) +lnet_parse_networks(struct list_head *netlist, char *networks) { struct cfs_expr_list *el = NULL; char *tokens; char *str; char *tmp; - struct lnet_ni *ni; - __u32 net; + struct lnet_net *net; + struct lnet_ni *ni = NULL; + __u32 net_id; int nnets = 0; struct list_head *temp_node; @@ -275,18 +315,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) if (comma) *comma++ = 0; - net = libcfs_str2net(strim(str)); + net_id = libcfs_str2net(strim(str)); - if (net == LNET_NIDNET(LNET_NID_ANY)) { + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { LCONSOLE_ERROR_MSG(0x113, "Unrecognised network type\n"); tmp = str; goto failed_syntax; } - if (LNET_NETTYP(net) != LOLND && /* LO is implicit */ - !lnet_ni_alloc(net, el, nilist)) - goto failed; + if (LNET_NETTYP(net_id) != LOLND) { /* LO is implicit */ + net = lnet_net_alloc(net_id, netlist); + if (!net || + !lnet_ni_alloc(net, el, NULL)) + goto failed; + } if (el) { cfs_expr_list_free(el); @@ -298,14 +341,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) } *bracket = 0; - net = libcfs_str2net(strim(str)); - if (net == LNET_NIDNET(LNET_NID_ANY)) { + net_id = libcfs_str2net(strim(str)); + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { tmp = str; goto failed_syntax; } - ni = lnet_ni_alloc(net, el, nilist); - if (!ni) + /* always allocate a net, since we will eventually add an + * interface to it, or we will fail, in which case we'll + * just delete it */ + net = lnet_net_alloc(net_id, netlist); + if (IS_ERR_OR_NULL(net)) + goto failed; + + ni = lnet_ni_alloc(net, el, NULL); + if (IS_ERR_OR_NULL(ni)) goto failed; if (el) { @@ -337,7 +387,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) if (niface == LNET_MAX_INTERFACES) { LCONSOLE_ERROR_MSG(0x115, "Too many interfaces for net %s\n", - libcfs_net2str(net)); + libcfs_net2str(net_id)); goto failed; } @@ -378,7 +428,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) } } - list_for_each(temp_node, nilist) + list_for_each(temp_node, netlist) nnets++; kfree(tokens); @@ -387,11 +437,12 @@ lnet_parse_networks(struct list_head *nilist, char *networks) failed_syntax: lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp)); failed: - while (!list_empty(nilist)) { - ni = list_entry(nilist->next, struct lnet_ni, ni_list); + /* free the net list and all the nis on each net */ + while (!list_empty(netlist)) { + net = list_entry(netlist->next, struct lnet_net, net_list); - list_del(&ni->ni_list); - lnet_ni_free(ni); + list_del_init(&net->net_list); + lnet_net_free(net); } if (el) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 1bf12af87a20..1c874025fa74 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -2289,7 +2289,7 @@ EXPORT_SYMBOL(LNetGet); int LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) { - struct lnet_ni *ni; + struct lnet_ni *ni = NULL; struct lnet_remotenet *rnet; __u32 dstnet = LNET_NIDNET(dstnid); int hops; @@ -2307,9 +2307,9 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) cpt = lnet_net_lock_current(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { if (ni->ni_nid == dstnid) { - if (srcnidp) + if (srcnidp != NULL) *srcnidp = dstnid; if (orderp) { if (LNET_NETTYP(LNET_NIDNET(dstnid)) == LOLND) diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 0c0ec0b27982..135dfe793b0b 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -245,13 +245,10 @@ static void lnet_shuffle_seed(void) if (seeded) return; - /* - * Nodes with small feet have little entropy - * the NID for this node gives the most entropy in the low bits - */ - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { + /* Nodes with small feet have little entropy + * the NID for this node gives the most entropy in the low bits */ + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { __u32 lnd_type, seed; - lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); if (lnd_type != LOLND) { seed = (LNET_NIDADDR(ni->ni_nid) | lnd_type); @@ -807,8 +804,8 @@ lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) static void lnet_update_ni_status_locked(void) { - struct lnet_ni *ni; - time64_t now; + struct lnet_ni *ni = NULL; + time64_t now; time64_t timeout; LASSERT(the_lnet.ln_routing); @@ -817,7 +814,7 @@ lnet_update_ni_status_locked(void) max(live_router_check_interval, dead_router_check_interval); now = ktime_get_real_seconds(); - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { if (ni->ni_net->net_lnd->lnd_type == LOLND) continue; diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index f3ccd6a2b70e..2a366e9a8627 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -641,26 +641,12 @@ static int proc_lnet_nis(struct ctl_table *table, int write, "rtr", "max", "tx", "min"); LASSERT(tmpstr + tmpsiz - s > 0); } else { - struct list_head *n; struct lnet_ni *ni = NULL; int skip = *ppos - 1; lnet_net_lock(0); - n = the_lnet.ln_nis.next; - - while (n != &the_lnet.ln_nis) { - struct lnet_ni *a_ni; - - a_ni = list_entry(n, struct lnet_ni, ni_list); - if (!skip) { - ni = a_ni; - break; - } - - skip--; - n = n->next; - } + ni = lnet_get_ni_idx_locked(skip); if (ni) { struct lnet_tx_queue *tq; -------------- next part -------------- An HTML attachment was scrubbed... URL: From amir.shehata.whamcloud at gmail.com Tue Sep 11 18:31:00 2018 From: amir.shehata.whamcloud at gmail.com (Amir Shehata) Date: Tue, 11 Sep 2018 11:31:00 -0700 Subject: [lustre-devel] [PATCH 11/34] lnet: pass tun to lnet_startup_lndni, instead of full conf In-Reply-To: <153628137168.8267.1167942220741712684.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137168.8267.1167942220741712684.stgit@noble> Message-ID: This block logic that was removed from lnet_startup_lndni() is done in the LND. Each LND has its own defaults. As an example look at kiblnd_tunables_setup() and ksocknal_startup(). These tunables are LND specific and have different values per LND. So instead of configuring it in the common LNet function and then it gets overwritten again the LND. We let the LND take care of initializing to the default values that they use for that LND, if they haven't already been set by the user. Note currently dynamic configuration of these parameters work only for the o2iblnd. Socklnd and gnilnd appear to not make use of the dynamic ability. I'll create an LU ticket to add the ability to dynamically set these values to the socklnd. The tunables are divided into two parts, a common set of tunables that are common to all the LND (although each LND could have different default values), and a specific set of LND tunables which pertain to a specific LND, again that's only used by the o2iblnd at the moment. On Thu, 6 Sep 2018 at 18:00, NeilBrown wrote: > I don't understand parts of this change. > Particularly the removal for > /* If given some LND tunable parameters, parse those now to > * override the values in the NI structure. */ > > isn't clear to me. > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > drivers/staging/lustre/lnet/lnet/api-ni.c | 41 > ++++++++--------------------- > 1 file changed, 12 insertions(+), 29 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c > b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 6e0b8310574d..53ecfd700db3 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -1240,10 +1240,8 @@ lnet_shutdown_lndni(struct lnet_ni *ni) > } > > static int > -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data > *conf) > +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) > { > - struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; > - struct lnet_lnd_tunables *tun = NULL; > int rc = -EINVAL; > int lnd_type; > struct lnet_lnd *lnd; > @@ -1296,36 +1294,12 @@ lnet_startup_lndni(struct lnet_ni *ni, struct > lnet_ioctl_config_data *conf) > > ni->ni_net->net_lnd = lnd; > > - if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) { > - lnd_tunables = (struct lnet_ioctl_config_lnd_tunables > *)conf->cfg_bulk; > - tun = &lnd_tunables->lt_tun; > - } > - > if (tun) { > memcpy(&ni->ni_lnd_tunables, tun, > sizeof(*tun)); > ni->ni_lnd_tunables_set = true; > } > > - /* > - * If given some LND tunable parameters, parse those now to > - * override the values in the NI structure. > - */ > - if (conf) { > - if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) > - ni->ni_net->net_tunables.lct_peer_rtr_credits = > - > conf->cfg_config_u.cfg_net.net_peer_rtr_credits; > - if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) > - ni->ni_net->net_tunables.lct_peer_timeout = > - > conf->cfg_config_u.cfg_net.net_peer_timeout; > - if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) > - ni->ni_net->net_tunables.lct_peer_tx_credits = > - > conf->cfg_config_u.cfg_net.net_peer_tx_credits; > - if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) > - ni->ni_net->net_tunables.lct_max_tx_credits = > - > conf->cfg_config_u.cfg_net.net_max_tx_credits; > - } > - > rc = lnd->lnd_startup(ni); > > mutex_unlock(&the_lnet.ln_lnd_mutex); > @@ -1861,9 +1835,13 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct > lnet_ioctl_config_data *conf) > struct list_head net_head; > struct lnet_remotenet *rnet; > int rc; > + struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; > > INIT_LIST_HEAD(&net_head); > > + if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) > + lnd_tunables = (struct lnet_ioctl_config_lnd_tunables > *)conf->cfg_bulk; > + > /* Create a net/ni structures for the network string */ > rc = lnet_parse_networks(&net_head, nets); > if (rc <= 0) > @@ -1898,9 +1876,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct > lnet_ioctl_config_data *conf) > goto failed0; > > list_del_init(&net->net_list); > + if (lnd_tunables) > + memcpy(&net->net_tunables, > + &lnd_tunables->lt_cmn, > sizeof(lnd_tunables->lt_cmn)); > + > ni = list_first_entry(&net->net_ni_list, struct lnet_ni, > ni_netlist); > - rc = lnet_startup_lndni(ni, conf); > - if (rc) > + rc = lnet_startup_lndni(ni, (lnd_tunables ? > + &lnd_tunables->lt_tun : NULL)); > + if (rc < 0) > goto failed1; > > if (ni->ni_net->net_lnd->lnd_accept) { > > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org > -------------- next part -------------- An HTML attachment was scrubbed... URL: From neilb at suse.com Wed Sep 12 02:16:27 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 12:16:27 +1000 Subject: [lustre-devel] [PATCH 09/34] lnet: add list of cpts to lnet_net. In-Reply-To: <5BB5FEA0-B2F8-4F61-8697-EB96B1CAAC92@cray.com> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137159.8267.921309094971745898.stgit@noble> <5BB5FEA0-B2F8-4F61-8697-EB96B1CAAC92@cray.com> Message-ID: <87pnxjqx38.fsf@notabene.neil.brown.name> On Mon, Sep 10 2018, Doug Oucharek wrote: > I agree with a comment from James Simmons: __u32 should only be used when the variable is being shared with user space. We need to start converting all uses of __uXX in LNet to just uXX. Perhaps that should be a set of future patches once all of MR/DD has landed? > That seems reasonable. I dont't think this series adds significant new uses of __u32. Changing them all to u32 should, as you suggest, come later. > Reviewed-by: Doug Oucharek > Thanks, NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Wed Sep 12 02:44:29 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 12:44:29 +1000 Subject: [lustre-devel] [PATCH 01/34] struct lnet_ni - reformat comments. In-Reply-To: References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137125.8267.7825080417267355121.stgit@noble> Message-ID: <87lg87qvsi.fsf@notabene.neil.brown.name> On Tue, Sep 11 2018, James Simmons wrote: >> This is part of >> >> 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail >> local NI split > > Better commit message would be: > > Rework the commonents in lib-types.h to limit the checkpatch > chatter of being over 80 characters. Thanks, I added that text (except "commonents") and applied the same change to a bunch of other comments, so that no other patch moves comments like this. NeilBrown > > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18274 > Reviewed-by: Doug Oucharek > Reviewed-by: Olaf Weber > Signed-off-by: NeilBrown > >> --- >> .../staging/lustre/include/linux/lnet/lib-types.h | 38 +++++++++++++++----- >> 1 file changed, 29 insertions(+), 9 deletions(-) >> >> diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h >> index 6d4106fd9039..078bc97a9ebf 100644 >> --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h >> +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h >> @@ -263,18 +263,38 @@ struct lnet_ni { >> int ni_peerrtrcredits; >> /* seconds to consider peer dead */ >> int ni_peertimeout; >> - int ni_ncpts; /* number of CPTs */ >> - __u32 *ni_cpts; /* bond NI on some CPTs */ >> - lnet_nid_t ni_nid; /* interface's NID */ >> - void *ni_data; /* instance-specific data */ >> + /* number of CPTs */ >> + int ni_ncpts; >> + >> + /* bond NI on some CPTs */ >> + __u32 *ni_cpts; >> + >> + /* interface's NID */ >> + lnet_nid_t ni_nid; >> + >> + /* instance-specific data */ >> + void *ni_data; >> + >> struct lnet_lnd *ni_lnd; /* procedural interface */ >> - struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */ >> - int **ni_refs; /* percpt reference count */ >> - time64_t ni_last_alive;/* when I was last alive */ >> - struct lnet_ni_status *ni_status; /* my health status */ >> + >> + /* percpt TX queues */ >> + struct lnet_tx_queue **ni_tx_queues; >> + >> + /* percpt reference count */ >> + int **ni_refs; >> + >> + /* when I was last alive */ >> + time64_t ni_last_alive; >> + >> + /* my health status */ >> + struct lnet_ni_status *ni_status; >> + >> /* per NI LND tunables */ >> struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables; >> - /* equivalent interfaces to use */ >> + /* >> + * equivalent interfaces to use >> + * This is an array because socklnd bonding can still be configured >> + */ >> char *ni_interfaces[LNET_MAX_INTERFACES]; >> /* original net namespace */ >> struct net *ni_net_ns; >> >> >> -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Wed Sep 12 02:48:40 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 12:48:40 +1000 Subject: [lustre-devel] [PATCH 05/34] lnet: begin separating "networks" from "network interfaces". In-Reply-To: <702B7D05-03FF-49F9-8584-D251CD896C75@cray.com> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137142.8267.15402125903541546660.stgit@noble> <702B7D05-03FF-49F9-8584-D251CD896C75@cray.com> Message-ID: <87in3bqvlj.fsf@notabene.neil.brown.name> On Mon, Sep 10 2018, Doug Oucharek wrote: > This patch is fine and can land, just one request: Please keep style improvement like how comments look in separate patches from functional changes. Keeping them separate makes it much easier to review. Style patches take a different reviewer mindset than functional changes. The original MR patches mixes these and that made them hard to review too. > > Reviewed-by: Doug Oucharek > > Thanks. I agree about style changes. I was applying the patches semi-automatically and so got some style changes mixed in with the good stuff. I'm gone through the series and sorted most of that out now. I'll do that with the next series *before* I post it :-) Thanks, NeilBrown > Doug > > On Sep 6, 2018, at 5:49 PM, NeilBrown > wrote: > > We already have "struct lnet_net" separate from "struct lnet_ni", > but they are currently allocated together and freed together and > it is assumed that they are 1-to-1. > > This patch starts breaking that assumption. We have separate > lnet_net_alloc() and lnet_net_free() to alloc/free the new lnet_net, > though they is currently called only when lnet_ni_alloc/free are > called. > > The netid is now stored in the lnet_net and fetched directly from > there, rather than extracting it from the net-interface-id ni_nid. > > The linkage between these two structures is now richer, lnet_net > can link to a list of lnet_ni. lnet_net now has a list of lnet_net, > so to find all the lnet_ni, we need to walk a list of lists. > This need to walk a list-of-lists occurs in several places, and new > helpers like lnet_get_ni_idx_locked() and lnet_get_next_ni_locked are > introduced. > > Previously a list_head was passed to lnet_ni_alloc() for the new > lnet_ni to be attached to. > Now a list is passed to lnet_net_alloc() for the net to be attached > to, and a lnet_net is passed to lnet_ni_alloc() for the ni to attach > to. > lnet_ni_alloc() also receives an interface name, but this is currently > unused. > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 15 + > .../staging/lustre/include/linux/lnet/lib-types.h | 23 +- > drivers/staging/lustre/lnet/lnet/acceptor.c | 2 > drivers/staging/lustre/lnet/lnet/api-ni.c | 255 ++++++++++++++------ > drivers/staging/lustre/lnet/lnet/config.c | 135 +++++++---- > drivers/staging/lustre/lnet/lnet/lib-move.c | 6 > drivers/staging/lustre/lnet/lnet/router.c | 15 - > drivers/staging/lustre/lnet/lnet/router_proc.c | 16 - > 8 files changed, 308 insertions(+), 159 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 0fecf0d32c58..4440b87299c4 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -369,8 +369,14 @@ lnet_ni_decref(struct lnet_ni *ni) > } > > void lnet_ni_free(struct lnet_ni *ni); > +void lnet_net_free(struct lnet_net *net); > + > +struct lnet_net * > +lnet_net_alloc(__u32 net_type, struct list_head *netlist); > + > struct lnet_ni * > -lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist); > +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, > + char *iface); > > static inline int > lnet_nid2peerhash(lnet_nid_t nid) > @@ -412,6 +418,9 @@ void lnet_destroy_routes(void); > int lnet_get_route(int idx, __u32 *net, __u32 *hops, > lnet_nid_t *gateway, __u32 *alive, __u32 *priority); > int lnet_get_rtr_pool_cfg(int idx, struct lnet_ioctl_pool_cfg *pool_cfg); > +struct lnet_ni *lnet_get_next_ni_locked(struct lnet_net *mynet, > + struct lnet_ni *prev); > +struct lnet_ni *lnet_get_ni_idx_locked(int idx); > > void lnet_router_debugfs_init(void); > void lnet_router_debugfs_fini(void); > @@ -584,7 +593,7 @@ int lnet_connect(struct socket **sockp, lnet_nid_t peer_nid, > __u32 local_ip, __u32 peer_ip, int peer_port); > void lnet_connect_console_error(int rc, lnet_nid_t peer_nid, > __u32 peer_ip, int port); > -int lnet_count_acceptor_nis(void); > +int lnet_count_acceptor_nets(void); > int lnet_acceptor_timeout(void); > int lnet_acceptor_port(void); > > @@ -618,7 +627,7 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); > int lnet_parse_ip2nets(char **networksp, char *ip2nets); > int lnet_parse_routes(char *route_str, int *im_a_router); > int lnet_parse_networks(struct list_head *nilist, char *networks); > -int lnet_net_unique(__u32 net, struct list_head *nilist); > +bool lnet_net_unique(__u32 net, struct list_head *nilist); > > int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); > struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index c5e3363de727..5f0d4703bf86 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -254,6 +254,15 @@ struct lnet_tx_queue { > }; > > struct lnet_net { > + /* chain on the ln_nets */ > + struct list_head net_list; > + > + /* net ID, which is compoed of > + * (net_type << 16) | net_num. > + * net_type can be one of the enumarated types defined in > + * lnet/include/lnet/nidstr.h */ > + __u32 net_id; > + > /* network tunables */ > struct lnet_ioctl_config_lnd_cmn_tunables net_tunables; > > @@ -264,11 +273,13 @@ struct lnet_net { > bool net_tunables_set; > /* procedural interface */ > struct lnet_lnd *net_lnd; > + /* list of NIs on this net */ > + struct list_head net_ni_list; > }; > > struct lnet_ni { > - /* chain on ln_nis */ > - struct list_head ni_list; > + /* chain on the lnet_net structure */ > + struct list_head ni_netlist; > /* chain on ln_nis_cpt */ > struct list_head ni_cptlist; > > @@ -626,14 +637,16 @@ struct lnet { > /* failure simulation */ > struct list_head ln_test_peers; > struct list_head ln_drop_rules; > - struct list_head ln_delay_rules; > + struct list_head ln_delay_rules; > > - struct list_head ln_nis; /* LND instances */ > + /* LND instances */ > + struct list_head ln_nets; > /* NIs bond on specific CPT(s) */ > struct list_head ln_nis_cpt; > /* dying LND instances */ > struct list_head ln_nis_zombie; > - struct lnet_ni *ln_loni; /* the loopback NI */ > + /* the loopback NI */ > + struct lnet_ni *ln_loni; > > /* remote networks with routes to them */ > struct list_head *ln_remote_nets_hash; > diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c > index f8c921f0221c..88b90c1fdbaf 100644 > --- a/drivers/staging/lustre/lnet/lnet/acceptor.c > +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c > @@ -454,7 +454,7 @@ lnet_acceptor_start(void) > if (rc <= 0) > return rc; > > - if (!lnet_count_acceptor_nis()) /* not required */ > + if (lnet_count_acceptor_nets() == 0) /* not required */ > return 0; > > task = kthread_run(lnet_acceptor, (void *)(uintptr_t)secure, > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index c944fbb155c8..05687278334a 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -537,7 +537,7 @@ lnet_prepare(lnet_pid_t requested_pid) > the_lnet.ln_pid = requested_pid; > > INIT_LIST_HEAD(&the_lnet.ln_test_peers); > - INIT_LIST_HEAD(&the_lnet.ln_nis); > + INIT_LIST_HEAD(&the_lnet.ln_nets); > INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); > INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); > INIT_LIST_HEAD(&the_lnet.ln_routers); > @@ -616,7 +616,7 @@ lnet_unprepare(void) > > LASSERT(!the_lnet.ln_refcount); > LASSERT(list_empty(&the_lnet.ln_test_peers)); > - LASSERT(list_empty(&the_lnet.ln_nis)); > + LASSERT(list_empty(&the_lnet.ln_nets)); > LASSERT(list_empty(&the_lnet.ln_nis_cpt)); > LASSERT(list_empty(&the_lnet.ln_nis_zombie)); > > @@ -648,14 +648,17 @@ lnet_unprepare(void) > } > > struct lnet_ni * > -lnet_net2ni_locked(__u32 net, int cpt) > +lnet_net2ni_locked(__u32 net_id, int cpt) > { > - struct lnet_ni *ni; > + struct lnet_ni *ni; > + struct lnet_net *net; > > LASSERT(cpt != LNET_LOCK_EX); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (LNET_NIDNET(ni->ni_nid) == net) { > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + if (net->net_id == net_id) { > + ni = list_entry(net->net_ni_list.next, struct lnet_ni, > + ni_netlist); > lnet_ni_addref_locked(ni, cpt); > return ni; > } > @@ -760,14 +763,17 @@ lnet_islocalnet(__u32 net) > struct lnet_ni * > lnet_nid2ni_locked(lnet_nid_t nid, int cpt) > { > - struct lnet_ni *ni; > + struct lnet_net *net; > + struct lnet_ni *ni; > > LASSERT(cpt != LNET_LOCK_EX); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_nid == nid) { > - lnet_ni_addref_locked(ni, cpt); > - return ni; > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + if (ni->ni_nid == nid) { > + lnet_ni_addref_locked(ni, cpt); > + return ni; > + } > } > } > > @@ -790,16 +796,18 @@ lnet_islocalnid(lnet_nid_t nid) > } > > int > -lnet_count_acceptor_nis(void) > +lnet_count_acceptor_nets(void) > { > /* Return the # of NIs that need the acceptor. */ > - int count = 0; > - struct lnet_ni *ni; > - int cpt; > + int count = 0; > + struct lnet_net *net; > + int cpt; > > cpt = lnet_net_lock_current(); > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (ni->ni_net->net_lnd->lnd_accept) > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + /* all socklnd type networks should have the acceptor > + * thread started */ > + if (net->net_lnd->lnd_accept) > count++; > } > > @@ -832,13 +840,16 @@ lnet_ping_info_create(int num_ni) > static inline int > lnet_get_ni_count(void) > { > - struct lnet_ni *ni; > - int count = 0; > + struct lnet_ni *ni; > + struct lnet_net *net; > + int count = 0; > > lnet_net_lock(0); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) > - count++; > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) > + count++; > + } > > lnet_net_unlock(0); > > @@ -854,14 +865,17 @@ lnet_ping_info_free(struct lnet_ping_info *pinfo) > static void > lnet_ping_info_destroy(void) > { > + struct lnet_net *net; > struct lnet_ni *ni; > > lnet_net_lock(LNET_LOCK_EX); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - lnet_ni_lock(ni); > - ni->ni_status = NULL; > - lnet_ni_unlock(ni); > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + lnet_ni_lock(ni); > + ni->ni_status = NULL; > + lnet_ni_unlock(ni); > + } > } > > lnet_ping_info_free(the_lnet.ln_ping_info); > @@ -963,24 +977,28 @@ lnet_ping_md_unlink(struct lnet_ping_info *pinfo, > static void > lnet_ping_info_install_locked(struct lnet_ping_info *ping_info) > { > + int i = 0; > struct lnet_ni_status *ns; > struct lnet_ni *ni; > - int i = 0; > + struct lnet_net *net; > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - LASSERT(i < ping_info->pi_nnis); > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + LASSERT(i < ping_info->pi_nnis); > > - ns = &ping_info->pi_ni[i]; > + ns = &ping_info->pi_ni[i]; > > - ns->ns_nid = ni->ni_nid; > + ns->ns_nid = ni->ni_nid; > > - lnet_ni_lock(ni); > - ns->ns_status = (ni->ni_status) ? > - ni->ni_status->ns_status : LNET_NI_STATUS_UP; > - ni->ni_status = ns; > - lnet_ni_unlock(ni); > + lnet_ni_lock(ni); > + ns->ns_status = ni->ni_status ? > + ni->ni_status->ns_status : > + LNET_NI_STATUS_UP; > + ni->ni_status = ns; > + lnet_ni_unlock(ni); > > - i++; > + i++; > + } > } > } > > @@ -1054,9 +1072,9 @@ lnet_ni_unlink_locked(struct lnet_ni *ni) > } > > /* move it to zombie list and nobody can find it anymore */ > - LASSERT(!list_empty(&ni->ni_list)); > - list_move(&ni->ni_list, &the_lnet.ln_nis_zombie); > - lnet_ni_decref_locked(ni, 0); /* drop ln_nis' ref */ > + LASSERT(!list_empty(&ni->ni_netlist)); > + list_move(&ni->ni_netlist, &the_lnet.ln_nis_zombie); > + lnet_ni_decref_locked(ni, 0); > } > > static void > @@ -1076,17 +1094,17 @@ lnet_clear_zombies_nis_locked(void) > int j; > > ni = list_entry(the_lnet.ln_nis_zombie.next, > - struct lnet_ni, ni_list); > - list_del_init(&ni->ni_list); > + struct lnet_ni, ni_netlist); > + list_del_init(&ni->ni_netlist); > cfs_percpt_for_each(ref, j, ni->ni_refs) { > if (!*ref) > continue; > /* still busy, add it back to zombie list */ > - list_add(&ni->ni_list, &the_lnet.ln_nis_zombie); > + list_add(&ni->ni_netlist, &the_lnet.ln_nis_zombie); > break; > } > > - if (!list_empty(&ni->ni_list)) { > + if (!list_empty(&ni->ni_netlist)) { > lnet_net_unlock(LNET_LOCK_EX); > ++i; > if ((i & (-i)) == i) { > @@ -1126,6 +1144,7 @@ lnet_shutdown_lndnis(void) > { > struct lnet_ni *ni; > int i; > + struct lnet_net *net; > > /* NB called holding the global mutex */ > > @@ -1138,10 +1157,14 @@ lnet_shutdown_lndnis(void) > the_lnet.ln_shutdown = 1; /* flag shutdown */ > > /* Unlink NIs from the global table */ > - while (!list_empty(&the_lnet.ln_nis)) { > - ni = list_entry(the_lnet.ln_nis.next, > - struct lnet_ni, ni_list); > - lnet_ni_unlink_locked(ni); > + while (!list_empty(&the_lnet.ln_nets)) { > + net = list_entry(the_lnet.ln_nets.next, > + struct lnet_net, net_list); > + while (!list_empty(&net->net_ni_list)) { > + ni = list_entry(net->net_ni_list.next, > + struct lnet_ni, ni_netlist); > + lnet_ni_unlink_locked(ni); > + } > } > > /* Drop the cached loopback NI. */ > @@ -1212,7 +1235,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > > /* Make sure this new NI is unique. */ > lnet_net_lock(LNET_LOCK_EX); > - rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis); > + rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nets); > lnet_net_unlock(LNET_LOCK_EX); > if (!rc) { > if (lnd_type == LOLND) { > @@ -1297,7 +1320,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) > lnet_net_lock(LNET_LOCK_EX); > /* refcount for ln_nis */ > lnet_ni_addref_locked(ni, 0); > - list_add_tail(&ni->ni_list, &the_lnet.ln_nis); > + list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); > if (ni->ni_cpts) { > lnet_ni_addref_locked(ni, 0); > list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); > @@ -1363,8 +1386,8 @@ lnet_startup_lndnis(struct list_head *nilist) > int ni_count = 0; > > while (!list_empty(nilist)) { > - ni = list_entry(nilist->next, struct lnet_ni, ni_list); > - list_del(&ni->ni_list); > + ni = list_entry(nilist->next, struct lnet_ni, ni_netlist); > + list_del(&ni->ni_netlist); > rc = lnet_startup_lndni(ni, NULL); > > if (rc < 0) > @@ -1486,6 +1509,7 @@ LNetNIInit(lnet_pid_t requested_pid) > struct lnet_ping_info *pinfo; > struct lnet_handle_md md_handle; > struct list_head net_head; > + struct lnet_net *net; > > INIT_LIST_HEAD(&net_head); > > @@ -1505,8 +1529,15 @@ LNetNIInit(lnet_pid_t requested_pid) > return rc; > } > > - /* Add in the loopback network */ > - if (!lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head)) { > + /* create a network for Loopback network */ > + net = lnet_net_alloc(LNET_MKNET(LOLND, 0), &net_head); > + if (net == NULL) { > + rc = -ENOMEM; > + goto err_empty_list; > + } > + > + /* Add in the loopback NI */ > + if (lnet_ni_alloc(net, NULL, NULL) == NULL) { > rc = -ENOMEM; > goto err_empty_list; > } > @@ -1584,11 +1615,11 @@ LNetNIInit(lnet_pid_t requested_pid) > LASSERT(rc < 0); > mutex_unlock(&the_lnet.ln_api_mutex); > while (!list_empty(&net_head)) { > - struct lnet_ni *ni; > + struct lnet_net *net; > > - ni = list_entry(net_head.next, struct lnet_ni, ni_list); > - list_del_init(&ni->ni_list); > - lnet_ni_free(ni); > + net = list_entry(net_head.next, struct lnet_net, net_list); > + list_del_init(&net->net_list); > + lnet_net_free(net); > } > return rc; > } > @@ -1714,25 +1745,83 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) > } > } > > +struct lnet_ni * > +lnet_get_ni_idx_locked(int idx) > +{ > + struct lnet_ni *ni; > + struct lnet_net *net; > + > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + if (idx-- == 0) > + return ni; > + } > + } > + > + return NULL; > +} > + > +struct lnet_ni * > +lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev) > +{ > + struct lnet_ni *ni; > + struct lnet_net *net = mynet; > + > + if (prev == NULL) { > + if (net == NULL) > + net = list_entry(the_lnet.ln_nets.next, struct lnet_net, > + net_list); > + ni = list_entry(net->net_ni_list.next, struct lnet_ni, > + ni_netlist); > + > + return ni; > + } > + > + if (prev->ni_netlist.next == &prev->ni_net->net_ni_list) { > + /* if you reached the end of the ni list and the net is > + * specified, then there are no more nis in that net */ > + if (net != NULL) > + return NULL; > + > + /* we reached the end of this net ni list. move to the > + * next net */ > + if (prev->ni_net->net_list.next == &the_lnet.ln_nets) > + /* no more nets and no more NIs. */ > + return NULL; > + > + /* get the next net */ > + net = list_entry(prev->ni_net->net_list.next, struct lnet_net, > + net_list); > + /* get the ni on it */ > + ni = list_entry(net->net_ni_list.next, struct lnet_ni, > + ni_netlist); > + > + return ni; > + } > + > + /* there are more nis left */ > + ni = list_entry(prev->ni_netlist.next, struct lnet_ni, ni_netlist); > + > + return ni; > +} > + > static int > lnet_get_net_config(struct lnet_ioctl_config_data *config) > { > struct lnet_ni *ni; > + int cpt; > int idx = config->cfg_count; > - int cpt, i = 0; > int rc = -ENOENT; > > cpt = lnet_net_lock_current(); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (i++ != idx) > - continue; > + ni = lnet_get_ni_idx_locked(idx); > > + if (ni != NULL) { > + rc = 0; > lnet_ni_lock(ni); > lnet_fill_ni_info(ni, config); > lnet_ni_unlock(ni); > - rc = 0; > - break; > } > > lnet_net_unlock(cpt); > @@ -1745,6 +1834,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > char *nets = conf->cfg_config_u.cfg_net.net_intf; > struct lnet_ping_info *pinfo; > struct lnet_handle_md md_handle; > + struct lnet_net *net; > struct lnet_ni *ni; > struct list_head net_head; > struct lnet_remotenet *rnet; > @@ -1752,7 +1842,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > > INIT_LIST_HEAD(&net_head); > > - /* Create a ni structure for the network string */ > + /* Create a net/ni structures for the network string */ > rc = lnet_parse_networks(&net_head, nets); > if (rc <= 0) > return !rc ? -EINVAL : rc; > @@ -1760,14 +1850,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > mutex_lock(&the_lnet.ln_api_mutex); > > if (rc > 1) { > - rc = -EINVAL; /* only add one interface per call */ > + rc = -EINVAL; /* only add one network per call */ > goto failed0; > } > > - ni = list_entry(net_head.next, struct lnet_ni, ni_list); > + net = list_entry(net_head.next, struct lnet_net, net_list); > > lnet_net_lock(LNET_LOCK_EX); > - rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid)); > + rnet = lnet_find_net_locked(net->net_id); > lnet_net_unlock(LNET_LOCK_EX); > /* > * make sure that the net added doesn't invalidate the current > @@ -1785,8 +1875,8 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > if (rc) > goto failed0; > > - list_del_init(&ni->ni_list); > - > + list_del_init(&net->net_list); > + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); > rc = lnet_startup_lndni(ni, conf); > if (rc) > goto failed1; > @@ -1812,9 +1902,9 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) > failed0: > mutex_unlock(&the_lnet.ln_api_mutex); > while (!list_empty(&net_head)) { > - ni = list_entry(net_head.next, struct lnet_ni, ni_list); > - list_del_init(&ni->ni_list); > - lnet_ni_free(ni); > + net = list_entry(net_head.next, struct lnet_net, net_list); > + list_del_init(&net->net_list); > + lnet_net_free(net); > } > return rc; > } > @@ -1849,7 +1939,7 @@ lnet_dyn_del_ni(__u32 net) > > lnet_shutdown_lndni(ni); > > - if (!lnet_count_acceptor_nis()) > + if (!lnet_count_acceptor_nets()) > lnet_acceptor_stop(); > > lnet_ping_target_update(pinfo, md_handle); > @@ -2103,7 +2193,8 @@ EXPORT_SYMBOL(LNetDebugPeer); > int > LNetGetId(unsigned int index, struct lnet_process_id *id) > { > - struct lnet_ni *ni; > + struct lnet_ni *ni; > + struct lnet_net *net; > int cpt; > int rc = -ENOENT; > > @@ -2111,14 +2202,16 @@ LNetGetId(unsigned int index, struct lnet_process_id *id) > > cpt = lnet_net_lock_current(); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > - if (index--) > - continue; > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + if (index-- != 0) > + continue; > > - id->nid = ni->ni_nid; > - id->pid = the_lnet.ln_pid; > - rc = 0; > - break; > + id->nid = ni->ni_nid; > + id->pid = the_lnet.ln_pid; > + rc = 0; > + break; > + } > } > > lnet_net_unlock(cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c > index 5646feeb433e..e83bdbec11e3 100644 > --- a/drivers/staging/lustre/lnet/lnet/config.c > +++ b/drivers/staging/lustre/lnet/lnet/config.c > @@ -78,17 +78,17 @@ lnet_issep(char c) > } > } > > -int > -lnet_net_unique(__u32 net, struct list_head *nilist) > +bool > +lnet_net_unique(__u32 net, struct list_head *netlist) > { > - struct lnet_ni *ni; > + struct lnet_net *net_l; > > - list_for_each_entry(ni, nilist, ni_list) { > - if (LNET_NIDNET(ni->ni_nid) == net) > - return 0; > + list_for_each_entry(net_l, netlist, net_list) { > + if (net_l->net_id == net) > + return false; > } > > - return 1; > + return true; > } > > void > @@ -112,41 +112,78 @@ lnet_ni_free(struct lnet_ni *ni) > if (ni->ni_net_ns) > put_net(ni->ni_net_ns); > > - kvfree(ni->ni_net); > kfree(ni); > } > > -struct lnet_ni * > -lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > +void > +lnet_net_free(struct lnet_net *net) > { > - struct lnet_tx_queue *tq; > + struct list_head *tmp, *tmp2; > struct lnet_ni *ni; > - int rc; > - int i; > + > + /* delete any nis which have been started. */ > + list_for_each_safe(tmp, tmp2, &net->net_ni_list) { > + ni = list_entry(tmp, struct lnet_ni, ni_netlist); > + list_del_init(&ni->ni_netlist); > + lnet_ni_free(ni); > + } > + > + kfree(net); > +} > + > +struct lnet_net * > +lnet_net_alloc(__u32 net_id, struct list_head *net_list) > +{ > struct lnet_net *net; > > - if (!lnet_net_unique(net_id, nilist)) { > - LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n", > - libcfs_net2str(net_id)); > + if (!lnet_net_unique(net_id, net_list)) { > + CERROR("Duplicate net %s. Ignore\n", > + libcfs_net2str(net_id)); > return NULL; > } > > - ni = kzalloc(sizeof(*ni), GFP_NOFS); > net = kzalloc(sizeof(*net), GFP_NOFS); > - if (!ni || !net) { > - kfree(ni); kfree(net); > + if (!net) { > CERROR("Out of memory creating network %s\n", > libcfs_net2str(net_id)); > return NULL; > } > + > + INIT_LIST_HEAD(&net->net_list); > + INIT_LIST_HEAD(&net->net_ni_list); > + > + net->net_id = net_id; > + > /* initialize global paramters to undefiend */ > net->net_tunables.lct_peer_timeout = -1; > net->net_tunables.lct_max_tx_credits = -1; > net->net_tunables.lct_peer_tx_credits = -1; > net->net_tunables.lct_peer_rtr_credits = -1; > > + list_add_tail(&net->net_list, net_list); > + > + return net; > +} > + > +struct lnet_ni * > +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) > +{ > + struct lnet_tx_queue *tq; > + struct lnet_ni *ni; > + int rc; > + int i; > + > + ni = kzalloc(sizeof(*ni), GFP_KERNEL); > + if (ni == NULL) { > + CERROR("Out of memory creating network interface %s%s\n", > + libcfs_net2str(net->net_id), > + (iface != NULL) ? iface : ""); > + return NULL; > + } > + > spin_lock_init(&ni->ni_lock); > INIT_LIST_HEAD(&ni->ni_cptlist); > + INIT_LIST_HEAD(&ni->ni_netlist); > ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(), > sizeof(*ni->ni_refs[0])); > if (!ni->ni_refs) > @@ -166,8 +203,9 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > } 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_id), rc); > + CERROR("Failed to set CPTs for NI %s(%s): %d\n", > + libcfs_net2str(net->net_id), > + (iface != NULL) ? iface : "", rc); > goto failed; > } > > @@ -182,7 +220,7 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > > ni->ni_net = net; > /* LND will fill in the address part of the NID */ > - ni->ni_nid = LNET_MKNID(net_id, 0); > + ni->ni_nid = LNET_MKNID(net->net_id, 0); > > /* Store net namespace in which current ni is being created */ > if (current->nsproxy->net_ns) > @@ -191,22 +229,24 @@ lnet_ni_alloc(__u32 net_id, struct cfs_expr_list *el, struct list_head *nilist) > ni->ni_net_ns = NULL; > > ni->ni_last_alive = ktime_get_real_seconds(); > - list_add_tail(&ni->ni_list, nilist); > + list_add_tail(&ni->ni_netlist, &net->net_ni_list); > + > return ni; > - failed: > +failed: > lnet_ni_free(ni); > return NULL; > } > > int > -lnet_parse_networks(struct list_head *nilist, char *networks) > +lnet_parse_networks(struct list_head *netlist, char *networks) > { > struct cfs_expr_list *el = NULL; > char *tokens; > char *str; > char *tmp; > - struct lnet_ni *ni; > - __u32 net; > + struct lnet_net *net; > + struct lnet_ni *ni = NULL; > + __u32 net_id; > int nnets = 0; > struct list_head *temp_node; > > @@ -275,18 +315,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > > if (comma) > *comma++ = 0; > - net = libcfs_str2net(strim(str)); > + net_id = libcfs_str2net(strim(str)); > > - if (net == LNET_NIDNET(LNET_NID_ANY)) { > + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { > LCONSOLE_ERROR_MSG(0x113, > "Unrecognised network type\n"); > tmp = str; > goto failed_syntax; > } > > - if (LNET_NETTYP(net) != LOLND && /* LO is implicit */ > - !lnet_ni_alloc(net, el, nilist)) > - goto failed; > + if (LNET_NETTYP(net_id) != LOLND) { /* LO is implicit */ > + net = lnet_net_alloc(net_id, netlist); > + if (!net || > + !lnet_ni_alloc(net, el, NULL)) > + goto failed; > + } > > if (el) { > cfs_expr_list_free(el); > @@ -298,14 +341,21 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > } > > *bracket = 0; > - net = libcfs_str2net(strim(str)); > - if (net == LNET_NIDNET(LNET_NID_ANY)) { > + net_id = libcfs_str2net(strim(str)); > + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { > tmp = str; > goto failed_syntax; > } > > - ni = lnet_ni_alloc(net, el, nilist); > - if (!ni) > + /* always allocate a net, since we will eventually add an > + * interface to it, or we will fail, in which case we'll > + * just delete it */ > + net = lnet_net_alloc(net_id, netlist); > + if (IS_ERR_OR_NULL(net)) > + goto failed; > + > + ni = lnet_ni_alloc(net, el, NULL); > + if (IS_ERR_OR_NULL(ni)) > goto failed; > > if (el) { > @@ -337,7 +387,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > if (niface == LNET_MAX_INTERFACES) { > LCONSOLE_ERROR_MSG(0x115, > "Too many interfaces for net %s\n", > - libcfs_net2str(net)); > + libcfs_net2str(net_id)); > goto failed; > } > > @@ -378,7 +428,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > } > } > > - list_for_each(temp_node, nilist) > + list_for_each(temp_node, netlist) > nnets++; > > kfree(tokens); > @@ -387,11 +437,12 @@ lnet_parse_networks(struct list_head *nilist, char *networks) > failed_syntax: > lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp)); > failed: > - while (!list_empty(nilist)) { > - ni = list_entry(nilist->next, struct lnet_ni, ni_list); > + /* free the net list and all the nis on each net */ > + while (!list_empty(netlist)) { > + net = list_entry(netlist->next, struct lnet_net, net_list); > > - list_del(&ni->ni_list); > - lnet_ni_free(ni); > + list_del_init(&net->net_list); > + lnet_net_free(net); > } > > if (el) > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index 1bf12af87a20..1c874025fa74 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -2289,7 +2289,7 @@ EXPORT_SYMBOL(LNetGet); > int > LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) > { > - struct lnet_ni *ni; > + struct lnet_ni *ni = NULL; > struct lnet_remotenet *rnet; > __u32 dstnet = LNET_NIDNET(dstnid); > int hops; > @@ -2307,9 +2307,9 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) > > cpt = lnet_net_lock_current(); > > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { > if (ni->ni_nid == dstnid) { > - if (srcnidp) > + if (srcnidp != NULL) > *srcnidp = dstnid; > if (orderp) { > if (LNET_NETTYP(LNET_NIDNET(dstnid)) == LOLND) > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 0c0ec0b27982..135dfe793b0b 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -245,13 +245,10 @@ static void lnet_shuffle_seed(void) > if (seeded) > return; > > - /* > - * Nodes with small feet have little entropy > - * the NID for this node gives the most entropy in the low bits > - */ > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > + /* Nodes with small feet have little entropy > + * the NID for this node gives the most entropy in the low bits */ > + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { > __u32 lnd_type, seed; > - > lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); > if (lnd_type != LOLND) { > seed = (LNET_NIDADDR(ni->ni_nid) | lnd_type); > @@ -807,8 +804,8 @@ lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) > static void > lnet_update_ni_status_locked(void) > { > - struct lnet_ni *ni; > - time64_t now; > + struct lnet_ni *ni = NULL; > + time64_t now; > time64_t timeout; > > LASSERT(the_lnet.ln_routing); > @@ -817,7 +814,7 @@ lnet_update_ni_status_locked(void) > max(live_router_check_interval, dead_router_check_interval); > > now = ktime_get_real_seconds(); > - list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { > + while ((ni = lnet_get_next_ni_locked(NULL, ni))) { > if (ni->ni_net->net_lnd->lnd_type == LOLND) > continue; > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index f3ccd6a2b70e..2a366e9a8627 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -641,26 +641,12 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > "rtr", "max", "tx", "min"); > LASSERT(tmpstr + tmpsiz - s > 0); > } else { > - struct list_head *n; > struct lnet_ni *ni = NULL; > int skip = *ppos - 1; > > lnet_net_lock(0); > > - n = the_lnet.ln_nis.next; > - > - while (n != &the_lnet.ln_nis) { > - struct lnet_ni *a_ni; > - > - a_ni = list_entry(n, struct lnet_ni, ni_list); > - if (!skip) { > - ni = a_ni; > - break; > - } > - > - skip--; > - n = n->next; > - } > + ni = lnet_get_ni_idx_locked(skip); > > if (ni) { > struct lnet_tx_queue *tq; -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Wed Sep 12 02:56:06 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 12:56:06 +1000 Subject: [lustre-devel] [PATCH 07/34] lnet: change lnet_peer to reference the net, rather than ni. In-Reply-To: References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137151.8267.3943711043829439593.stgit@noble> Message-ID: <87ftyfqv95.fsf@notabene.neil.brown.name> On Tue, Sep 11 2018, James Simmons wrote: >> @@ -1164,10 +1164,12 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) >> /* ENOMEM or shutting down */ >> return rc; >> } >> - LASSERT(lp->lp_ni == src_ni); >> + LASSERT(lp->lp_net == src_ni->ni_net); >> } else { >> /* sending to a remote network */ >> - lp = lnet_find_route_locked(src_ni, dst_nid, rtr_nid); >> + lp = lnet_find_route_locked(src_ni != NULL ? >> + src_ni->ni_net : NULL, >> + dst_nid, rtr_nid); >> if (!lp) { >> if (src_ni) >> lnet_ni_decref_locked(src_ni, cpt); >> @@ -1203,10 +1205,11 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) >> lnet_msgtyp2str(msg->msg_type), msg->msg_len); >> >> if (!src_ni) { >> - src_ni = lp->lp_ni; >> + src_ni = lnet_get_next_ni_locked(lp->lp_net, NULL); >> + LASSERT(src_ni != NULL); > > Checkpatch will not like the above. I think checkpatch is sometimes wrong. However I went through the series removing all "== NULL" and "!= NULL". >> >> - lp->lp_ni = lnet_net2ni_locked(LNET_NIDNET(nid), cpt2); >> - if (!lp->lp_ni) { >> - rc = -EHOSTUNREACH; >> - goto out; >> - } >> - >> - lp->lp_txcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; >> - lp->lp_mintxcredits = lp->lp_ni->ni_net->net_tunables.lct_peer_tx_credits; >> - lp->lp_rtrcredits = lnet_peer_buffer_credits(lp->lp_ni); >> - lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni); >> + lp->lp_net = lnet_get_net_locked(LNET_NIDNET(!lp->lp_nid)); > > This is the single error in your port that broke stuff. The correct code > is: > > lp->lp_net = lnet_get_net_locked(LNET_NIDNET(lp->lp_nid)); > Thanks for spotting that!! >> @@ -952,6 +950,7 @@ lnet_ping_router_locked(struct lnet_peer *rtr) >> struct lnet_rc_data *rcd = NULL; >> time64_t now = ktime_get_seconds(); >> time64_t secs; >> + struct lnet_ni *ni; > > Another grep from Greg was the spacing in declared variables. As I port > patches new code removes the spacing. Newer lustre code no long does > this kind of spacing. Well most of it :-) > I went through the series are removed all the stray space in local variable decls. Thanks, NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From doucharek at cray.com Wed Sep 12 03:30:58 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 03:30:58 +0000 Subject: [lustre-devel] [PATCH 11/34] lnet: pass tun to lnet_startup_lndni, instead of full conf In-Reply-To: <153628137168.8267.1167942220741712684.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137168.8267.1167942220741712684.stgit@noble> Message-ID: <83C2283B-AFA7-47D6-925D-D2E4ECD95FF0@cray.com> With the suggested commit message from Amir: Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:53 PM, "NeilBrown" wrote: I don't understand parts of this change. Particularly the removal for /* If given some LND tunable parameters, parse those now to * override the values in the NI structure. */ isn't clear to me. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 41 ++++++++--------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 6e0b8310574d..53ecfd700db3 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1240,10 +1240,8 @@ lnet_shutdown_lndni(struct lnet_ni *ni) } static int -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) { - struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; - struct lnet_lnd_tunables *tun = NULL; int rc = -EINVAL; int lnd_type; struct lnet_lnd *lnd; @@ -1296,36 +1294,12 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) ni->ni_net->net_lnd = lnd; - if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) { - lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; - tun = &lnd_tunables->lt_tun; - } - if (tun) { memcpy(&ni->ni_lnd_tunables, tun, sizeof(*tun)); ni->ni_lnd_tunables_set = true; } - /* - * If given some LND tunable parameters, parse those now to - * override the values in the NI structure. - */ - if (conf) { - if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) - ni->ni_net->net_tunables.lct_peer_rtr_credits = - conf->cfg_config_u.cfg_net.net_peer_rtr_credits; - if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) - ni->ni_net->net_tunables.lct_peer_timeout = - conf->cfg_config_u.cfg_net.net_peer_timeout; - if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) - ni->ni_net->net_tunables.lct_peer_tx_credits = - conf->cfg_config_u.cfg_net.net_peer_tx_credits; - if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) - ni->ni_net->net_tunables.lct_max_tx_credits = - conf->cfg_config_u.cfg_net.net_max_tx_credits; - } - rc = lnd->lnd_startup(ni); mutex_unlock(&the_lnet.ln_lnd_mutex); @@ -1861,9 +1835,13 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) struct list_head net_head; struct lnet_remotenet *rnet; int rc; + struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; INIT_LIST_HEAD(&net_head); + if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) + lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; + /* Create a net/ni structures for the network string */ rc = lnet_parse_networks(&net_head, nets); if (rc <= 0) @@ -1898,9 +1876,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) goto failed0; list_del_init(&net->net_list); + if (lnd_tunables) + memcpy(&net->net_tunables, + &lnd_tunables->lt_cmn, sizeof(lnd_tunables->lt_cmn)); + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); - rc = lnet_startup_lndni(ni, conf); - if (rc) + rc = lnet_startup_lndni(ni, (lnd_tunables ? + &lnd_tunables->lt_tun : NULL)); + if (rc < 0) goto failed1; if (ni->ni_net->net_lnd->lnd_accept) { From doucharek at cray.com Wed Sep 12 03:39:16 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 03:39:16 +0000 Subject: [lustre-devel] [PATCH 12/34] lnet: split lnet_startup_lndni In-Reply-To: <153628137171.8267.13510813931908233567.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137171.8267.13510813931908233567.stgit@noble> Message-ID: <9EA5BEB2-C7A3-472D-A396-A5C728E403D8@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:53 PM, "NeilBrown" wrote: Split into lnet_startup_lndnet which starts all nis in a net, and lnet_startup_lndni which starts an individual ni. lnet_startup_lndni() returns 0 on success, or -ve error. lnet_startup_lndnis() returned the count of interfaces started. The new lnet_startup_lndnet() returns the count of started interfaces, This requires adding lnet_shutdown_lndnet() to handle errors in lnet_dyn_add_ni(), which now uses the new lnet_startup_lndnet(). We now drop the ln_lnd_mutex near the end of lnet_startup_lndnet(), and re-claim it for each lnet_startup_lndni(). This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 142 +++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 31 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 53ecfd700db3..8afddf11b5e2 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1239,32 +1239,61 @@ lnet_shutdown_lndni(struct lnet_ni *ni) lnet_net_unlock(LNET_LOCK_EX); } +static void +lnet_shutdown_lndnet(struct lnet_net *net) +{ + struct lnet_ni *ni; + + lnet_net_lock(LNET_LOCK_EX); + + list_del_init(&net->net_list); + + while (!list_empty(&net->net_ni_list)) { + ni = list_entry(net->net_ni_list.next, + struct lnet_ni, ni_netlist); + lnet_net_unlock(LNET_LOCK_EX); + lnet_shutdown_lndni(ni); + lnet_net_lock(LNET_LOCK_EX); + } + + /* + * decrement ref count on lnd only when the entire network goes + * away + */ + net->net_lnd->lnd_refcount--; + + lnet_net_unlock(LNET_LOCK_EX); + + lnet_net_free(net); +} + static int -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun); + +static int +lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) { - int rc = -EINVAL; - int lnd_type; - struct lnet_lnd *lnd; - struct lnet_tx_queue *tq; - int i; - u32 seed; + struct lnet_ni *ni; + __u32 lnd_type; + struct lnet_lnd *lnd; + int rc; - lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); + lnd_type = LNET_NETTYP(net->net_id); LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ lnet_net_lock(LNET_LOCK_EX); - rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nets); + rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); lnet_net_unlock(LNET_LOCK_EX); if (!rc) { if (lnd_type == LOLND) { - lnet_ni_free(ni); + lnet_net_free(net); return 0; } CERROR("Net %s is not unique\n", - libcfs_net2str(LNET_NIDNET(ni->ni_nid))); + libcfs_net2str(net->net_id)); rc = -EEXIST; goto failed0; } @@ -1291,8 +1320,32 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) lnet_net_lock(LNET_LOCK_EX); lnd->lnd_refcount++; lnet_net_unlock(LNET_LOCK_EX); + net->net_lnd = lnd; + mutex_unlock(&the_lnet.ln_lnd_mutex); - ni->ni_net->net_lnd = lnd; + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); + + rc = lnet_startup_lndni(ni, tun); + if (rc < 0) + return rc; + return 1; + +failed0: + lnet_net_free(net); + + return rc; +} + +static int +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) +{ + int rc = -EINVAL; + struct lnet_tx_queue *tq; + int i; + struct lnet_net *net = ni->ni_net; + u32 seed; + + mutex_lock(&the_lnet.ln_lnd_mutex); if (tun) { memcpy(&ni->ni_lnd_tunables, tun, @@ -1300,15 +1353,15 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) ni->ni_lnd_tunables_set = true; } - rc = lnd->lnd_startup(ni); + rc = net->net_lnd->lnd_startup(ni); mutex_unlock(&the_lnet.ln_lnd_mutex); if (rc) { LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n", - rc, libcfs_lnd2str(lnd->lnd_type)); + rc, libcfs_lnd2str(net->net_lnd->lnd_type)); lnet_net_lock(LNET_LOCK_EX); - lnd->lnd_refcount--; + net->net_lnd->lnd_refcount--; lnet_net_unlock(LNET_LOCK_EX); goto failed0; } @@ -1324,7 +1377,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) lnet_net_unlock(LNET_LOCK_EX); - if (lnd->lnd_type == LOLND) { + if (net->net_lnd->lnd_type == LOLND) { lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); the_lnet.ln_loni = ni; @@ -1338,7 +1391,7 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) if (!ni->ni_net->net_tunables.lct_peer_tx_credits || !ni->ni_net->net_tunables.lct_max_tx_credits) { LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n", - libcfs_lnd2str(lnd->lnd_type), + libcfs_lnd2str(net->net_lnd->lnd_type), !ni->ni_net->net_tunables.lct_peer_tx_credits ? "" : "per-peer "); /* @@ -1375,21 +1428,22 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) } static int -lnet_startup_lndnis(struct list_head *nilist) +lnet_startup_lndnets(struct list_head *netlist) { - struct lnet_ni *ni; + struct lnet_net *net; int rc; int ni_count = 0; - while (!list_empty(nilist)) { - ni = list_entry(nilist->next, struct lnet_ni, ni_netlist); - list_del(&ni->ni_netlist); - rc = lnet_startup_lndni(ni, NULL); + while (!list_empty(netlist)) { + net = list_entry(netlist->next, struct lnet_net, net_list); + list_del_init(&net->net_list); + + rc = lnet_startup_lndnet(net, NULL); if (rc < 0) goto failed; - ni_count++; + ni_count += rc; } return ni_count; @@ -1552,7 +1606,7 @@ LNetNIInit(lnet_pid_t requested_pid) goto err_empty_list; } - ni_count = lnet_startup_lndnis(&net_head); + ni_count = lnet_startup_lndnets(&net_head); if (ni_count < 0) { rc = ni_count; goto err_empty_list; @@ -1831,10 +1885,11 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; struct lnet_net *net; - struct lnet_ni *ni; struct list_head net_head; struct lnet_remotenet *rnet; int rc; + int num_acceptor_nets; + __u32 net_type; struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; INIT_LIST_HEAD(&net_head); @@ -1876,22 +1931,47 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) goto failed0; list_del_init(&net->net_list); + if (lnd_tunables) memcpy(&net->net_tunables, &lnd_tunables->lt_cmn, sizeof(lnd_tunables->lt_cmn)); - ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); - rc = lnet_startup_lndni(ni, (lnd_tunables ? + /* + * before starting this network get a count of the current TCP + * networks which require the acceptor thread running. If that + * count is == 0 before we start up this network, then we'd want to + * start up the acceptor thread after starting up this network + */ + num_acceptor_nets = lnet_count_acceptor_nets(); + + /* + * lnd_startup_lndnet() can deallocate 'net' even if it it returns + * success, because we endded up adding interfaces to an existing + * network. So grab the net_type now + */ + net_type = LNET_NETTYP(net->net_id); + + rc = lnet_startup_lndnet(net, (lnd_tunables ? &lnd_tunables->lt_tun : NULL)); if (rc < 0) goto failed1; - if (ni->ni_net->net_lnd->lnd_accept) { + /* + * Start the acceptor thread if this is the first network + * being added that requires the thread. + */ + if (net_type == SOCKLND && num_acceptor_nets == 0) { rc = lnet_acceptor_start(); if (rc < 0) { - /* shutdown the ni that we just started */ + /* shutdown the net that we just started */ CERROR("Failed to start up acceptor thread\n"); - lnet_shutdown_lndni(ni); + /* + * Note that if we needed to start the acceptor + * thread, then 'net' must have been the first TCP + * network, therefore was unique, and therefore + * wasn't deallocated by lnet_startup_lndnet() + */ + lnet_shutdown_lndnet(net); goto failed1; } } From doucharek at cray.com Wed Sep 12 03:39:50 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 03:39:50 +0000 Subject: [lustre-devel] [PATCH 13/34] lnet: reverse order of lnet_startup_lnd{net, ni} In-Reply-To: <153628137175.8267.2271624767774752203.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137175.8267.2271624767774752203.stgit@noble> Message-ID: Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:53 PM, "NeilBrown" wrote: Change the order - no other change. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 135 ++++++++++++++--------------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 8afddf11b5e2..09ea7e506128 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1267,75 +1267,6 @@ lnet_shutdown_lndnet(struct lnet_net *net) lnet_net_free(net); } -static int -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun); - -static int -lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) -{ - struct lnet_ni *ni; - __u32 lnd_type; - struct lnet_lnd *lnd; - int rc; - - lnd_type = LNET_NETTYP(net->net_id); - - LASSERT(libcfs_isknown_lnd(lnd_type)); - - /* Make sure this new NI is unique. */ - lnet_net_lock(LNET_LOCK_EX); - rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); - lnet_net_unlock(LNET_LOCK_EX); - if (!rc) { - if (lnd_type == LOLND) { - lnet_net_free(net); - return 0; - } - - CERROR("Net %s is not unique\n", - libcfs_net2str(net->net_id)); - rc = -EEXIST; - goto failed0; - } - - mutex_lock(&the_lnet.ln_lnd_mutex); - lnd = lnet_find_lnd_by_type(lnd_type); - - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - rc = request_module("%s", libcfs_lnd2modname(lnd_type)); - mutex_lock(&the_lnet.ln_lnd_mutex); - - lnd = lnet_find_lnd_by_type(lnd_type); - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - CERROR("Can't load LND %s, module %s, rc=%d\n", - libcfs_lnd2str(lnd_type), - libcfs_lnd2modname(lnd_type), rc); - rc = -EINVAL; - goto failed0; - } - } - - lnet_net_lock(LNET_LOCK_EX); - lnd->lnd_refcount++; - lnet_net_unlock(LNET_LOCK_EX); - net->net_lnd = lnd; - mutex_unlock(&the_lnet.ln_lnd_mutex); - - ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); - - rc = lnet_startup_lndni(ni, tun); - if (rc < 0) - return rc; - return 1; - -failed0: - lnet_net_free(net); - - return rc; -} - static int lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) { @@ -1427,6 +1358,72 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) return rc; } +static int +lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) +{ + struct lnet_ni *ni; + __u32 lnd_type; + struct lnet_lnd *lnd; + int rc; + + lnd_type = LNET_NETTYP(net->net_id); + + LASSERT(libcfs_isknown_lnd(lnd_type)); + + /* Make sure this new NI is unique. */ + lnet_net_lock(LNET_LOCK_EX); + rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); + lnet_net_unlock(LNET_LOCK_EX); + if (!rc) { + if (lnd_type == LOLND) { + lnet_net_free(net); + return 0; + } + + CERROR("Net %s is not unique\n", + libcfs_net2str(net->net_id)); + rc = -EEXIST; + goto failed0; + } + + mutex_lock(&the_lnet.ln_lnd_mutex); + lnd = lnet_find_lnd_by_type(lnd_type); + + if (!lnd) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + rc = request_module("%s", libcfs_lnd2modname(lnd_type)); + mutex_lock(&the_lnet.ln_lnd_mutex); + + lnd = lnet_find_lnd_by_type(lnd_type); + if (!lnd) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + CERROR("Can't load LND %s, module %s, rc=%d\n", + libcfs_lnd2str(lnd_type), + libcfs_lnd2modname(lnd_type), rc); + rc = -EINVAL; + goto failed0; + } + } + + lnet_net_lock(LNET_LOCK_EX); + lnd->lnd_refcount++; + lnet_net_unlock(LNET_LOCK_EX); + net->net_lnd = lnd; + mutex_unlock(&the_lnet.ln_lnd_mutex); + + ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); + + rc = lnet_startup_lndni(ni, tun); + if (rc < 0) + return rc; + return 1; + +failed0: + lnet_net_free(net); + + return rc; +} + static int lnet_startup_lndnets(struct list_head *netlist) { From doucharek at cray.com Wed Sep 12 03:40:46 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 03:40:46 +0000 Subject: [lustre-devel] [PATCH 14/34] lnet: rename lnet_find_net_locked to lnet_find_rnet_locked In-Reply-To: <153628137179.8267.355535015389180735.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137179.8267.355535015389180735.stgit@noble> Message-ID: <1B50CEB8-1F64-4C77-8BA0-B37377C5D9B1@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:53 PM, "NeilBrown" wrote: This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 2 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 2 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- drivers/staging/lustre/lnet/lnet/router.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index e32dbb854d80..faa3f19dd844 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -430,7 +430,7 @@ int lnet_rtrpools_adjust(int tiny, int small, int large); int lnet_rtrpools_enable(void); void lnet_rtrpools_disable(void); void lnet_rtrpools_free(int keep_pools); -struct lnet_remotenet *lnet_find_net_locked(__u32 net); +struct lnet_remotenet *lnet_find_rnet_locked(__u32 net); int lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf); int lnet_dyn_del_ni(__u32 net); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 09ea7e506128..c3c568e63342 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1909,7 +1909,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) net = list_entry(net_head.next, struct lnet_net, net_list); lnet_net_lock(LNET_LOCK_EX); - rnet = lnet_find_net_locked(net->net_id); + rnet = lnet_find_rnet_locked(net->net_id); lnet_net_unlock(LNET_LOCK_EX); /* * make sure that the net added doesn't invalidate the current diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 02cd1a5a466f..00a89221c9b3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1022,7 +1022,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, * If @rtr_nid is not LNET_NID_ANY, return the gateway with * rtr_nid nid, otherwise find the best gateway I can use */ - rnet = lnet_find_net_locked(LNET_NIDNET(target)); + rnet = lnet_find_rnet_locked(LNET_NIDNET(target)); if (!rnet) return NULL; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 5493d13de6d9..1fce991fcb0e 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -220,7 +220,7 @@ lnet_rtr_decref_locked(struct lnet_peer *lp) } struct lnet_remotenet * -lnet_find_net_locked(__u32 net) +lnet_find_rnet_locked(__u32 net) { struct lnet_remotenet *rnet; struct list_head *rn_list; @@ -347,7 +347,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, LASSERT(!the_lnet.ln_shutdown); - rnet2 = lnet_find_net_locked(net); + rnet2 = lnet_find_rnet_locked(net); if (!rnet2) { /* new network */ list_add_tail(&rnet->lrn_list, lnet_net2rnethash(net)); From doucharek at cray.com Wed Sep 12 03:53:47 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 03:53:47 +0000 Subject: [lustre-devel] [PATCH 15/34] lnet: extend zombie handling to nets and nis In-Reply-To: <153628137183.8267.14166864803956204561.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137183.8267.14166864803956204561.stgit@noble> Message-ID: <384BF908-3F8C-477C-800E-8ECCE708EC6F@cray.com> Which refcount line are you referring to? The call to lnet_ni_unlink_locked()? Reviewed-by: Doug Oucharek k Doug On 9/6/18, 5:53 PM, "NeilBrown" wrote: A zombie lnet_ni is now attached to the lnet_net rather than the global the_lnet. The zombie lnet_net are attached to the_lnet. For some reason, we don't drop the refcount on the lnd before shutting it down now. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 9 ++- drivers/staging/lustre/lnet/lnet/api-ni.c | 65 ++++++++++---------- drivers/staging/lustre/lnet/lnet/config.c | 3 + 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 22957d142cc0..1d372672e2de 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -284,6 +284,9 @@ struct lnet_net { struct lnet_lnd *net_lnd; /* list of NIs on this net */ struct list_head net_ni_list; + + /* dying LND instances */ + struct list_head net_ni_zombie; }; struct lnet_ni { @@ -653,11 +656,11 @@ struct lnet { /* LND instances */ struct list_head ln_nets; /* NIs bond on specific CPT(s) */ - struct list_head ln_nis_cpt; - /* dying LND instances */ - struct list_head ln_nis_zombie; + struct list_head ln_nis_cpt; /* the loopback NI */ struct lnet_ni *ln_loni; + /* network zombie list */ + struct list_head ln_net_zombie; /* remote networks with routes to them */ struct list_head *ln_remote_nets_hash; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index c3c568e63342..18d111cb826b 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -539,7 +539,6 @@ lnet_prepare(lnet_pid_t requested_pid) INIT_LIST_HEAD(&the_lnet.ln_test_peers); INIT_LIST_HEAD(&the_lnet.ln_nets); INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); - INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); INIT_LIST_HEAD(&the_lnet.ln_routers); INIT_LIST_HEAD(&the_lnet.ln_drop_rules); INIT_LIST_HEAD(&the_lnet.ln_delay_rules); @@ -618,7 +617,6 @@ lnet_unprepare(void) LASSERT(list_empty(&the_lnet.ln_test_peers)); LASSERT(list_empty(&the_lnet.ln_nets)); LASSERT(list_empty(&the_lnet.ln_nis_cpt)); - LASSERT(list_empty(&the_lnet.ln_nis_zombie)); lnet_portals_destroy(); @@ -1095,34 +1093,35 @@ lnet_ni_unlink_locked(struct lnet_ni *ni) /* move it to zombie list and nobody can find it anymore */ LASSERT(!list_empty(&ni->ni_netlist)); - list_move(&ni->ni_netlist, &the_lnet.ln_nis_zombie); + list_move(&ni->ni_netlist, &ni->ni_net->net_ni_zombie); lnet_ni_decref_locked(ni, 0); } static void -lnet_clear_zombies_nis_locked(void) +lnet_clear_zombies_nis_locked(struct lnet_net *net) { int i; int islo; struct lnet_ni *ni; + struct list_head *zombie_list = &net->net_ni_zombie; /* - * Now wait for the NI's I just nuked to show up on ln_zombie_nis - * and shut them down in guaranteed thread context + * Now wait for the NIs I just nuked to show up on the zombie + * list and shut them down in guaranteed thread context */ i = 2; - while (!list_empty(&the_lnet.ln_nis_zombie)) { + while (!list_empty(zombie_list)) { int *ref; int j; - ni = list_entry(the_lnet.ln_nis_zombie.next, + ni = list_entry(zombie_list->next, struct lnet_ni, ni_netlist); list_del_init(&ni->ni_netlist); cfs_percpt_for_each(ref, j, ni->ni_refs) { if (!*ref) continue; /* still busy, add it back to zombie list */ - list_add(&ni->ni_netlist, &the_lnet.ln_nis_zombie); + list_add(&ni->ni_netlist, zombie_list); break; } @@ -1138,18 +1137,13 @@ lnet_clear_zombies_nis_locked(void) continue; } - ni->ni_net->net_lnd->lnd_refcount--; lnet_net_unlock(LNET_LOCK_EX); islo = ni->ni_net->net_lnd->lnd_type == LOLND; LASSERT(!in_interrupt()); - ni->ni_net->net_lnd->lnd_shutdown(ni); + net->net_lnd->lnd_shutdown(ni); - /* - * can't deref lnd anymore now; it might have unregistered - * itself... - */ if (!islo) CDEBUG(D_LNI, "Removed LNI %s\n", libcfs_nid2str(ni->ni_nid)); @@ -1162,9 +1156,11 @@ lnet_clear_zombies_nis_locked(void) } static void -lnet_shutdown_lndnis(void) +lnet_shutdown_lndnet(struct lnet_net *net); + +static void +lnet_shutdown_lndnets(void) { - struct lnet_ni *ni; int i; struct lnet_net *net; @@ -1173,30 +1169,35 @@ lnet_shutdown_lndnis(void) /* All quiet on the API front */ LASSERT(!the_lnet.ln_shutdown); LASSERT(!the_lnet.ln_refcount); - LASSERT(list_empty(&the_lnet.ln_nis_zombie)); lnet_net_lock(LNET_LOCK_EX); the_lnet.ln_shutdown = 1; /* flag shutdown */ - /* Unlink NIs from the global table */ while (!list_empty(&the_lnet.ln_nets)) { + /* + * move the nets to the zombie list to avoid them being + * picked up for new work. LONET is also included in the + * Nets that will be moved to the zombie list + */ net = list_entry(the_lnet.ln_nets.next, struct lnet_net, net_list); - while (!list_empty(&net->net_ni_list)) { - ni = list_entry(net->net_ni_list.next, - struct lnet_ni, ni_netlist); - lnet_ni_unlink_locked(ni); - } + list_move(&net->net_list, &the_lnet.ln_net_zombie); } - /* Drop the cached loopback NI. */ + /* Drop the cached loopback Net. */ if (the_lnet.ln_loni) { lnet_ni_decref_locked(the_lnet.ln_loni, 0); the_lnet.ln_loni = NULL; } - lnet_net_unlock(LNET_LOCK_EX); + /* iterate through the net zombie list and delete each net */ + while (!list_empty(&the_lnet.ln_net_zombie)) { + net = list_entry(the_lnet.ln_net_zombie.next, + struct lnet_net, net_list); + lnet_shutdown_lndnet(net); + } + /* * Clear lazy portals and drop delayed messages which hold refs * on their lnet_msg::msg_rxpeer @@ -1211,8 +1212,6 @@ lnet_shutdown_lndnis(void) lnet_peer_tables_cleanup(NULL); lnet_net_lock(LNET_LOCK_EX); - - lnet_clear_zombies_nis_locked(); the_lnet.ln_shutdown = 0; lnet_net_unlock(LNET_LOCK_EX); } @@ -1222,6 +1221,7 @@ static void lnet_shutdown_lndni(struct lnet_ni *ni) { int i; + struct lnet_net *net = ni->ni_net; lnet_net_lock(LNET_LOCK_EX); lnet_ni_unlink_locked(ni); @@ -1235,7 +1235,7 @@ lnet_shutdown_lndni(struct lnet_ni *ni) lnet_peer_tables_cleanup(ni); lnet_net_lock(LNET_LOCK_EX); - lnet_clear_zombies_nis_locked(); + lnet_clear_zombies_nis_locked(net); lnet_net_unlock(LNET_LOCK_EX); } @@ -1445,7 +1445,7 @@ lnet_startup_lndnets(struct list_head *netlist) return ni_count; failed: - lnet_shutdown_lndnis(); + lnet_shutdown_lndnets(); return rc; } @@ -1492,6 +1492,7 @@ int lnet_lib_init(void) the_lnet.ln_refcount = 0; LNetInvalidateEQHandle(&the_lnet.ln_rc_eqh); INIT_LIST_HEAD(&the_lnet.ln_lnds); + INIT_LIST_HEAD(&the_lnet.ln_net_zombie); INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie); INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow); @@ -1656,7 +1657,7 @@ LNetNIInit(lnet_pid_t requested_pid) if (!the_lnet.ln_nis_from_mod_params) lnet_destroy_routes(); err_shutdown_lndnis: - lnet_shutdown_lndnis(); + lnet_shutdown_lndnets(); err_empty_list: lnet_unprepare(); LASSERT(rc < 0); @@ -1703,7 +1704,7 @@ LNetNIFini(void) lnet_acceptor_stop(); lnet_destroy_routes(); - lnet_shutdown_lndnis(); + lnet_shutdown_lndnets(); lnet_unprepare(); } diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 380a3fb1caba..2588d67fea1b 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -279,6 +279,8 @@ lnet_net_free(struct lnet_net *net) struct list_head *tmp, *tmp2; struct lnet_ni *ni; + LASSERT(list_empty(&net->net_ni_zombie)); + /* delete any nis which have been started. */ list_for_each_safe(tmp, tmp2, &net->net_ni_list) { ni = list_entry(tmp, struct lnet_ni, ni_netlist); @@ -312,6 +314,7 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) INIT_LIST_HEAD(&net->net_list); INIT_LIST_HEAD(&net->net_ni_list); + INIT_LIST_HEAD(&net->net_ni_zombie); net->net_id = net_id; From doucharek at cray.com Wed Sep 12 03:55:51 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 03:55:51 +0000 Subject: [lustre-devel] [PATCH 17/34] lnet: move lnet_shutdown_lndnets down to after first use In-Reply-To: <153628137192.8267.6087363236690952153.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137192.8267.6087363236690952153.stgit@noble> Message-ID: <6A7808B9-6E1A-4C72-BBA5-7C925EE1FD20@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 91 ++++++++++++++--------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2529a11c6c59..46c5ca71bc07 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1155,53 +1155,6 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net) } } -static void -lnet_shutdown_lndnet(struct lnet_net *net); - -static void -lnet_shutdown_lndnets(void) -{ - struct lnet_net *net; - - /* NB called holding the global mutex */ - - /* All quiet on the API front */ - LASSERT(!the_lnet.ln_shutdown); - LASSERT(!the_lnet.ln_refcount); - - lnet_net_lock(LNET_LOCK_EX); - the_lnet.ln_shutdown = 1; /* flag shutdown */ - - while (!list_empty(&the_lnet.ln_nets)) { - /* - * move the nets to the zombie list to avoid them being - * picked up for new work. LONET is also included in the - * Nets that will be moved to the zombie list - */ - net = list_entry(the_lnet.ln_nets.next, - struct lnet_net, net_list); - list_move(&net->net_list, &the_lnet.ln_net_zombie); - } - - /* Drop the cached loopback Net. */ - if (the_lnet.ln_loni) { - lnet_ni_decref_locked(the_lnet.ln_loni, 0); - the_lnet.ln_loni = NULL; - } - lnet_net_unlock(LNET_LOCK_EX); - - /* iterate through the net zombie list and delete each net */ - while (!list_empty(&the_lnet.ln_net_zombie)) { - net = list_entry(the_lnet.ln_net_zombie.next, - struct lnet_net, net_list); - lnet_shutdown_lndnet(net); - } - - lnet_net_lock(LNET_LOCK_EX); - the_lnet.ln_shutdown = 0; - lnet_net_unlock(LNET_LOCK_EX); -} - /* shutdown down the NI and release refcount */ static void lnet_shutdown_lndni(struct lnet_ni *ni) @@ -1253,6 +1206,50 @@ lnet_shutdown_lndnet(struct lnet_net *net) lnet_net_free(net); } +static void +lnet_shutdown_lndnets(void) +{ + struct lnet_net *net; + + /* NB called holding the global mutex */ + + /* All quiet on the API front */ + LASSERT(!the_lnet.ln_shutdown); + LASSERT(!the_lnet.ln_refcount); + + lnet_net_lock(LNET_LOCK_EX); + the_lnet.ln_shutdown = 1; /* flag shutdown */ + + while (!list_empty(&the_lnet.ln_nets)) { + /* + * move the nets to the zombie list to avoid them being + * picked up for new work. LONET is also included in the + * Nets that will be moved to the zombie list + */ + net = list_entry(the_lnet.ln_nets.next, + struct lnet_net, net_list); + list_move(&net->net_list, &the_lnet.ln_net_zombie); + } + + /* Drop the cached loopback Net. */ + if (the_lnet.ln_loni) { + lnet_ni_decref_locked(the_lnet.ln_loni, 0); + the_lnet.ln_loni = NULL; + } + lnet_net_unlock(LNET_LOCK_EX); + + /* iterate through the net zombie list and delete each net */ + while (!list_empty(&the_lnet.ln_net_zombie)) { + net = list_entry(the_lnet.ln_net_zombie.next, + struct lnet_net, net_list); + lnet_shutdown_lndnet(net); + } + + lnet_net_lock(LNET_LOCK_EX); + the_lnet.ln_shutdown = 0; + lnet_net_unlock(LNET_LOCK_EX); +} + static int lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) { From doucharek at cray.com Wed Sep 12 03:59:16 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 03:59:16 +0000 Subject: [lustre-devel] [PATCH 18/34] lnet: add ni_state In-Reply-To: <153628137195.8267.16400748098054215181.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137195.8267.16400748098054215181.stgit@noble> Message-ID: <0DD49EFB-412D-4C87-8FC8-3F0C93D2E98A@cray.com> I believe the introduction of this state machine is to help us understand how healthy an NI is so we can avoid if it is not healthy and we have other paths which are still ok. Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: This is barely used. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + .../staging/lustre/include/linux/lnet/lib-types.h | 16 ++++++++++++++++ drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++++++++++ drivers/staging/lustre/lnet/lnet/config.c | 1 + 4 files changed, 34 insertions(+) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index faa3f19dd844..54a93235834c 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -400,6 +400,7 @@ int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); struct lnet_ni *lnet_net2ni(__u32 net); +bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); extern int portal_rotor; diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 1d372672e2de..6c34ecf22021 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -256,6 +256,19 @@ struct lnet_tx_queue { struct list_head tq_delayed; /* delayed TXs */ }; +enum lnet_ni_state { + /* set when NI block is allocated */ + LNET_NI_STATE_INIT = 0, + /* set when NI is started successfully */ + LNET_NI_STATE_ACTIVE, + /* set when LND notifies NI failed */ + LNET_NI_STATE_FAILED, + /* set when LND notifies NI degraded */ + LNET_NI_STATE_DEGRADED, + /* set when shuttding down NI */ + LNET_NI_STATE_DELETING +}; + struct lnet_net { /* chain on the ln_nets */ struct list_head net_list; @@ -324,6 +337,9 @@ struct lnet_ni { /* my health status */ struct lnet_ni_status *ni_status; + /* NI FSM */ + enum lnet_ni_state ni_state; + /* per NI LND tunables */ struct lnet_lnd_tunables ni_lnd_tunables; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 46c5ca71bc07..618fdf8141f0 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -780,6 +780,16 @@ lnet_islocalnet(__u32 net) return !!ni; } +bool +lnet_is_ni_healthy_locked(struct lnet_ni *ni) +{ + if (ni->ni_state == LNET_NI_STATE_ACTIVE || + ni->ni_state == LNET_NI_STATE_DEGRADED) + return true; + + return false; +} + struct lnet_ni * lnet_nid2ni_locked(lnet_nid_t nid, int cpt) { @@ -1117,6 +1127,9 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net) ni = list_entry(zombie_list->next, struct lnet_ni, ni_netlist); list_del_init(&ni->ni_netlist); + /* the ni should be in deleting state. If it's not it's + * a bug */ + LASSERT(ni->ni_state == LNET_NI_STATE_DELETING); cfs_percpt_for_each(ref, j, ni->ni_refs) { if (!*ref) continue; @@ -1163,6 +1176,7 @@ lnet_shutdown_lndni(struct lnet_ni *ni) struct lnet_net *net = ni->ni_net; lnet_net_lock(LNET_LOCK_EX); + ni->ni_state = LNET_NI_STATE_DELETING; lnet_ni_unlink_locked(ni); lnet_net_unlock(LNET_LOCK_EX); @@ -1291,6 +1305,8 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) lnet_net_unlock(LNET_LOCK_EX); + ni->ni_state = LNET_NI_STATE_ACTIVE; + if (net->net_lnd->lnd_type == LOLND) { lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 2588d67fea1b..081812e19b13 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -393,6 +393,7 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) ni->ni_net_ns = NULL; ni->ni_last_alive = ktime_get_real_seconds(); + ni->ni_state = LNET_NI_STATE_INIT; rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); if (rc != 0) goto failed; From doucharek at cray.com Wed Sep 12 04:02:19 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:02:19 +0000 Subject: [lustre-devel] [PATCH 19/34] lnet: simplify lnet_islocalnet() In-Reply-To: <153628137199.8267.13740900509571445302.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137199.8267.13740900509571445302.stgit@noble> Message-ID: <670A90DC-85E2-48A2-98AB-AF9AC036F371@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: Having lnet_get_net_locked() makes this (a little) simpler. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 618fdf8141f0..546d5101360f 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -764,20 +764,16 @@ lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni) EXPORT_SYMBOL(lnet_cpt_of_nid); int -lnet_islocalnet(__u32 net) +lnet_islocalnet(__u32 net_id) { - struct lnet_ni *ni; - int cpt; + struct lnet_net *net; + int cpt; cpt = lnet_net_lock_current(); - - ni = lnet_net2ni_locked(net, cpt); - if (ni) - lnet_ni_decref_locked(ni, cpt); - + net = lnet_get_net_locked(net_id); lnet_net_unlock(cpt); - return !!ni; + return !!net; } bool From neilb at suse.com Wed Sep 12 04:03:45 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 14:03:45 +1000 Subject: [lustre-devel] [PATCH 11/34] lnet: pass tun to lnet_startup_lndni, instead of full conf In-Reply-To: References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137168.8267.1167942220741712684.stgit@noble> Message-ID: <87d0tjqs4e.fsf@notabene.neil.brown.name> On Tue, Sep 11 2018, Amir Shehata wrote: > This block logic that was removed from lnet_startup_lndni() is done in the > LND. Each LND has its own defaults. As an example look at > kiblnd_tunables_setup() and ksocknal_startup(). > These tunables are LND specific and have different values per LND. So > instead of configuring it in the common LNet function and then it gets > overwritten again the LND. We let the LND take care of initializing to the > default values that they use for that LND, if they haven't already been set > by the user. > Note currently dynamic configuration of these parameters work only for the > o2iblnd. Socklnd and gnilnd appear to not make use of the dynamic ability. > I'll create an LU ticket to add the ability to dynamically set these values > to the socklnd. > The tunables are divided into two parts, a common set of tunables that are > common to all the LND (although each LND could have different default > values), and a specific set of LND tunables which pertain to a specific > LND, again that's only used by the o2iblnd at the moment. Thanks a lot. That helps. NeilBrown > > On Thu, 6 Sep 2018 at 18:00, NeilBrown wrote: > >> I don't understand parts of this change. >> Particularly the removal for >> /* If given some LND tunable parameters, parse those now to >> * override the values in the NI structure. */ >> >> isn't clear to me. >> >> This is part of >> 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 >> LU-7734 lnet: Multi-Rail local NI split >> >> Signed-off-by: NeilBrown >> --- >> drivers/staging/lustre/lnet/lnet/api-ni.c | 41 >> ++++++++--------------------- >> 1 file changed, 12 insertions(+), 29 deletions(-) >> >> diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c >> b/drivers/staging/lustre/lnet/lnet/api-ni.c >> index 6e0b8310574d..53ecfd700db3 100644 >> --- a/drivers/staging/lustre/lnet/lnet/api-ni.c >> +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c >> @@ -1240,10 +1240,8 @@ lnet_shutdown_lndni(struct lnet_ni *ni) >> } >> >> static int >> -lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data >> *conf) >> +lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) >> { >> - struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; >> - struct lnet_lnd_tunables *tun = NULL; >> int rc = -EINVAL; >> int lnd_type; >> struct lnet_lnd *lnd; >> @@ -1296,36 +1294,12 @@ lnet_startup_lndni(struct lnet_ni *ni, struct >> lnet_ioctl_config_data *conf) >> >> ni->ni_net->net_lnd = lnd; >> >> - if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) { >> - lnd_tunables = (struct lnet_ioctl_config_lnd_tunables >> *)conf->cfg_bulk; >> - tun = &lnd_tunables->lt_tun; >> - } >> - >> if (tun) { >> memcpy(&ni->ni_lnd_tunables, tun, >> sizeof(*tun)); >> ni->ni_lnd_tunables_set = true; >> } >> >> - /* >> - * If given some LND tunable parameters, parse those now to >> - * override the values in the NI structure. >> - */ >> - if (conf) { >> - if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) >> - ni->ni_net->net_tunables.lct_peer_rtr_credits = >> - >> conf->cfg_config_u.cfg_net.net_peer_rtr_credits; >> - if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) >> - ni->ni_net->net_tunables.lct_peer_timeout = >> - >> conf->cfg_config_u.cfg_net.net_peer_timeout; >> - if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) >> - ni->ni_net->net_tunables.lct_peer_tx_credits = >> - >> conf->cfg_config_u.cfg_net.net_peer_tx_credits; >> - if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) >> - ni->ni_net->net_tunables.lct_max_tx_credits = >> - >> conf->cfg_config_u.cfg_net.net_max_tx_credits; >> - } >> - >> rc = lnd->lnd_startup(ni); >> >> mutex_unlock(&the_lnet.ln_lnd_mutex); >> @@ -1861,9 +1835,13 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct >> lnet_ioctl_config_data *conf) >> struct list_head net_head; >> struct lnet_remotenet *rnet; >> int rc; >> + struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; >> >> INIT_LIST_HEAD(&net_head); >> >> + if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) >> + lnd_tunables = (struct lnet_ioctl_config_lnd_tunables >> *)conf->cfg_bulk; >> + >> /* Create a net/ni structures for the network string */ >> rc = lnet_parse_networks(&net_head, nets); >> if (rc <= 0) >> @@ -1898,9 +1876,14 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct >> lnet_ioctl_config_data *conf) >> goto failed0; >> >> list_del_init(&net->net_list); >> + if (lnd_tunables) >> + memcpy(&net->net_tunables, >> + &lnd_tunables->lt_cmn, >> sizeof(lnd_tunables->lt_cmn)); >> + >> ni = list_first_entry(&net->net_ni_list, struct lnet_ni, >> ni_netlist); >> - rc = lnet_startup_lndni(ni, conf); >> - if (rc) >> + rc = lnet_startup_lndni(ni, (lnd_tunables ? >> + &lnd_tunables->lt_tun : NULL)); >> + if (rc < 0) >> goto failed1; >> >> if (ni->ni_net->net_lnd->lnd_accept) { >> >> >> _______________________________________________ >> lustre-devel mailing list >> lustre-devel at lists.lustre.org >> http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org >> -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From doucharek at cray.com Wed Sep 12 04:07:04 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:07:04 +0000 Subject: [lustre-devel] [PATCH 20/34] lnet: discard ni_cpt_list In-Reply-To: <153628137203.8267.14277020278461943610.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137203.8267.14277020278461943610.stgit@noble> Message-ID: I'm assuming that a future patch will be chaining the NI structure on to the NET structure it belongs to. This patch is just not chaining the NIs on a global NIS list anymore. As such, ni_cptlist is being "repurposed". Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: This isn't used any more. The new comment is odd - this is no net_ni_cpt !! The ni_cptlist linkage is no longer used - should it go too? This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 4 +--- drivers/staging/lustre/lnet/lnet/api-ni.c | 7 ------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 6c34ecf22021..dc15fa75a9d2 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -305,7 +305,7 @@ struct lnet_net { struct lnet_ni { /* chain on the lnet_net structure */ struct list_head ni_netlist; - /* chain on ln_nis_cpt */ + /* chain on net_ni_cpt */ struct list_head ni_cptlist; spinlock_t ni_lock; @@ -671,8 +671,6 @@ struct lnet { /* LND instances */ struct list_head ln_nets; - /* NIs bond on specific CPT(s) */ - struct list_head ln_nis_cpt; /* the loopback NI */ struct lnet_ni *ln_loni; /* network zombie list */ diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 546d5101360f..960f235df5e7 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -538,7 +538,6 @@ lnet_prepare(lnet_pid_t requested_pid) INIT_LIST_HEAD(&the_lnet.ln_test_peers); INIT_LIST_HEAD(&the_lnet.ln_nets); - INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); INIT_LIST_HEAD(&the_lnet.ln_routers); INIT_LIST_HEAD(&the_lnet.ln_drop_rules); INIT_LIST_HEAD(&the_lnet.ln_delay_rules); @@ -616,7 +615,6 @@ lnet_unprepare(void) LASSERT(!the_lnet.ln_refcount); LASSERT(list_empty(&the_lnet.ln_test_peers)); LASSERT(list_empty(&the_lnet.ln_nets)); - LASSERT(list_empty(&the_lnet.ln_nis_cpt)); lnet_portals_destroy(); @@ -1294,11 +1292,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) /* refcount for ln_nis */ lnet_ni_addref_locked(ni, 0); list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); - if (ni->ni_cpts) { - lnet_ni_addref_locked(ni, 0); - list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); - } - lnet_net_unlock(LNET_LOCK_EX); ni->ni_state = LNET_NI_STATE_ACTIVE; From neilb at suse.com Wed Sep 12 04:10:46 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 14:10:46 +1000 Subject: [lustre-devel] [PATCH 15/34] lnet: extend zombie handling to nets and nis In-Reply-To: <384BF908-3F8C-477C-800E-8ECCE708EC6F@cray.com> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137183.8267.14166864803956204561.stgit@noble> <384BF908-3F8C-477C-800E-8ECCE708EC6F@cray.com> Message-ID: <87a7onqrsp.fsf@notabene.neil.brown.name> On Wed, Sep 12 2018, Doug Oucharek wrote: > Which refcount line are you referring to? The call to > lnet_ni_unlink_locked()? Line 1141 = in lnet_clear_zombies_nis_locked(). > - ni->ni_net->net_lnd->lnd_refcount--; Thanks, NeilBrown > > Reviewed-by: Doug Oucharek > > Doug > > On 9/6/18, 5:53 PM, "NeilBrown" wrote: > > A zombie lnet_ni is now attached to the lnet_net rather than the > global the_lnet. The zombie lnet_net are attached to the_lnet. > > For some reason, we don't drop the refcount on the lnd before shutting > it down now. > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 9 ++- > drivers/staging/lustre/lnet/lnet/api-ni.c | 65 ++++++++++---------- > drivers/staging/lustre/lnet/lnet/config.c | 3 + > 3 files changed, 42 insertions(+), 35 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 22957d142cc0..1d372672e2de 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -284,6 +284,9 @@ struct lnet_net { > struct lnet_lnd *net_lnd; > /* list of NIs on this net */ > struct list_head net_ni_list; > + > + /* dying LND instances */ > + struct list_head net_ni_zombie; > }; > > struct lnet_ni { > @@ -653,11 +656,11 @@ struct lnet { > /* LND instances */ > struct list_head ln_nets; > /* NIs bond on specific CPT(s) */ > - struct list_head ln_nis_cpt; > - /* dying LND instances */ > - struct list_head ln_nis_zombie; > + struct list_head ln_nis_cpt; > /* the loopback NI */ > struct lnet_ni *ln_loni; > + /* network zombie list */ > + struct list_head ln_net_zombie; > > /* remote networks with routes to them */ > struct list_head *ln_remote_nets_hash; > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index c3c568e63342..18d111cb826b 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -539,7 +539,6 @@ lnet_prepare(lnet_pid_t requested_pid) > INIT_LIST_HEAD(&the_lnet.ln_test_peers); > INIT_LIST_HEAD(&the_lnet.ln_nets); > INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); > - INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); > INIT_LIST_HEAD(&the_lnet.ln_routers); > INIT_LIST_HEAD(&the_lnet.ln_drop_rules); > INIT_LIST_HEAD(&the_lnet.ln_delay_rules); > @@ -618,7 +617,6 @@ lnet_unprepare(void) > LASSERT(list_empty(&the_lnet.ln_test_peers)); > LASSERT(list_empty(&the_lnet.ln_nets)); > LASSERT(list_empty(&the_lnet.ln_nis_cpt)); > - LASSERT(list_empty(&the_lnet.ln_nis_zombie)); > > lnet_portals_destroy(); > > @@ -1095,34 +1093,35 @@ lnet_ni_unlink_locked(struct lnet_ni *ni) > > /* move it to zombie list and nobody can find it anymore */ > LASSERT(!list_empty(&ni->ni_netlist)); > - list_move(&ni->ni_netlist, &the_lnet.ln_nis_zombie); > + list_move(&ni->ni_netlist, &ni->ni_net->net_ni_zombie); > lnet_ni_decref_locked(ni, 0); > } > > static void > -lnet_clear_zombies_nis_locked(void) > +lnet_clear_zombies_nis_locked(struct lnet_net *net) > { > int i; > int islo; > struct lnet_ni *ni; > + struct list_head *zombie_list = &net->net_ni_zombie; > > /* > - * Now wait for the NI's I just nuked to show up on ln_zombie_nis > - * and shut them down in guaranteed thread context > + * Now wait for the NIs I just nuked to show up on the zombie > + * list and shut them down in guaranteed thread context > */ > i = 2; > - while (!list_empty(&the_lnet.ln_nis_zombie)) { > + while (!list_empty(zombie_list)) { > int *ref; > int j; > > - ni = list_entry(the_lnet.ln_nis_zombie.next, > + ni = list_entry(zombie_list->next, > struct lnet_ni, ni_netlist); > list_del_init(&ni->ni_netlist); > cfs_percpt_for_each(ref, j, ni->ni_refs) { > if (!*ref) > continue; > /* still busy, add it back to zombie list */ > - list_add(&ni->ni_netlist, &the_lnet.ln_nis_zombie); > + list_add(&ni->ni_netlist, zombie_list); > break; > } > > @@ -1138,18 +1137,13 @@ lnet_clear_zombies_nis_locked(void) > continue; > } > > - ni->ni_net->net_lnd->lnd_refcount--; > lnet_net_unlock(LNET_LOCK_EX); > > islo = ni->ni_net->net_lnd->lnd_type == LOLND; > > LASSERT(!in_interrupt()); > - ni->ni_net->net_lnd->lnd_shutdown(ni); > + net->net_lnd->lnd_shutdown(ni); > > - /* > - * can't deref lnd anymore now; it might have unregistered > - * itself... > - */ > if (!islo) > CDEBUG(D_LNI, "Removed LNI %s\n", > libcfs_nid2str(ni->ni_nid)); > @@ -1162,9 +1156,11 @@ lnet_clear_zombies_nis_locked(void) > } > > static void > -lnet_shutdown_lndnis(void) > +lnet_shutdown_lndnet(struct lnet_net *net); > + > +static void > +lnet_shutdown_lndnets(void) > { > - struct lnet_ni *ni; > int i; > struct lnet_net *net; > > @@ -1173,30 +1169,35 @@ lnet_shutdown_lndnis(void) > /* All quiet on the API front */ > LASSERT(!the_lnet.ln_shutdown); > LASSERT(!the_lnet.ln_refcount); > - LASSERT(list_empty(&the_lnet.ln_nis_zombie)); > > lnet_net_lock(LNET_LOCK_EX); > the_lnet.ln_shutdown = 1; /* flag shutdown */ > > - /* Unlink NIs from the global table */ > while (!list_empty(&the_lnet.ln_nets)) { > + /* > + * move the nets to the zombie list to avoid them being > + * picked up for new work. LONET is also included in the > + * Nets that will be moved to the zombie list > + */ > net = list_entry(the_lnet.ln_nets.next, > struct lnet_net, net_list); > - while (!list_empty(&net->net_ni_list)) { > - ni = list_entry(net->net_ni_list.next, > - struct lnet_ni, ni_netlist); > - lnet_ni_unlink_locked(ni); > - } > + list_move(&net->net_list, &the_lnet.ln_net_zombie); > } > > - /* Drop the cached loopback NI. */ > + /* Drop the cached loopback Net. */ > if (the_lnet.ln_loni) { > lnet_ni_decref_locked(the_lnet.ln_loni, 0); > the_lnet.ln_loni = NULL; > } > - > lnet_net_unlock(LNET_LOCK_EX); > > + /* iterate through the net zombie list and delete each net */ > + while (!list_empty(&the_lnet.ln_net_zombie)) { > + net = list_entry(the_lnet.ln_net_zombie.next, > + struct lnet_net, net_list); > + lnet_shutdown_lndnet(net); > + } > + > /* > * Clear lazy portals and drop delayed messages which hold refs > * on their lnet_msg::msg_rxpeer > @@ -1211,8 +1212,6 @@ lnet_shutdown_lndnis(void) > lnet_peer_tables_cleanup(NULL); > > lnet_net_lock(LNET_LOCK_EX); > - > - lnet_clear_zombies_nis_locked(); > the_lnet.ln_shutdown = 0; > lnet_net_unlock(LNET_LOCK_EX); > } > @@ -1222,6 +1221,7 @@ static void > lnet_shutdown_lndni(struct lnet_ni *ni) > { > int i; > + struct lnet_net *net = ni->ni_net; > > lnet_net_lock(LNET_LOCK_EX); > lnet_ni_unlink_locked(ni); > @@ -1235,7 +1235,7 @@ lnet_shutdown_lndni(struct lnet_ni *ni) > lnet_peer_tables_cleanup(ni); > > lnet_net_lock(LNET_LOCK_EX); > - lnet_clear_zombies_nis_locked(); > + lnet_clear_zombies_nis_locked(net); > lnet_net_unlock(LNET_LOCK_EX); > } > > @@ -1445,7 +1445,7 @@ lnet_startup_lndnets(struct list_head *netlist) > > return ni_count; > failed: > - lnet_shutdown_lndnis(); > + lnet_shutdown_lndnets(); > > return rc; > } > @@ -1492,6 +1492,7 @@ int lnet_lib_init(void) > the_lnet.ln_refcount = 0; > LNetInvalidateEQHandle(&the_lnet.ln_rc_eqh); > INIT_LIST_HEAD(&the_lnet.ln_lnds); > + INIT_LIST_HEAD(&the_lnet.ln_net_zombie); > INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie); > INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow); > > @@ -1656,7 +1657,7 @@ LNetNIInit(lnet_pid_t requested_pid) > if (!the_lnet.ln_nis_from_mod_params) > lnet_destroy_routes(); > err_shutdown_lndnis: > - lnet_shutdown_lndnis(); > + lnet_shutdown_lndnets(); > err_empty_list: > lnet_unprepare(); > LASSERT(rc < 0); > @@ -1703,7 +1704,7 @@ LNetNIFini(void) > > lnet_acceptor_stop(); > lnet_destroy_routes(); > - lnet_shutdown_lndnis(); > + lnet_shutdown_lndnets(); > lnet_unprepare(); > } > > diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c > index 380a3fb1caba..2588d67fea1b 100644 > --- a/drivers/staging/lustre/lnet/lnet/config.c > +++ b/drivers/staging/lustre/lnet/lnet/config.c > @@ -279,6 +279,8 @@ lnet_net_free(struct lnet_net *net) > struct list_head *tmp, *tmp2; > struct lnet_ni *ni; > > + LASSERT(list_empty(&net->net_ni_zombie)); > + > /* delete any nis which have been started. */ > list_for_each_safe(tmp, tmp2, &net->net_ni_list) { > ni = list_entry(tmp, struct lnet_ni, ni_netlist); > @@ -312,6 +314,7 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) > > INIT_LIST_HEAD(&net->net_list); > INIT_LIST_HEAD(&net->net_ni_list); > + INIT_LIST_HEAD(&net->net_ni_zombie); > > net->net_id = net_id; > > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From doucharek at cray.com Wed Sep 12 04:15:06 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:15:06 +0000 Subject: [lustre-devel] [PATCH 21/34] lnet: add net_ni_added In-Reply-To: <153628137207.8267.8628833457984431545.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137207.8267.8628833457984431545.stgit@noble> Message-ID: <09A41DB4-EC94-472F-B511-7EBD5FBCE018@cray.com> I have to say, there are way too many lists being managed in LNet. I'm confusing myself looking at this code again. Wish there was a better way. Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: When we allocate an ni, it is now added to the new net_ni_added list of unstarted interfaces. lnet_startup_lndnet() now starts all those added interfaces. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 3 ++ drivers/staging/lustre/lnet/lnet/api-ni.c | 39 +++++++++++++++++--- drivers/staging/lustre/lnet/lnet/config.c | 13 ++++++- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index dc15fa75a9d2..1faa247a93b8 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -298,6 +298,9 @@ struct lnet_net { /* list of NIs on this net */ struct list_head net_ni_list; + /* list of NIs being added, but not started yet */ + struct list_head net_ni_added; + /* dying LND instances */ struct list_head net_ni_zombie; }; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 960f235df5e7..ce3dd0f32e12 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1350,12 +1350,15 @@ static int lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) { struct lnet_ni *ni; + struct list_head local_ni_list; + int rc; + int ni_count = 0; __u32 lnd_type; struct lnet_lnd *lnd; - int rc; lnd_type = LNET_NETTYP(net->net_id); + INIT_LIST_HEAD(&local_ni_list); LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ @@ -1399,12 +1402,36 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) net->net_lnd = lnd; mutex_unlock(&the_lnet.ln_lnd_mutex); - ni = list_first_entry(&net->net_ni_list, struct lnet_ni, ni_netlist); + while (!list_empty(&net->net_ni_added)) { + ni = list_entry(net->net_ni_added.next, struct lnet_ni, + ni_netlist); + list_del_init(&ni->ni_netlist); - rc = lnet_startup_lndni(ni, tun); - if (rc < 0) - return rc; - return 1; + rc = lnet_startup_lndni(ni, tun); + + if (rc < 0) + goto failed1; + + list_add_tail(&ni->ni_netlist, &local_ni_list); + + ni_count++; + } + lnet_net_lock(LNET_LOCK_EX); + list_splice_tail(&local_ni_list, &net->net_ni_list); + lnet_net_unlock(LNET_LOCK_EX); + return ni_count; + +failed1: + /* + * shutdown the new NIs that are being started up + * free the NET being started + */ + while (!list_empty(&local_ni_list)) { + ni = list_entry(local_ni_list.next, struct lnet_ni, + ni_netlist); + + lnet_shutdown_lndni(ni); + } failed0: lnet_net_free(net); diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 081812e19b13..f886dcfc6d6e 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -281,6 +281,16 @@ lnet_net_free(struct lnet_net *net) LASSERT(list_empty(&net->net_ni_zombie)); + /* + * delete any nis that haven't been added yet. This could happen + * if there is a failure on net startup + */ + list_for_each_safe(tmp, tmp2, &net->net_ni_added) { + ni = list_entry(tmp, struct lnet_ni, ni_netlist); + list_del_init(&ni->ni_netlist); + lnet_ni_free(ni); + } + /* delete any nis which have been started. */ list_for_each_safe(tmp, tmp2, &net->net_ni_list) { ni = list_entry(tmp, struct lnet_ni, ni_netlist); @@ -314,6 +324,7 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) INIT_LIST_HEAD(&net->net_list); INIT_LIST_HEAD(&net->net_ni_list); + INIT_LIST_HEAD(&net->net_ni_added); INIT_LIST_HEAD(&net->net_ni_zombie); net->net_id = net_id; @@ -397,7 +408,7 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); if (rc != 0) goto failed; - list_add_tail(&ni->ni_netlist, &net->net_ni_list); + list_add_tail(&ni->ni_netlist, &net->net_ni_added); return ni; failed: From doucharek at cray.com Wed Sep 12 04:18:21 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:18:21 +0000 Subject: [lustre-devel] [PATCH 22/34] lnet: don't take reference in lnet_XX2ni_locked() In-Reply-To: <153628137211.8267.6066882916704220570.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137211.8267.6066882916704220570.stgit@noble> Message-ID: <3D26740D-2ABC-4596-BDF1-D3E2F186608A@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: lnet_net2ni_locked() and lnet_nid2ni_locked() no longer take a reference - as the lock is held, a ref isn't always needed. Instead, introduce lnet_nid2ni_addref() which does take the reference (but doesn't need the lock). Various places which called lnet_net2ni_locked() or lnet_nid2ni_locked() no longer need to drop the ref afterwards. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 2 + drivers/staging/lustre/lnet/lnet/acceptor.c | 2 + drivers/staging/lustre/lnet/lnet/api-ni.c | 27 +++++++++++++------- drivers/staging/lustre/lnet/lnet/lib-move.c | 17 +------------ 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 54a93235834c..6401d9a37b23 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -398,6 +398,7 @@ extern int avoid_asym_router_failure; int lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni); int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); +struct lnet_ni *lnet_nid2ni_addref(lnet_nid_t nid); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); struct lnet_ni *lnet_net2ni(__u32 net); bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index e64c14914924..af8f863b6a68 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -2294,7 +2294,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) } nid = reqmsg->ibm_srcnid; - ni = lnet_net2ni(LNET_NIDNET(reqmsg->ibm_dstnid)); + ni = lnet_nid2ni_addref(reqmsg->ibm_dstnid); if (ni) { net = (struct kib_net *)ni->ni_data; diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c index 88b90c1fdbaf..25205f686801 100644 --- a/drivers/staging/lustre/lnet/lnet/acceptor.c +++ b/drivers/staging/lustre/lnet/lnet/acceptor.c @@ -296,7 +296,7 @@ lnet_accept(struct socket *sock, __u32 magic) if (flip) __swab64s(&cr.acr_nid); - ni = lnet_net2ni(LNET_NIDNET(cr.acr_nid)); + ni = lnet_nid2ni_addref(cr.acr_nid); if (!ni || /* no matching net */ ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */ if (ni) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ce3dd0f32e12..42e775e2a669 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -655,7 +655,6 @@ lnet_net2ni_locked(__u32 net_id, int cpt) if (net->net_id == net_id) { ni = list_entry(net->net_ni_list.next, struct lnet_ni, ni_netlist); - lnet_ni_addref_locked(ni, cpt); return ni; } } @@ -794,16 +793,29 @@ lnet_nid2ni_locked(lnet_nid_t nid, int cpt) list_for_each_entry(net, &the_lnet.ln_nets, net_list) { list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { - if (ni->ni_nid == nid) { - lnet_ni_addref_locked(ni, cpt); + if (ni->ni_nid == nid) return ni; - } } } return NULL; } +struct lnet_ni * +lnet_nid2ni_addref(lnet_nid_t nid) +{ + struct lnet_ni *ni; + + lnet_net_lock(0); + ni = lnet_nid2ni_locked(nid, 0); + if (ni) + lnet_ni_addref_locked(ni, 0); + lnet_net_unlock(0); + + return ni; +} +EXPORT_SYMBOL(lnet_nid2ni_addref); + int lnet_islocalnid(lnet_nid_t nid) { @@ -812,8 +824,6 @@ lnet_islocalnid(lnet_nid_t nid) cpt = lnet_net_lock_current(); ni = lnet_nid2ni_locked(nid, cpt); - if (ni) - lnet_ni_decref_locked(ni, cpt); lnet_net_unlock(cpt); return !!ni; @@ -1412,6 +1422,7 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) if (rc < 0) goto failed1; + lnet_ni_addref(ni); list_add_tail(&ni->ni_netlist, &local_ni_list); ni_count++; @@ -2032,9 +2043,6 @@ lnet_dyn_del_ni(__u32 net) goto failed; } - /* decrement the reference counter taken by lnet_net2ni() */ - lnet_ni_decref_locked(ni, 0); - lnet_shutdown_lndni(ni); if (!lnet_count_acceptor_nets()) @@ -2264,7 +2272,6 @@ LNetCtl(unsigned int cmd, void *arg) else rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); - lnet_ni_decref(ni); return rc; } /* not reached */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 00a89221c9b3..60f34c4b85d3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1127,11 +1127,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) if (!src_ni) { src_ni = local_ni; src_nid = src_ni->ni_nid; - } else if (src_ni == local_ni) { - lnet_ni_decref_locked(local_ni, cpt); - } else { - lnet_ni_decref_locked(local_ni, cpt); - lnet_ni_decref_locked(src_ni, cpt); + } else if (src_ni != local_ni) { lnet_net_unlock(cpt); LCONSOLE_WARN("No route to %s via from %s\n", libcfs_nid2str(dst_nid), @@ -1149,16 +1145,10 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) /* No send credit hassles with LOLND */ lnet_net_unlock(cpt); lnet_ni_send(src_ni, msg); - - lnet_net_lock(cpt); - lnet_ni_decref_locked(src_ni, cpt); - lnet_net_unlock(cpt); return 0; } rc = lnet_nid2peer_locked(&lp, dst_nid, cpt); - /* lp has ref on src_ni; lose mine */ - lnet_ni_decref_locked(src_ni, cpt); if (rc) { lnet_net_unlock(cpt); LCONSOLE_WARN("Error %d finding peer %s\n", rc, @@ -1173,8 +1163,6 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) src_ni->ni_net : NULL, dst_nid, rtr_nid); if (!lp) { - if (src_ni) - lnet_ni_decref_locked(src_ni, cpt); lnet_net_unlock(cpt); LCONSOLE_WARN("No route to %s via %s (all routers down)\n", @@ -1192,8 +1180,6 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) if (rtr_nid != lp->lp_nid) { cpt2 = lp->lp_cpt; if (cpt2 != cpt) { - if (src_ni) - lnet_ni_decref_locked(src_ni, cpt); lnet_net_unlock(cpt); rtr_nid = lp->lp_nid; @@ -1212,7 +1198,6 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) src_nid = src_ni->ni_nid; } else { LASSERT(src_ni->ni_net == lp->lp_net); - lnet_ni_decref_locked(src_ni, cpt); } lnet_peer_addref_locked(lp); From neilb at suse.com Wed Sep 12 04:25:00 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 14:25:00 +1000 Subject: [lustre-devel] [PATCH 18/34] lnet: add ni_state In-Reply-To: <0DD49EFB-412D-4C87-8FC8-3F0C93D2E98A@cray.com> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137195.8267.16400748098054215181.stgit@noble> <0DD49EFB-412D-4C87-8FC8-3F0C93D2E98A@cray.com> Message-ID: <877ejrqr4z.fsf@notabene.neil.brown.name> On Wed, Sep 12 2018, Doug Oucharek wrote: > I believe the introduction of this state machine is to help us understand how healthy an NI is so we can avoid if it is not healthy and we have other paths which are still ok. > > Reviewed-by: Doug Oucharek Thanks. Now reads: ----------- lnet: add ni_state This will be used more in later patches to track how healthy an NI is, so we can avoid one if it isn't healthy and we have other paths which are still OK. Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown ------------ I noticed that it was used more in later patches, which is why I didn't discard the patch. The original has a "net_state" in lnet_net - I haven't included that change as net_state is still unused. Thanks, NeilBrown > > Doug > > On 9/6/18, 5:54 PM, "NeilBrown" wrote: > > This is barely used. > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + > .../staging/lustre/include/linux/lnet/lib-types.h | 16 ++++++++++++++++ > drivers/staging/lustre/lnet/lnet/api-ni.c | 16 ++++++++++++++++ > drivers/staging/lustre/lnet/lnet/config.c | 1 + > 4 files changed, 34 insertions(+) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index faa3f19dd844..54a93235834c 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -400,6 +400,7 @@ int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); > struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); > struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); > struct lnet_ni *lnet_net2ni(__u32 net); > +bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); > > extern int portal_rotor; > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 1d372672e2de..6c34ecf22021 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -256,6 +256,19 @@ struct lnet_tx_queue { > struct list_head tq_delayed; /* delayed TXs */ > }; > > +enum lnet_ni_state { > + /* set when NI block is allocated */ > + LNET_NI_STATE_INIT = 0, > + /* set when NI is started successfully */ > + LNET_NI_STATE_ACTIVE, > + /* set when LND notifies NI failed */ > + LNET_NI_STATE_FAILED, > + /* set when LND notifies NI degraded */ > + LNET_NI_STATE_DEGRADED, > + /* set when shuttding down NI */ > + LNET_NI_STATE_DELETING > +}; > + > struct lnet_net { > /* chain on the ln_nets */ > struct list_head net_list; > @@ -324,6 +337,9 @@ struct lnet_ni { > /* my health status */ > struct lnet_ni_status *ni_status; > > + /* NI FSM */ > + enum lnet_ni_state ni_state; > + > /* per NI LND tunables */ > struct lnet_lnd_tunables ni_lnd_tunables; > > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 46c5ca71bc07..618fdf8141f0 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -780,6 +780,16 @@ lnet_islocalnet(__u32 net) > return !!ni; > } > > +bool > +lnet_is_ni_healthy_locked(struct lnet_ni *ni) > +{ > + if (ni->ni_state == LNET_NI_STATE_ACTIVE || > + ni->ni_state == LNET_NI_STATE_DEGRADED) > + return true; > + > + return false; > +} > + > struct lnet_ni * > lnet_nid2ni_locked(lnet_nid_t nid, int cpt) > { > @@ -1117,6 +1127,9 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net) > ni = list_entry(zombie_list->next, > struct lnet_ni, ni_netlist); > list_del_init(&ni->ni_netlist); > + /* the ni should be in deleting state. If it's not it's > + * a bug */ > + LASSERT(ni->ni_state == LNET_NI_STATE_DELETING); > cfs_percpt_for_each(ref, j, ni->ni_refs) { > if (!*ref) > continue; > @@ -1163,6 +1176,7 @@ lnet_shutdown_lndni(struct lnet_ni *ni) > struct lnet_net *net = ni->ni_net; > > lnet_net_lock(LNET_LOCK_EX); > + ni->ni_state = LNET_NI_STATE_DELETING; > lnet_ni_unlink_locked(ni); > lnet_net_unlock(LNET_LOCK_EX); > > @@ -1291,6 +1305,8 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) > > lnet_net_unlock(LNET_LOCK_EX); > > + ni->ni_state = LNET_NI_STATE_ACTIVE; > + > if (net->net_lnd->lnd_type == LOLND) { > lnet_ni_addref(ni); > LASSERT(!the_lnet.ln_loni); > diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c > index 2588d67fea1b..081812e19b13 100644 > --- a/drivers/staging/lustre/lnet/lnet/config.c > +++ b/drivers/staging/lustre/lnet/lnet/config.c > @@ -393,6 +393,7 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) > ni->ni_net_ns = NULL; > > ni->ni_last_alive = ktime_get_real_seconds(); > + ni->ni_state = LNET_NI_STATE_INIT; > rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); > if (rc != 0) > goto failed; > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From doucharek at cray.com Wed Sep 12 04:27:58 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:27:58 +0000 Subject: [lustre-devel] [PATCH 23/34] lnet: don't need lock to test ln_shutdown. In-Reply-To: <153628137216.8267.15666994772553520296.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137216.8267.15666994772553520296.stgit@noble> Message-ID: <41CB4483-3CFE-4EC2-9980-CBCBE6B3FE88@cray.com> It seems the selection code being affected by this patch later gets moved to its own routine called lnet_select_pathway(). The logic is completely re-written so it may not be important to fix the use of locks here. However, it is not good that the lock is not being held while checking for shutdown. Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: ln_shutdown returns -ESHUTDOWN if ln_shutdown is already set. The lock is always taken to set ln_shutdown, but apparently we don't need to hold the lock for this test. I guess if it is set immediately after the test, and before we take the lock then.... can anything bad happen? This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/lib-move.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 60f34c4b85d3..46e593fbb44f 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1099,12 +1099,9 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid, local_ni); again: - lnet_net_lock(cpt); - - if (the_lnet.ln_shutdown) { - lnet_net_unlock(cpt); + if (the_lnet.ln_shutdown) return -ESHUTDOWN; - } + lnet_net_lock(cpt); if (src_nid == LNET_NID_ANY) { src_ni = NULL; From doucharek at cray.com Wed Sep 12 04:29:15 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:29:15 +0000 Subject: [lustre-devel] [PATCH 24/34] lnet: don't take lock over lnet_net_unique() In-Reply-To: <153628137220.8267.9479780300443400770.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137220.8267.9479780300443400770.stgit@noble> Message-ID: Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: holding ln_api_mutex is enough to keep the list stable. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 42e775e2a669..2b5c25a1dc7c 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1372,9 +1372,7 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ - lnet_net_lock(LNET_LOCK_EX); rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); - lnet_net_unlock(LNET_LOCK_EX); if (!rc) { if (lnd_type == LOLND) { lnet_net_free(net); From doucharek at cray.com Wed Sep 12 04:32:36 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:32:36 +0000 Subject: [lustre-devel] [PATCH 25/34] lnet: swap 'then' and 'else' branches in lnet_startup_lndnet In-Reply-To: <153628137225.8267.589541269937133692.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137225.8267.589541269937133692.stgit@noble> Message-ID: <2EBFAE62-F94C-4E75-89DA-9685518F47A5@cray.com> Hmm...if we made lnd_refcount atomic, could we get rid of unnecessary calls to lnet_net_lock(LNET_LOCK_EX) ? Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:54 PM, "NeilBrown" wrote: This swap makes the diff for the next patch more readable. We also stop storing the return value from lnet_net_unique() as it is never used. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 55 +++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2b5c25a1dc7c..ab4d093c04da 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1372,8 +1372,34 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ - rc = lnet_net_unique(net->net_id, &the_lnet.ln_nets); - if (!rc) { + if (lnet_net_unique(net->net_id, &the_lnet.ln_nets)) { + mutex_lock(&the_lnet.ln_lnd_mutex); + lnd = lnet_find_lnd_by_type(lnd_type); + + if (lnd == NULL) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + rc = request_module("%s", libcfs_lnd2modname(lnd_type)); + mutex_lock(&the_lnet.ln_lnd_mutex); + + lnd = lnet_find_lnd_by_type(lnd_type); + if (lnd == NULL) { + mutex_unlock(&the_lnet.ln_lnd_mutex); + CERROR("Can't load LND %s, module %s, rc=%d\n", + libcfs_lnd2str(lnd_type), + libcfs_lnd2modname(lnd_type), rc); + rc = -EINVAL; + goto failed0; + } + } + + lnet_net_lock(LNET_LOCK_EX); + lnd->lnd_refcount++; + lnet_net_unlock(LNET_LOCK_EX); + + net->net_lnd = lnd; + + mutex_unlock(&the_lnet.ln_lnd_mutex); + } else { if (lnd_type == LOLND) { lnet_net_free(net); return 0; @@ -1385,31 +1411,6 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) goto failed0; } - mutex_lock(&the_lnet.ln_lnd_mutex); - lnd = lnet_find_lnd_by_type(lnd_type); - - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - rc = request_module("%s", libcfs_lnd2modname(lnd_type)); - mutex_lock(&the_lnet.ln_lnd_mutex); - - lnd = lnet_find_lnd_by_type(lnd_type); - if (!lnd) { - mutex_unlock(&the_lnet.ln_lnd_mutex); - CERROR("Can't load LND %s, module %s, rc=%d\n", - libcfs_lnd2str(lnd_type), - libcfs_lnd2modname(lnd_type), rc); - rc = -EINVAL; - goto failed0; - } - } - - lnet_net_lock(LNET_LOCK_EX); - lnd->lnd_refcount++; - lnet_net_unlock(LNET_LOCK_EX); - net->net_lnd = lnd; - mutex_unlock(&the_lnet.ln_lnd_mutex); - while (!list_empty(&net->net_ni_added)) { ni = list_entry(net->net_ni_added.next, struct lnet_ni, ni_netlist); From doucharek at cray.com Wed Sep 12 04:34:14 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:34:14 +0000 Subject: [lustre-devel] [PATCH 26/34] lnet: only valid lnd_type when net_id is unique. In-Reply-To: <153628137230.8267.13002746471298616108.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137230.8267.13002746471298616108.stgit@noble> Message-ID: <74A69DE4-7A94-4BDC-96E9-9F45C2108D61@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: If it isn't unique, we won't add it, so no need to validate. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ab4d093c04da..0dfd3004f735 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1366,13 +1366,14 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) __u32 lnd_type; struct lnet_lnd *lnd; - lnd_type = LNET_NETTYP(net->net_id); - INIT_LIST_HEAD(&local_ni_list); - LASSERT(libcfs_isknown_lnd(lnd_type)); /* Make sure this new NI is unique. */ if (lnet_net_unique(net->net_id, &the_lnet.ln_nets)) { + lnd_type = LNET_NETTYP(net->net_id); + + LASSERT(libcfs_isknown_lnd(lnd_type)); + mutex_lock(&the_lnet.ln_lnd_mutex); lnd = lnet_find_lnd_by_type(lnd_type); From doucharek at cray.com Wed Sep 12 04:38:18 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:38:18 +0000 Subject: [lustre-devel] [PATCH 27/34] lnet: make it possible to add a new interface to a network In-Reply-To: <153628137234.8267.14872362382875902424.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137234.8267.14872362382875902424.stgit@noble> Message-ID: Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: lnet_startup_lndnet() is enhanced to cope if the net already exists. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 + drivers/staging/lustre/lnet/lnet/api-ni.c | 69 +++++++++++++++----- drivers/staging/lustre/lnet/lnet/config.c | 12 ++- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 6401d9a37b23..905213fc16c7 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -630,7 +630,8 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); int lnet_parse_routes(char *route_str, int *im_a_router); int lnet_parse_networks(struct list_head *nilist, char *networks); -bool lnet_net_unique(__u32 net, struct list_head *nilist); +bool lnet_net_unique(__u32 net_id, struct list_head *nilist, + struct lnet_net **net); int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 0dfd3004f735..042ab0d9e318 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1298,14 +1298,9 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) goto failed0; } - lnet_net_lock(LNET_LOCK_EX); - /* refcount for ln_nis */ - lnet_ni_addref_locked(ni, 0); - list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); - lnet_net_unlock(LNET_LOCK_EX); - ni->ni_state = LNET_NI_STATE_ACTIVE; + /* We keep a reference on the loopback net through the loopback NI */ if (net->net_lnd->lnd_type == LOLND) { lnet_ni_addref(ni); LASSERT(!the_lnet.ln_loni); @@ -1360,6 +1355,7 @@ static int lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) { struct lnet_ni *ni; + struct lnet_net *net_l = NULL; struct list_head local_ni_list; int rc; int ni_count = 0; @@ -1368,8 +1364,14 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) INIT_LIST_HEAD(&local_ni_list); - /* Make sure this new NI is unique. */ - if (lnet_net_unique(net->net_id, &the_lnet.ln_nets)) { + /* + * make sure that this net is unique. If it isn't then + * we are adding interfaces to an already existing network, and + * 'net' is just a convenient way to pass in the list. + * if it is unique we need to find the LND and load it if + * necessary. + */ + if (lnet_net_unique(net->net_id, &the_lnet.ln_nets, &net_l)) { lnd_type = LNET_NETTYP(net->net_id); LASSERT(libcfs_isknown_lnd(lnd_type)); @@ -1400,23 +1402,41 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) net->net_lnd = lnd; mutex_unlock(&the_lnet.ln_lnd_mutex); - } else { - if (lnd_type == LOLND) { - lnet_net_free(net); - return 0; - } - CERROR("Net %s is not unique\n", - libcfs_net2str(net->net_id)); - rc = -EEXIST; - goto failed0; + net_l = net; } + /* + * net_l: if the network being added is unique then net_l + * will point to that network + * if the network being added is not unique then + * net_l points to the existing network. + * + * When we enter the loop below, we'll pick NIs off he + * network beign added and start them up, then add them to + * a local ni list. Once we've successfully started all + * the NIs then we join the local NI list (of started up + * networks) with the net_l->net_ni_list, which should + * point to the correct network to add the new ni list to + * + * If any of the new NIs fail to start up, then we want to + * iterate through the local ni list, which should include + * any NIs which were successfully started up, and shut + * them down. + * + * After than we want to delete the network being added, + * to avoid a memory leak. + */ + while (!list_empty(&net->net_ni_added)) { ni = list_entry(net->net_ni_added.next, struct lnet_ni, ni_netlist); list_del_init(&ni->ni_netlist); + /* adjust the pointer the parent network, just in case it + * the net is a duplicate */ + ni->ni_net = net_l; + rc = lnet_startup_lndni(ni, tun); if (rc < 0) @@ -1427,9 +1447,22 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) ni_count++; } + lnet_net_lock(LNET_LOCK_EX); - list_splice_tail(&local_ni_list, &net->net_ni_list); + list_splice_tail(&local_ni_list, &net_l->net_ni_list); lnet_net_unlock(LNET_LOCK_EX); + + /* if the network is not unique then we don't want to keep + * it around after we're done. Free it. Otherwise add that + * net to the global the_lnet.ln_nets */ + if (net_l != net && net_l != NULL) { + lnet_net_free(net); + } else { + lnet_net_lock(LNET_LOCK_EX); + list_add_tail(&net->net_list, &the_lnet.ln_nets); + lnet_net_unlock(LNET_LOCK_EX); + } + return ni_count; failed1: diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index f886dcfc6d6e..fcae50676422 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -79,13 +79,17 @@ lnet_issep(char c) } bool -lnet_net_unique(__u32 net, struct list_head *netlist) +lnet_net_unique(__u32 net_id, struct list_head *netlist, + struct lnet_net **net) { - struct lnet_net *net_l; + struct lnet_net *net_l; list_for_each_entry(net_l, netlist, net_list) { - if (net_l->net_id == net) + if (net_l->net_id == net_id) { + if (net != NULL) + *net = net_l; return false; + } } return true; @@ -309,7 +313,7 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) { struct lnet_net *net; - if (!lnet_net_unique(net_id, net_list)) { + if (!lnet_net_unique(net_id, net_list, NULL)) { CERROR("Duplicate net %s. Ignore\n", libcfs_net2str(net_id)); return NULL; From doucharek at cray.com Wed Sep 12 04:39:56 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:39:56 +0000 Subject: [lustre-devel] [PATCH 28/34] lnet: add checks to ensure network interface names are unique. In-Reply-To: <153628137237.8267.13304938702171788855.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137237.8267.13304938702171788855.stgit@noble> Message-ID: <3831B6C9-AC8F-433F-82FB-B79BCBAC616F@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + drivers/staging/lustre/lnet/lnet/api-ni.c | 8 ++++++ drivers/staging/lustre/lnet/lnet/config.c | 25 ++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 905213fc16c7..ef551b571935 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -632,6 +632,7 @@ int lnet_parse_routes(char *route_str, int *im_a_router); int lnet_parse_networks(struct list_head *nilist, char *networks); bool lnet_net_unique(__u32 net_id, struct list_head *nilist, struct lnet_net **net); +bool lnet_ni_unique_net(struct list_head *nilist, char *iface); int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 042ab0d9e318..3f6f5ead8a03 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1433,6 +1433,14 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) ni_netlist); list_del_init(&ni->ni_netlist); + /* make sure that the the NI we're about to start + * up is actually unique. if it's not fail. */ + if (!lnet_ni_unique_net(&net_l->net_ni_list, + ni->ni_interfaces[0])) { + rc = -EINVAL; + goto failed1; + } + /* adjust the pointer the parent network, just in case it * the net is a duplicate */ ni->ni_net = net_l; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index fcae50676422..11d6dbc80507 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -95,6 +95,25 @@ lnet_net_unique(__u32 net_id, struct list_head *netlist, return true; } +/* check that the NI is unique within the list of NIs already added to + * a network */ +bool +lnet_ni_unique_net(struct list_head *nilist, char *iface) +{ + struct list_head *tmp; + struct lnet_ni *ni; + + list_for_each(tmp, nilist) { + ni = list_entry(tmp, struct lnet_ni, ni_netlist); + + if (ni->ni_interfaces[0] != NULL && + strncmp(ni->ni_interfaces[0], iface, strlen(iface)) == 0) + return false; + } + + return true; +} + static bool in_array(__u32 *array, __u32 size, __u32 value) { @@ -352,6 +371,12 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) int rc; int i; + if (iface != NULL) + /* make sure that this NI is unique in the net it's + * being added to */ + if (!lnet_ni_unique_net(&net->net_ni_added, iface)) + return NULL; + ni = kzalloc(sizeof(*ni), GFP_KERNEL); if (ni == NULL) { CERROR("Out of memory creating network interface %s%s\n", From doucharek at cray.com Wed Sep 12 04:47:03 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:47:03 +0000 Subject: [lustre-devel] [PATCH 29/34] lnet: track tunables in lnet_startup_lndnet() In-Reply-To: <153628137241.8267.17639366442733480713.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137241.8267.17639366442733480713.stgit@noble> Message-ID: <7B17D070-1A0A-4609-A58E-8D0785879D3F@cray.com> Amir: You need to comment on this one. It looks to me that it starts off by making a copy of three tunables to see if the user has set them specific to the NET. Then, if the LND changes them, it changes them back to what the user set. What I don't get: why would the LND change the values if they are not -1? Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: Not really sure what this is yet. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 3f6f5ead8a03..f4efb48c4cf3 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1361,6 +1361,12 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) int ni_count = 0; __u32 lnd_type; struct lnet_lnd *lnd; + int peer_timeout = + net->net_tunables.lct_peer_timeout; + int maxtxcredits = + net->net_tunables.lct_max_tx_credits; + int peerrtrcredits = + net->net_tunables.lct_peer_rtr_credits; INIT_LIST_HEAD(&local_ni_list); @@ -1447,6 +1453,9 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) rc = lnet_startup_lndni(ni, tun); + LASSERT(ni->ni_net->net_tunables.lct_peer_timeout <= 0 || + ni->ni_net->net_lnd->lnd_query != NULL); + if (rc < 0) goto failed1; @@ -1464,8 +1473,23 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) * it around after we're done. Free it. Otherwise add that * net to the global the_lnet.ln_nets */ if (net_l != net && net_l != NULL) { + /* + * TODO - note. currently the tunables can not be updated + * once added + */ lnet_net_free(net); } else { + /* + * restore tunables after it has been overwitten by the + * lnd + */ + if (peer_timeout != -1) + net->net_tunables.lct_peer_timeout = peer_timeout; + if (maxtxcredits != -1) + net->net_tunables.lct_max_tx_credits = maxtxcredits; + if (peerrtrcredits != -1) + net->net_tunables.lct_peer_rtr_credits = peerrtrcredits; + lnet_net_lock(LNET_LOCK_EX); list_add_tail(&net->net_list, &the_lnet.ln_nets); lnet_net_unlock(LNET_LOCK_EX); From doucharek at cray.com Wed Sep 12 04:47:29 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:47:29 +0000 Subject: [lustre-devel] [PATCH 30/34] lnet: fix typo In-Reply-To: <153628137245.8267.15918400233109764157.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137245.8267.15918400233109764157.stgit@noble> Message-ID: <0AB7DCED-0F17-4FF1-9E71-C70713583B4B@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: to -> too This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index f4efb48c4cf3..cf0ffb8ac84b 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1868,7 +1868,7 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) if (config->cfg_hdr.ioc_len > min_size) tunable_size = config->cfg_hdr.ioc_len - min_size; - /* Don't copy to much data to user space */ + /* Don't copy too much data to user space */ min_size = min(tunable_size, sizeof(ni->ni_lnd_tunables)); lnd_cfg = (struct lnet_ioctl_config_lnd_tunables *)net_config->cfg_bulk; From doucharek at cray.com Wed Sep 12 04:48:32 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:48:32 +0000 Subject: [lustre-devel] [PATCH 31/34] lnet: lnet_dyn_add_ni: fix ping_info count In-Reply-To: <153628137248.8267.6726065772840936203.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137248.8267.6726065772840936203.stgit@noble> Message-ID: <45251532-129B-4DAD-A0FD-ADD0E51E15CA@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: Use the correct count of interfaces when calling lnet_ping_info_setup() in lnet_dyn_add_ni() Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index cf0ffb8ac84b..2ce0a7212dc2 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -871,6 +871,18 @@ lnet_ping_info_create(int num_ni) return ping_info; } +static inline int +lnet_get_net_ni_count_locked(struct lnet_net *net) +{ + struct lnet_ni *ni; + int count = 0; + + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) + count++; + + return count; +} + static inline int lnet_get_ni_count(void) { @@ -1977,6 +1989,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) struct list_head net_head; struct lnet_remotenet *rnet; int rc; + int net_ni_count; int num_acceptor_nets; __u32 net_type; struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; @@ -2014,7 +2027,19 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) goto failed0; } - rc = lnet_ping_info_setup(&pinfo, &md_handle, 1 + lnet_get_ni_count(), + /* + * make sure you calculate the correct number of slots in the ping + * info. Since the ping info is a flattened list of all the NIs, + * we should allocate enough slots to accomodate the number of NIs + * which will be added. + * + * We can use lnet_get_net_ni_count_locked() since the net is not + * on a public list yet, so locking is not a problem + */ + net_ni_count = lnet_get_net_ni_count_locked(net); + + rc = lnet_ping_info_setup(&pinfo, &md_handle, + net_ni_count + lnet_get_ni_count(), false); if (rc) goto failed0; From doucharek at cray.com Wed Sep 12 04:49:48 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:49:48 +0000 Subject: [lustre-devel] [PATCH 32/34] lnet: lnet_dyn_del_ni: fix ping_info count In-Reply-To: <153628137252.8267.5413803631901452139.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137252.8267.5413803631901452139.stgit@noble> Message-ID: <065B4E44-A590-4DFB-99D3-1E80DA91FE78@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: - use correct interface count for lnet_ping_info_setup(). - also rename 'net' to 'net_id' so the name 'net' is free to identify the lnet_net. This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 35 +++++++++++++++++------------ 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2ce0a7212dc2..ff5149da2d79 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -2109,40 +2109,45 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) } int -lnet_dyn_del_ni(__u32 net) +lnet_dyn_del_ni(__u32 net_id) { - struct lnet_ni *ni; + struct lnet_net *net; struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; int rc; + int net_ni_count; /* don't allow userspace to shutdown the LOLND */ - if (LNET_NETTYP(net) == LOLND) + if (LNET_NETTYP(net_id) == LOLND) return -EINVAL; mutex_lock(&the_lnet.ln_api_mutex); + + lnet_net_lock(0); + + net = lnet_get_net_locked(net_id); + if (net == NULL) { + rc = -EINVAL; + goto out; + } + + net_ni_count = lnet_get_net_ni_count_locked(net); + + lnet_net_unlock(0); + /* create and link a new ping info, before removing the old one */ rc = lnet_ping_info_setup(&pinfo, &md_handle, - lnet_get_ni_count() - 1, false); + lnet_get_ni_count() - net_ni_count, false); if (rc) goto out; - ni = lnet_net2ni(net); - if (!ni) { - rc = -EINVAL; - goto failed; - } - - lnet_shutdown_lndni(ni); + lnet_shutdown_lndnet(net); if (!lnet_count_acceptor_nets()) lnet_acceptor_stop(); lnet_ping_target_update(pinfo, md_handle); - goto out; -failed: - lnet_ping_md_unlink(pinfo, &md_handle); - lnet_ping_info_free(pinfo); + out: mutex_unlock(&the_lnet.ln_api_mutex); From doucharek at cray.com Wed Sep 12 04:54:18 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:54:18 +0000 Subject: [lustre-devel] [PATCH 33/34] Completely re-write lnet_parse_networks(). In-Reply-To: <153628137255.8267.7924367116215461900.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137255.8267.7924367116215461900.stgit@noble> Message-ID: <260B47CF-351E-43CD-964D-E1A4D383082E@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:55 PM, "NeilBrown" wrote: From: Amir Shehata Was: LU-7734 lnet: Multi-Rail local NI split This patch allows the configuration of multiple NIs under one Net. It is now possible to have multiple NIDs on the same network: Ex: @tcp, @tcp. This can be configured using the following syntax: Ex: tcp(eth0, eth1) The data structures for the example above can be visualized as follows NET(tcp) | ----------------- | | NI(eth0) NI(eth1) For more details refer to the Mult-Rail Requirements and HLD documents Signed-off-by: Amir Shehata Change-Id: Id7c73b9b811a3082b61e53b9e9f95743188cbd51 Reviewed-on: http://review.whamcloud.com/18274 Tested-by: Jenkins Reviewed-by: Doug Oucharek Tested-by: Maloo Reviewed-by: Olaf Weber --- drivers/staging/lustre/lnet/lnet/config.c | 341 ++++++++++++++++++----------- 1 file changed, 217 insertions(+), 124 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 11d6dbc80507..0571fa6a7249 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -48,8 +48,11 @@ static int lnet_tbnob; /* track text buf allocation */ #define LNET_MAX_TEXTBUF_NOB (64 << 10) /* bound allocation */ #define LNET_SINGLE_TEXTBUF_NOB (4 << 10) +#define SPACESTR " \t\v\r\n" +#define DELIMITERS ":()[]" + static void -lnet_syntax(char *name, char *str, int offset, int width) +lnet_syntax(const char *name, const char *str, int offset, int width) { static char dots[LNET_SINGLE_TEXTBUF_NOB]; static char dashes[LNET_SINGLE_TEXTBUF_NOB]; @@ -363,6 +366,42 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) return net; } +static int +lnet_ni_add_interface(struct lnet_ni *ni, char *iface) +{ + int niface = 0; + + if (ni == NULL) + return -ENOMEM; + + /* Allocate a separate piece of memory and copy + * into it the string, so we don't have + * a depencency on the tokens string. This way we + * can free the tokens at the end of the function. + * The newly allocated ni_interfaces[] can be + * freed when freeing the NI */ + while (niface < LNET_MAX_INTERFACES && + ni->ni_interfaces[niface] != NULL) + niface++; + + if (niface >= LNET_MAX_INTERFACES) { + LCONSOLE_ERROR_MSG(0x115, "Too many interfaces " + "for net %s\n", + libcfs_net2str(LNET_NIDNET(ni->ni_nid))); + return -EINVAL; + } + + ni->ni_interfaces[niface] = kstrdup(iface, GFP_KERNEL); + + if (ni->ni_interfaces[niface] == NULL) { + CERROR("Can't allocate net interface name\n"); + return -ENOMEM; + } + + return 0; +} + +/* allocate and add to the provided network */ struct lnet_ni * lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) { @@ -439,24 +478,33 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) goto failed; list_add_tail(&ni->ni_netlist, &net->net_ni_added); + /* if an interface name is provided then make sure to add in that + * interface name in NI */ + if (iface != NULL) + if (lnet_ni_add_interface(ni, iface) != 0) + goto failed; + return ni; failed: lnet_ni_free(ni); return NULL; } +/* + * Parse the networks string and create the matching set of NIs on the + * nilist. + */ int lnet_parse_networks(struct list_head *netlist, char *networks) { - struct cfs_expr_list *el = NULL; + struct cfs_expr_list *net_el = NULL; + struct cfs_expr_list *ni_el = NULL; char *tokens; char *str; - char *tmp; struct lnet_net *net; struct lnet_ni *ni = NULL; __u32 net_id; int nnets = 0; - struct list_head *temp_node; if (!networks) { CERROR("networks string is undefined\n"); @@ -476,84 +524,108 @@ lnet_parse_networks(struct list_head *netlist, char *networks) return -ENOMEM; } - tmp = tokens; str = tokens; - while (str && *str) { - char *comma = strchr(str, ','); - char *bracket = strchr(str, '('); - char *square = strchr(str, '['); - char *iface; - int niface; + /* + * Main parser loop. + * + * NB we don't check interface conflicts here; it's the LNDs + * responsibility (if it cares at all) + */ + do { + char *nistr; + char *elstr; + char *name; int rc; /* - * NB we don't check interface conflicts here; it's the LNDs - * responsibility (if it cares at all) + * Parse a network string into its components. + * + * {"("...")"}{"[""]"} */ - if (square && (!comma || square < comma)) { - /* - * i.e: o2ib0(ib0)[1,2], number between square - * brackets are CPTs this NI needs to be bond - */ - if (bracket && bracket > square) { - tmp = square; + + /* Network name (mandatory) + */ + while (isspace(*str)) + *str++ = '\0'; + if (!*str) + break; + name = str; + str += strcspn(str, SPACESTR ":()[],"); + while (isspace(*str)) + *str++ = '\0'; + + /* Interface list (optional) */ + if (*str == '(') { + *str++ = '\0'; + nistr = str; + str += strcspn(str, ")"); + if (*str != ')') { + str = nistr; goto failed_syntax; } + do { + *str++ = '\0'; + } while (isspace(*str)); + } else { + nistr = NULL; + } - tmp = strchr(square, ']'); - if (!tmp) { - tmp = square; + /* CPT expression (optional) */ + if (*str == '[') { + elstr = str; + str += strcspn(str, "]"); + if (*str != ']') { + str = elstr; goto failed_syntax; } - - rc = cfs_expr_list_parse(square, tmp - square + 1, - 0, LNET_CPT_NUMBER - 1, &el); + rc = cfs_expr_list_parse(elstr, str - elstr + 1, + 0, LNET_CPT_NUMBER - 1, + &net_el); if (rc) { - tmp = square; + str = elstr; goto failed_syntax; } - - while (square <= tmp) - *square++ = ' '; + *elstr = '\0'; + do { + *str++ = '\0'; + } while (isspace(*str)); } - if (!bracket || (comma && comma < bracket)) { - /* no interface list specified */ + /* Bad delimiters */ + if (*str && (strchr(DELIMITERS, *str) != NULL)) + goto failed_syntax; - if (comma) - *comma++ = 0; - net_id = libcfs_str2net(strim(str)); + /* go to the next net if it exits */ + str += strcspn(str, ","); + if (*str == ',') + *str++ = '\0'; - if (net_id == LNET_NIDNET(LNET_NID_ANY)) { - LCONSOLE_ERROR_MSG(0x113, - "Unrecognised network type\n"); - tmp = str; - goto failed_syntax; - } - - if (LNET_NETTYP(net_id) != LOLND) { /* LO is implicit */ - net = lnet_net_alloc(net_id, netlist); - if (!net || - !lnet_ni_alloc(net, el, NULL)) - goto failed; - } + /* + * At this point the name is properly terminated. + */ + net_id = libcfs_str2net(name); + if (net_id == LNET_NIDNET(LNET_NID_ANY)) { + LCONSOLE_ERROR_MSG(0x113, + "Unrecognised network type\n"); + str = name; + goto failed_syntax; + } - if (el) { - cfs_expr_list_free(el); - el = NULL; + if (LNET_NETTYP(net_id) == LOLND) { + /* Loopback is implicit, and there can be only one. */ + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; } - - str = comma; + /* Should we error out instead? */ continue; } - *bracket = 0; - net_id = libcfs_str2net(strim(str)); - if (net_id == LNET_NIDNET(LNET_NID_ANY)) { - tmp = str; - goto failed_syntax; - } + /* + * All network paramaters are now known. + */ + nnets++; /* always allocate a net, since we will eventually add an * interface to it, or we will fail, in which case we'll @@ -562,88 +634,107 @@ lnet_parse_networks(struct list_head *netlist, char *networks) if (IS_ERR_OR_NULL(net)) goto failed; - ni = lnet_ni_alloc(net, el, NULL); - if (IS_ERR_OR_NULL(ni)) - goto failed; - - if (el) { - cfs_expr_list_free(el); - el = NULL; - } - - niface = 0; - iface = bracket + 1; + if (!nistr) { + /* + * No interface list was specified, allocate a + * ni using the defaults. + */ + ni = lnet_ni_alloc(net, net_el, NULL); + if (IS_ERR_OR_NULL(ni)) + goto failed; - bracket = strchr(iface, ')'); - if (!bracket) { - tmp = iface; - goto failed_syntax; + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; + } + continue; } - *bracket = 0; do { - comma = strchr(iface, ','); - if (comma) - *comma++ = 0; - - iface = strim(iface); - if (!*iface) { - tmp = iface; - goto failed_syntax; + elstr = NULL; + + /* Interface name (mandatory) */ + while (isspace(*nistr)) + *nistr++ = '\0'; + name = nistr; + nistr += strcspn(nistr, SPACESTR "[],"); + while (isspace(*nistr)) + *nistr++ = '\0'; + + /* CPT expression (optional) */ + if (*nistr == '[') { + elstr = nistr; + nistr += strcspn(nistr, "]"); + if (*nistr != ']') { + str = elstr; + goto failed_syntax; + } + rc = cfs_expr_list_parse(elstr, + nistr - elstr + 1, + 0, LNET_CPT_NUMBER - 1, + &ni_el); + if (rc != 0) { + str = elstr; + goto failed_syntax; + } + *elstr = '\0'; + do { + *nistr++ = '\0'; + } while (isspace(*nistr)); + } else { + ni_el = net_el; } - if (niface == LNET_MAX_INTERFACES) { - LCONSOLE_ERROR_MSG(0x115, - "Too many interfaces for net %s\n", - libcfs_net2str(net_id)); - goto failed; + /* + * End of single interface specificaton, + * advance to the start of the next one, if + * any. + */ + if (*nistr == ',') { + do { + *nistr++ = '\0'; + } while (isspace(*nistr)); + if (!*nistr) { + str = nistr; + goto failed_syntax; + } + } else if (*nistr) { + str = nistr; + goto failed_syntax; } /* - * Allocate a separate piece of memory and copy - * into it the string, so we don't have - * a depencency on the tokens string. This way we - * can free the tokens at the end of the function. - * The newly allocated ni_interfaces[] can be - * freed when freeing the NI + * At this point the name + is properly terminated. */ - ni->ni_interfaces[niface] = kstrdup(iface, GFP_KERNEL); - if (!ni->ni_interfaces[niface]) { - CERROR("Can't allocate net interface name\n"); - goto failed; - } - niface++; - iface = comma; - } while (iface); - - str = bracket + 1; - comma = strchr(bracket + 1, ','); - if (comma) { - *comma = 0; - str = strim(str); - if (*str) { - tmp = str; + if (!*name) { + str = name; goto failed_syntax; } - str = comma + 1; - continue; - } - str = strim(str); - if (*str) { - tmp = str; - goto failed_syntax; - } - } + ni = lnet_ni_alloc(net, ni_el, name); + if (IS_ERR_OR_NULL(ni)) + goto failed; - list_for_each(temp_node, netlist) - nnets++; + if (ni_el) { + if (ni_el != net_el) { + cfs_expr_list_free(ni_el); + ni_el = NULL; + } + } + } while (*nistr); + + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; + } + } while (*str); kfree(tokens); return nnets; failed_syntax: - lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp)); + lnet_syntax("networks", networks, (int)(str - tokens), strlen(str)); failed: /* free the net list and all the nis on each net */ while (!list_empty(netlist)) { @@ -653,8 +744,10 @@ lnet_parse_networks(struct list_head *netlist, char *networks) lnet_net_free(net); } - if (el) - cfs_expr_list_free(el); + if (ni_el && ni_el != net_el) + cfs_expr_list_free(ni_el); + if (net_el) + cfs_expr_list_free(net_el); kfree(tokens); From doucharek at cray.com Wed Sep 12 04:54:49 2018 From: doucharek at cray.com (Doug Oucharek) Date: Wed, 12 Sep 2018 04:54:49 +0000 Subject: [lustre-devel] [PATCH 34/34] lnet: introduce use_tcp_bonding mod param In-Reply-To: <153628137259.8267.2306617574801795911.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137259.8267.2306617574801795911.stgit@noble> Message-ID: <4DA7E7FA-7658-40E5-986D-313DF02B21DC@cray.com> Reviewed-by: Doug Oucharek Doug On 9/6/18, 5:56 PM, "NeilBrown" wrote: This is part of 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 LU-7734 lnet: Multi-Rail local NI split Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 + drivers/staging/lustre/lnet/lnet/api-ni.c | 22 ++++++++- drivers/staging/lustre/lnet/lnet/config.c | 50 ++++++++++++++++---- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index ef551b571935..5ee770cd7a5f 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -629,7 +629,8 @@ void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); int lnet_parse_routes(char *route_str, int *im_a_router); -int lnet_parse_networks(struct list_head *nilist, char *networks); +int lnet_parse_networks(struct list_head *nilist, char *networks, + bool use_tcp_bonding); bool lnet_net_unique(__u32 net_id, struct list_head *nilist, struct lnet_net **net); bool lnet_ni_unique_net(struct list_head *nilist, char *iface); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ff5149da2d79..8ff386992c99 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -59,6 +59,11 @@ static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT; module_param(rnet_htable_size, int, 0444); MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table"); +static int use_tcp_bonding = false; +module_param(use_tcp_bonding, int, 0444); +MODULE_PARM_DESC(use_tcp_bonding, + "Set to 1 to use socklnd bonding. 0 to use Multi-Rail"); + static int lnet_ping(struct lnet_process_id id, signed long timeout, struct lnet_process_id __user *ids, int n_ids); @@ -1446,6 +1451,18 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) * to avoid a memory leak. */ + /* + * When a network uses TCP bonding then all its interfaces + * must be specified when the network is first defined: the + * TCP bonding code doesn't allow for interfaces to be added + * or removed. + */ + if (net_l != net && net_l != NULL && use_tcp_bonding && + LNET_NETTYP(net_l->net_id) == SOCKLND) { + rc = -EINVAL; + goto failed0; + } + while (!list_empty(&net->net_ni_added)) { ni = list_entry(net->net_ni_added.next, struct lnet_ni, ni_netlist); @@ -1702,7 +1719,8 @@ LNetNIInit(lnet_pid_t requested_pid) * routes if it has been loaded */ if (!the_lnet.ln_nis_from_mod_params) { - rc = lnet_parse_networks(&net_head, lnet_get_networks()); + rc = lnet_parse_networks(&net_head, lnet_get_networks(), + use_tcp_bonding); if (rc < 0) goto err_empty_list; } @@ -2000,7 +2018,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; /* Create a net/ni structures for the network string */ - rc = lnet_parse_networks(&net_head, nets); + rc = lnet_parse_networks(&net_head, nets, use_tcp_bonding); if (rc <= 0) return !rc ? -EINVAL : rc; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 0571fa6a7249..abfc5d8dc219 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -117,6 +117,21 @@ lnet_ni_unique_net(struct list_head *nilist, char *iface) return true; } +/* check that the NI is unique to the interfaces with in the same NI. + * This is only a consideration if use_tcp_bonding is set */ +static bool +lnet_ni_unique_ni(char *iface_list[LNET_MAX_INTERFACES], char *iface) +{ + int i; + for (i = 0; i < LNET_MAX_INTERFACES; i++) { + if (iface_list[i] != NULL && + strncmp(iface_list[i], iface, strlen(iface)) == 0) + return false; + } + + return true; +} + static bool in_array(__u32 *array, __u32 size, __u32 value) { @@ -374,6 +389,9 @@ lnet_ni_add_interface(struct lnet_ni *ni, char *iface) if (ni == NULL) return -ENOMEM; + if (!lnet_ni_unique_ni(ni->ni_interfaces, iface)) + return -EINVAL; + /* Allocate a separate piece of memory and copy * into it the string, so we don't have * a depencency on the tokens string. This way we @@ -495,7 +513,8 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) * nilist. */ int -lnet_parse_networks(struct list_head *netlist, char *networks) +lnet_parse_networks(struct list_head *netlist, char *networks, + bool use_tcp_bonding) { struct cfs_expr_list *net_el = NULL; struct cfs_expr_list *ni_el = NULL; @@ -634,7 +653,8 @@ lnet_parse_networks(struct list_head *netlist, char *networks) if (IS_ERR_OR_NULL(net)) goto failed; - if (!nistr) { + if (!nistr || + (use_tcp_bonding && LNET_NETTYP(net_id) == SOCKLND)) { /* * No interface list was specified, allocate a * ni using the defaults. @@ -643,11 +663,13 @@ lnet_parse_networks(struct list_head *netlist, char *networks) if (IS_ERR_OR_NULL(ni)) goto failed; - if (net_el) { - cfs_expr_list_free(net_el); - net_el = NULL; + if (!nistr) { + if (net_el) { + cfs_expr_list_free(net_el); + net_el = NULL; + } + continue; } - continue; } do { @@ -704,17 +726,23 @@ lnet_parse_networks(struct list_head *netlist, char *networks) } /* - * At this point the name - is properly terminated. + * At this point the name is properly terminated. */ if (!*name) { str = name; goto failed_syntax; } - ni = lnet_ni_alloc(net, ni_el, name); - if (IS_ERR_OR_NULL(ni)) - goto failed; + if (use_tcp_bonding && + LNET_NETTYP(net->net_id) == SOCKLND) { + rc = lnet_ni_add_interface(ni, name); + if (rc != 0) + goto failed; + } else { + ni = lnet_ni_alloc(net, ni_el, name); + if (IS_ERR_OR_NULL(ni)) + goto failed; + } if (ni_el) { if (ni_el != net_el) { From neilb at suse.com Wed Sep 12 05:48:24 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 15:48:24 +1000 Subject: [lustre-devel] [PATCH 20/34] lnet: discard ni_cpt_list In-Reply-To: References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137203.8267.14277020278461943610.stgit@noble> Message-ID: <874levqn9z.fsf@notabene.neil.brown.name> On Wed, Sep 12 2018, Doug Oucharek wrote: > I'm assuming that a future patch will be chaining the NI structure on to the NET structure it belongs to. This patch is just not chaining the NIs on a global NIS list anymore. As such, ni_cptlist is being "repurposed". The NI is already chained onto the NET through lnet_net.net_ni_list and lnet_ni.ni_netlist ni_cptlist is not used even in current master. It is never added to any list, but lnet_ni_unlink_locked() does remove it from a list. Is that code wrong (should be checking ni_netlist), or is it cruft that should be removed? Thanks, NeilBrown > > Reviewed-by: Doug Oucharek > > Doug > > On 9/6/18, 5:54 PM, "NeilBrown" wrote: > > This isn't used any more. > The new comment is odd - this is no net_ni_cpt !! > The ni_cptlist linkage is no longer used - should it go too? > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 4 +--- > drivers/staging/lustre/lnet/lnet/api-ni.c | 7 ------- > 2 files changed, 1 insertion(+), 10 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 6c34ecf22021..dc15fa75a9d2 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -305,7 +305,7 @@ struct lnet_net { > struct lnet_ni { > /* chain on the lnet_net structure */ > struct list_head ni_netlist; > - /* chain on ln_nis_cpt */ > + /* chain on net_ni_cpt */ > struct list_head ni_cptlist; > > spinlock_t ni_lock; > @@ -671,8 +671,6 @@ struct lnet { > > /* LND instances */ > struct list_head ln_nets; > - /* NIs bond on specific CPT(s) */ > - struct list_head ln_nis_cpt; > /* the loopback NI */ > struct lnet_ni *ln_loni; > /* network zombie list */ > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 546d5101360f..960f235df5e7 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -538,7 +538,6 @@ lnet_prepare(lnet_pid_t requested_pid) > > INIT_LIST_HEAD(&the_lnet.ln_test_peers); > INIT_LIST_HEAD(&the_lnet.ln_nets); > - INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); > INIT_LIST_HEAD(&the_lnet.ln_routers); > INIT_LIST_HEAD(&the_lnet.ln_drop_rules); > INIT_LIST_HEAD(&the_lnet.ln_delay_rules); > @@ -616,7 +615,6 @@ lnet_unprepare(void) > LASSERT(!the_lnet.ln_refcount); > LASSERT(list_empty(&the_lnet.ln_test_peers)); > LASSERT(list_empty(&the_lnet.ln_nets)); > - LASSERT(list_empty(&the_lnet.ln_nis_cpt)); > > lnet_portals_destroy(); > > @@ -1294,11 +1292,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) > /* refcount for ln_nis */ > lnet_ni_addref_locked(ni, 0); > list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); > - if (ni->ni_cpts) { > - lnet_ni_addref_locked(ni, 0); > - list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); > - } > - > lnet_net_unlock(LNET_LOCK_EX); > > ni->ni_state = LNET_NI_STATE_ACTIVE; > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Wed Sep 12 05:54:41 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 12 Sep 2018 15:54:41 +1000 Subject: [lustre-devel] [PATCH 23/34] lnet: don't need lock to test ln_shutdown. In-Reply-To: <41CB4483-3CFE-4EC2-9980-CBCBE6B3FE88@cray.com> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137216.8267.15666994772553520296.stgit@noble> <41CB4483-3CFE-4EC2-9980-CBCBE6B3FE88@cray.com> Message-ID: <871s9zqmzi.fsf@notabene.neil.brown.name> On Wed, Sep 12 2018, Doug Oucharek wrote: > It seems the selection code being affected by this patch later gets moved to its own routine called lnet_select_pathway(). The logic is completely re-written so it may not be important to fix the use of locks here. However, it is not good that the lock is not being held while checking for shutdown. Thanks... I might drop the patch here, and probably fold it into which ever subsequent patch changes this code can gets rid of lnet_send(). I'll try that anyway. NeilBrown > > Reviewed-by: Doug Oucharek > > Doug > > On 9/6/18, 5:54 PM, "NeilBrown" wrote: > > ln_shutdown returns -ESHUTDOWN if ln_shutdown > is already set. > The lock is always taken to set ln_shutdown, but apparently > we don't need to hold the lock for this test. > I guess if it is set immediately after the test, and before > we take the lock then.... can anything bad happen? > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > drivers/staging/lustre/lnet/lnet/lib-move.c | 7 ++----- > 1 file changed, 2 insertions(+), 5 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index 60f34c4b85d3..46e593fbb44f 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -1099,12 +1099,9 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid, > local_ni); > again: > - lnet_net_lock(cpt); > - > - if (the_lnet.ln_shutdown) { > - lnet_net_unlock(cpt); > + if (the_lnet.ln_shutdown) > return -ESHUTDOWN; > - } > + lnet_net_lock(cpt); > > if (src_nid == LNET_NID_ANY) { > src_ni = NULL; > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From amir.shehata.whamcloud at gmail.com Wed Sep 12 16:29:20 2018 From: amir.shehata.whamcloud at gmail.com (Amir Shehata) Date: Wed, 12 Sep 2018 09:29:20 -0700 Subject: [lustre-devel] [PATCH 20/34] lnet: discard ni_cpt_list In-Reply-To: <153628137203.8267.14277020278461943610.stgit@noble> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137203.8267.14277020278461943610.stgit@noble> Message-ID: This area was re-implemented. There is no need for ni_cptlist any longer. I looked at the current code and it's not being used. Originally it was being used to place the the ni on a global list: ln_nis_cpt. Which was traversed when attempting to calculate the cpt for a NID using lnet_cpt_of_nid_locked(). However that latter function has been re-implemented due to how MR works now. So there is not need for ni_cptlist. On Thu, 6 Sep 2018 at 18:05, NeilBrown wrote: > This isn't used any more. > The new comment is odd - this is no net_ni_cpt !! > The ni_cptlist linkage is no longer used - should it go too? > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-types.h | 4 +--- > drivers/staging/lustre/lnet/lnet/api-ni.c | 7 ------- > 2 files changed, 1 insertion(+), 10 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h > b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 6c34ecf22021..dc15fa75a9d2 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -305,7 +305,7 @@ struct lnet_net { > struct lnet_ni { > /* chain on the lnet_net structure */ > struct list_head ni_netlist; > - /* chain on ln_nis_cpt */ > + /* chain on net_ni_cpt */ > struct list_head ni_cptlist; > > spinlock_t ni_lock; > @@ -671,8 +671,6 @@ struct lnet { > > /* LND instances */ > struct list_head ln_nets; > - /* NIs bond on specific CPT(s) */ > - struct list_head ln_nis_cpt; > /* the loopback NI */ > struct lnet_ni *ln_loni; > /* network zombie list */ > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c > b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 546d5101360f..960f235df5e7 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -538,7 +538,6 @@ lnet_prepare(lnet_pid_t requested_pid) > > INIT_LIST_HEAD(&the_lnet.ln_test_peers); > INIT_LIST_HEAD(&the_lnet.ln_nets); > - INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); > INIT_LIST_HEAD(&the_lnet.ln_routers); > INIT_LIST_HEAD(&the_lnet.ln_drop_rules); > INIT_LIST_HEAD(&the_lnet.ln_delay_rules); > @@ -616,7 +615,6 @@ lnet_unprepare(void) > LASSERT(!the_lnet.ln_refcount); > LASSERT(list_empty(&the_lnet.ln_test_peers)); > LASSERT(list_empty(&the_lnet.ln_nets)); > - LASSERT(list_empty(&the_lnet.ln_nis_cpt)); > > lnet_portals_destroy(); > > @@ -1294,11 +1292,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct > lnet_lnd_tunables *tun) > /* refcount for ln_nis */ > lnet_ni_addref_locked(ni, 0); > list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); > - if (ni->ni_cpts) { > - lnet_ni_addref_locked(ni, 0); > - list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); > - } > - > lnet_net_unlock(LNET_LOCK_EX); > > ni->ni_state = LNET_NI_STATE_ACTIVE; > > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org > -------------- next part -------------- An HTML attachment was scrubbed... URL: From green at whamcloud.com Thu Sep 13 04:54:14 2018 From: green at whamcloud.com (Oleg Drokin) Date: Thu, 13 Sep 2018 04:54:14 +0000 Subject: [lustre-devel] New tag 2.11.55 Message-ID: <7C1C845D-AF5A-4E46-84CD-AB88446BD229@whamcloud.com> Hello! I just tagged 2.11.55 in the Lustre community development branch. Here’s the changelog: Alex Zhuravlev (5): LU-11175 osc: serialize access to idle_timeout vs cleanup LU-8215 tests: sanity-benchmark/iozone should wait for space recovery LU-11096 osd: wrap new blk integrity stuff LU-10018 protocol: MDT as a statfs proxy LU-11282 osd-zfs: drop cache immediately Alexander Boyko (1): LU-11116 llog: error handling cleanup Amir Shehata (33): LU-9120 lnet: refactor lnet_select_pathway() LU-9120 lnet: add health value per ni LU-9120 lnet: add lnet_health_sensitivity LU-9120 lnet: add monitor thread LU-9120 lnet: handle local ni failure LU-9120 lnet: handle o2iblnd tx failure LU-9120 lnet: handle socklnd tx failure LU-9120 lnet: handle remote errors in LNet LU-9120 lnet: add retry count LU-9120 lnet: calculate the lnd timeout LU-9120 lnet: sysfs functions for module params LU-9120 lnet: timeout delayed REPLYs and ACKs LU-9120 lnet: remove duplicate timeout mechanism LU-9120 lnet: handle fatal device error LU-9120 lnet: reset health value LU-9120 lnet: add health statistics LU-9120 lnet: Add ioctl to get health stats LU-9120 lnet: remove obsolete health functions LU-9120 lnet: set retry count from lnetctl LU-9120 lnet: set transaction timeout from lnetctl LU-9120 lnet: set health sensitivity from lnetctl LU-9120 lnet: show local ni health stats LU-9120 lnet: show peer ni health stats LU-9120 lnet: set health value from user space LU-9120 lnet: add global health statistics LU-9120 lnet: print recovery queues content LU-9120 lnet: health error simulation LU-9120 lnet: LNet Health/Resiliency Feature LU-11271 lnd: conditionally set health status LU-11272 lnet: router handling LU-11273 lnet: update logging LU-11283 lnet: fix setting health value manually LU-11309 lnd: Clean up logging Andreas Dilger (6): LU-8066 lov: fix lov.*.stripeoffset printing LU-11040 utils: improve mount usage/man page LU-8066 tests: don't access /proc/sys/lnet/debug directly LU-10740 tests: disable tests for replay-dne-zfs-part-4 LU-11012 doc: improve the lfs-setstripe.1 man page LU-10447 build: fix checkpatch.pl to not mangle case Andriy Skulysh (1): LU-11135 mdt: LASSERT(lu_object_exists(o)) fails Ann Koehler (1): LU-11195 lod: Mark comps cached on replay of layout change Arshad Hussain (7): LU-6142 osd-ldiskfs: Fix style issues for osd_iam_lfix.c LU-6142 obdclass: Fix style issues for acl.c LU-6142 osd-ldiskfs: Fix style issues for osd_handler.c LU-6142 obdclass: Fix style issues for statfs_pack.c LU-6142 obdclass: Fix style issues for lustre_peer.c LU-6142 obdclass: Fix style issues for lustre_handles.c LU-6142 obdclass: Fix style issues for lu_ref.c Aya Mahfouz (1): LU-9855 include: replace OBD_CHECK_DEV by obd_check_dev Bobi Jam (5): LU-11226 flr: mirror resync regression LU-11238 lod: refine obj avoid collect for FLR LU-11212 lod: preserve mirror ID on mirror extension LU-8708 osc: enable/disable OSC grant shrink LU-11245 flr: lfs mirror dump command Chris Horn (1): LU-11240 gnilnd: Replace KGNILND_BUILD_REV Emoly Liu (1): LU-11110 ofd: remove obdfilter.*.* symlinks in few releases Hongchao Zhang (1): LU-11056 lwp: fix lwp reconnection issue James Nunez (1): LU-10686 tests: stop running sanity-pfl test 9 James Simmons (10): LU-9325 ptlrpc: replace simple_strtol with kstrtol LU-11224 obd: use correct ip_compute_csum() version LU-8066 lod: migrate from proc to sysfs LU-11200 libcfs: handle DECLARE_TIMER reduced to two arguments LU-8066 llite: move /proc/fs/lustre/llite/uuid to sysfs LU-10824 llite: don't use ll_mnt to get fstype name LU-10365 tests: set proper paths headers for sanity test 400a LU-9855 obdclass: simplify md_stats code LU-8130 libcfs: prepare rhashtable support LU-8066 llite: move /proc/fs/lustre/llite/checksum_pages to sysfs Jian Yu (1): LU-11255 kernel: kernel update [SLES12 SP3 4.4.143-94.47] Jinshan Xiong (1): LU-11244 build: apply IB_OPTIONS to debian rules John L. Hammond (5): LU-11014 mdc: remove obsolete intent opcodes LU-4256 test: add lustre-rsync-test 2b to ALWAYS_EXCEPT LU-10855 llog: use llog_common_cat_ops LU-11259 test: correct fail_loc names in replay-{single,dual} LU-11075 ldlm: correct logic in ldlm_prepare_lru_list() Lai Siyao (1): LU-11201 lfsck: check linkea entry validity Li Dongyang (2): LU-11215 tests: replace "large_xattr" with "ea_inode" LU-11328 ldlm: fix compile problem with --disable-lru-size Mikhail Pershin (5): LU-10509 mdd: don't set size attr for DOM file LU-11125 ofd: decrease message level LU-11275 llite: check truncate race for DOM pages LU-11270 mdt: better DOM data discard LU-10961 ldlm: don't cancel DoM locks before replay Mikhal Pershin (1): LU-11121 mdt: take discard lock at cleanup stage Minh Diep (1): LU-11266 build: update changelog for Ubuntu Nikitas Angelinas (1): LU-10818 obdecho: don't set ma_need in echo_attr_get_complex() Oleg Drokin (3): LU-9120 lnet: LNet Health/Resiliency Feature Revert "LU-11057 tests: exercise 'network' client mount option" New tag 2.11.55 Robin Humble (1): LU-11227 lod: lod_sync: don't attempt sync to inactive targets Sebastien Buisson (2): LU-11057 obd: check '-o network' and peer discovery conflict LU-11057 tests: exercise 'network' client mount option Sonia Sharma (2): LU-10654 lnet: lnetctl doesn't error out on mistyped options LU-11006 lnet: fix show peer yaml tree with no peer Wang Shilong (4): LU-11154 llite: use proper flags for FS_IOC_{FSSET,FSGET}XATTR LU-11146 lustre: fix setstripe for specific osts upon dir LU-11279 lod: reset ostlist properly in lod_get_default_lov_striping LU-11304 misc: update all url links to whamcloud Wei Liu (1): LU-11009 test: add version check to test_102 From amir.shehata.whamcloud at gmail.com Thu Sep 13 19:33:01 2018 From: amir.shehata.whamcloud at gmail.com (Amir Shehata) Date: Thu, 13 Sep 2018 12:33:01 -0700 Subject: [lustre-devel] [PATCH 20/34] lnet: discard ni_cpt_list In-Reply-To: <874levqn9z.fsf@notabene.neil.brown.name> References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137203.8267.14277020278461943610.stgit@noble> <874levqn9z.fsf@notabene.neil.brown.name> Message-ID: did you read my response to that question? Pasted below: --- This area was re-implemented. There is no need for ni_cptlist any longer. I looked at the current code and it's not being used. Originally it was being used to place the the ni on a global list: ln_nis_cpt. Which was traversed when attempting to calculate the cpt for a NID using lnet_cpt_of_nid_locked(). However that latter function has been re-implemented due to how MR works now. So there is not need for ni_cptlist. ___ thanks amir On Wed, 12 Sep 2018 at 17:35, NeilBrown wrote: > On Wed, Sep 12 2018, Doug Oucharek wrote: > > > I'm assuming that a future patch will be chaining the NI structure on to > the NET structure it belongs to. This patch is just not chaining the NIs > on a global NIS list anymore. As such, ni_cptlist is being "repurposed". > > The NI is already chained onto the NET through > lnet_net.net_ni_list and lnet_ni.ni_netlist > > ni_cptlist is not used even in current master. > It is never added to any list, but lnet_ni_unlink_locked() does remove > it from a list. Is that code wrong (should be checking ni_netlist), or > is it cruft that should be removed? > > Thanks, > NeilBrown > > > > > Reviewed-by: Doug Oucharek > > > > Doug > > > > On 9/6/18, 5:54 PM, "NeilBrown" wrote: > > > > This isn't used any more. > > The new comment is odd - this is no net_ni_cpt !! > > The ni_cptlist linkage is no longer used - should it go too? > > > > This is part of > > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > > LU-7734 lnet: Multi-Rail local NI split > > > > Signed-off-by: NeilBrown > > --- > > .../staging/lustre/include/linux/lnet/lib-types.h | 4 +--- > > drivers/staging/lustre/lnet/lnet/api-ni.c | 7 ------- > > 2 files changed, 1 insertion(+), 10 deletions(-) > > > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h > b/drivers/staging/lustre/include/linux/lnet/lib-types.h > > index 6c34ecf22021..dc15fa75a9d2 100644 > > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > > @@ -305,7 +305,7 @@ struct lnet_net { > > struct lnet_ni { > > /* chain on the lnet_net structure */ > > struct list_head ni_netlist; > > - /* chain on ln_nis_cpt */ > > + /* chain on net_ni_cpt */ > > struct list_head ni_cptlist; > > > > spinlock_t ni_lock; > > @@ -671,8 +671,6 @@ struct lnet { > > > > /* LND instances */ > > struct list_head ln_nets; > > - /* NIs bond on specific CPT(s) */ > > - struct list_head ln_nis_cpt; > > /* the loopback NI */ > > struct lnet_ni *ln_loni; > > /* network zombie list */ > > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c > b/drivers/staging/lustre/lnet/lnet/api-ni.c > > index 546d5101360f..960f235df5e7 100644 > > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > > @@ -538,7 +538,6 @@ lnet_prepare(lnet_pid_t requested_pid) > > > > INIT_LIST_HEAD(&the_lnet.ln_test_peers); > > INIT_LIST_HEAD(&the_lnet.ln_nets); > > - INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); > > INIT_LIST_HEAD(&the_lnet.ln_routers); > > INIT_LIST_HEAD(&the_lnet.ln_drop_rules); > > INIT_LIST_HEAD(&the_lnet.ln_delay_rules); > > @@ -616,7 +615,6 @@ lnet_unprepare(void) > > LASSERT(!the_lnet.ln_refcount); > > LASSERT(list_empty(&the_lnet.ln_test_peers)); > > LASSERT(list_empty(&the_lnet.ln_nets)); > > - LASSERT(list_empty(&the_lnet.ln_nis_cpt)); > > > > lnet_portals_destroy(); > > > > @@ -1294,11 +1292,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct > lnet_lnd_tunables *tun) > > /* refcount for ln_nis */ > > lnet_ni_addref_locked(ni, 0); > > list_add_tail(&ni->ni_net->net_list, &the_lnet.ln_nets); > > - if (ni->ni_cpts) { > > - lnet_ni_addref_locked(ni, 0); > > - list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); > > - } > > - > > lnet_net_unlock(LNET_LOCK_EX); > > > > ni->ni_state = LNET_NI_STATE_ACTIVE; > > > > > > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Mon Sep 17 17:30:10 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:10 -0400 Subject: [lustre-devel] [PATCH 00/30] lustre: first batch of fixes from lustre 2.10 Message-ID: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> First collection of patches to address various cleanups and bugs in the lustre 2.10 release that are missing for the lustre linux client. These patches can be applied in any order. Alexander Boyko (2): lustre: osc: fix for cl_env_get in low memory lustre: ptlrpc: fix wrong error handlers Alexandr Boyko (1): lustre: osc: adds radix_tree_preload Andreas Dilger (2): lustre: llog: update llog print format to use FIDs lustre: mdc: allow setting readdir RPC size parameter Andrew Perepechko (1): lustre: llite: llite.stat_blocksize param for fixed st_blksize Andriy Skulysh (3): lustre: osc: GPF while doing ELC with no_wait_policy lustre: ldlm: GPF in _ldlm_lock_debug() lustre: llite: protect ll_dentry_data modification Bobi Jam (2): lustre: osc: osc page lru list race lustre: llite: check the return value of cl_file_inode_init() Bruno Faccini (1): lustre: ptlrpc: drain "ptlrpc_request_buffer_desc" objects Doug Oucharek (1): lustre: lnet: Change sock_create() to sock_create_kern() Fan Yong (1): lustre: ptlrpc: free reply buffer earlier for open RPC James Simmons (2): lustre: lnd: resolve IP query code in LND drivers lustre: clio: fix spare bit handling John L. Hammond (3): lustre: ptlrpc: set rq_sent when send fails due to -ENOMEM lustre: kuc: initialize kkuc_groups at module init time lustre: ldlm: use static initializer macros where possible Niu Yawei (3): lustre: uapi: add documentation about FIDs lustre: osc: update timestamps on write only lustre: ptlrpc: add replay request into unreplied list Patrick Farrell (1): lustre: ldlm: cond_resched in ldlm_bl_thread_main Sebastien Buisson (1): lustre: llite: set sec ctx on client's inode at create time Steve Guminski (3): lustre: ptlrpc: Prevent possible dereference of NULL pointers lustre: mgc: Remove unnecessary checks for config_log_put() lustre: llite: rcu-walk check should not depend on statahead Vitaly Fertman (1): lustre: ptlrpc: increase sleep time in ptlrpc_request_bufs_pack() Wang Shilong (1): lustre: obd: remove obsolete OBD_FL_LOCAL_MASK Yang Sheng (1): lustre: libcfs: use save_stack_trace for stack dump .../lustre/include/linux/libcfs/libcfs_debug.h | 1 + .../lustre/include/uapi/linux/lustre/lustre_idl.h | 88 +++++++++++++++++++++- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 12 ++- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- drivers/staging/lustre/lnet/libcfs/debug.c | 46 ++++++++++- drivers/staging/lustre/lnet/lnet/lib-socket.c | 2 +- .../staging/lustre/lustre/include/lprocfs_status.h | 5 ++ drivers/staging/lustre/lustre/include/lustre_dlm.h | 4 +- .../lustre/lustre/include/lustre_kernelcomm.h | 1 + drivers/staging/lustre/lustre/include/lustre_net.h | 14 ++-- drivers/staging/lustre/lustre/include/obd.h | 5 +- drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 13 +++- drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c | 12 +-- drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 6 +- drivers/staging/lustre/lustre/llite/dcache.c | 7 +- drivers/staging/lustre/lustre/llite/dir.c | 22 +++--- drivers/staging/lustre/lustre/llite/file.c | 2 +- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 19 ++--- .../staging/lustre/lustre/llite/llite_internal.h | 8 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 24 +++--- drivers/staging/lustre/lustre/llite/llite_nfs.c | 4 +- drivers/staging/lustre/lustre/llite/lproc_llite.c | 33 ++++++++ drivers/staging/lustre/lustre/llite/namei.c | 59 ++++++++++++--- drivers/staging/lustre/lustre/llite/statahead.c | 4 - drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 20 +---- drivers/staging/lustre/lustre/mdc/mdc_request.c | 35 ++++++--- drivers/staging/lustre/lustre/mgc/mgc_request.c | 36 ++++----- drivers/staging/lustre/lustre/obdclass/class_obd.c | 3 + .../staging/lustre/lustre/obdclass/kernelcomm.c | 38 +++++++--- drivers/staging/lustre/lustre/obdclass/llog_cat.c | 28 +++---- drivers/staging/lustre/lustre/obdclass/llog_swab.c | 4 +- .../lustre/lustre/obdclass/lprocfs_status.c | 54 +++++++++++++ drivers/staging/lustre/lustre/obdclass/obdo.c | 11 --- drivers/staging/lustre/lustre/osc/lproc_osc.c | 46 ----------- drivers/staging/lustre/lustre/osc/osc_cache.c | 3 + drivers/staging/lustre/lustre/osc/osc_io.c | 2 +- drivers/staging/lustre/lustre/osc/osc_lock.c | 13 +++- drivers/staging/lustre/lustre/osc/osc_object.c | 2 +- drivers/staging/lustre/lustre/osc/osc_page.c | 43 ++++++----- drivers/staging/lustre/lustre/osc/osc_request.c | 7 +- drivers/staging/lustre/lustre/ptlrpc/client.c | 67 +++++++++++----- drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 20 ++--- .../staging/lustre/lustre/ptlrpc/pack_generic.c | 26 +++++-- .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h | 1 + drivers/staging/lustre/lustre/ptlrpc/recover.c | 12 +-- drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 2 +- drivers/staging/lustre/lustre/ptlrpc/service.c | 14 +++- drivers/staging/lustre/lustre/ptlrpc/wiretest.c | 1 - 48 files changed, 585 insertions(+), 296 deletions(-) -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:11 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:11 -0400 Subject: [lustre-devel] [PATCH 01/30] lustre: lnd: resolve IP query code in LND drivers In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-2-git-send-email-jsimmons@infradead.org> The recent IP querying code that landed to both ksocklnd and ko2iblnd have some bugs that prevent proper setup. The first bug in both drivers is that the IP address of ifa_local is in big endian format so on little endian systems the IP address is incorrect. Calling ntohl() on ifa_local gets the real IP address. The second bug located in ko2iblnd is that in_dev is always NULL. Add the call __in_dev_get_rtnl() to get in_dev and use that information to query the IP address. Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 12 +++++++++--- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 15953e4..6874e53 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2468,8 +2468,7 @@ static struct kib_dev *kiblnd_create_dev(char *ifname) flags = dev_get_flags(netdev); if (!(flags & IFF_UP)) { CERROR("Can't query IPoIB interface %s: it's down\n", ifname); - rtnl_unlock(); - return NULL; + goto unlock; } dev = kzalloc(sizeof(*dev), GFP_NOFS); @@ -2481,9 +2480,16 @@ static struct kib_dev *kiblnd_create_dev(char *ifname) INIT_LIST_HEAD(&dev->ibd_nets); INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */ INIT_LIST_HEAD(&dev->ibd_fail_list); + + in_dev = __in_dev_get_rtnl(netdev); + if (!in_dev) { + kfree(dev); + goto unlock; + } + for_primary_ifa(in_dev) if (strcmp(ifa->ifa_label, ifname) == 0) { - dev->ibd_ifip = ifa->ifa_local; + dev->ibd_ifip = ntohl(ifa->ifa_local); break; } endfor_ifa(in_dev); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 5b81040..750a7ce 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2589,7 +2589,7 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) } for_primary_ifa(in_dev) if (strcmp(ifa->ifa_label, name) == 0) { - ksi->ksni_ipaddr = ifa->ifa_local; + ksi->ksni_ipaddr = ntohl(ifa->ifa_local); ksi->ksni_netmask = ifa->ifa_mask; strlcpy(ksi->ksni_name, name, sizeof(ksi->ksni_name)); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:12 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:12 -0400 Subject: [lustre-devel] [PATCH 02/30] lustre: uapi: add documentation about FIDs In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-3-git-send-email-jsimmons@infradead.org> From: Niu Yawei Add details about FIDs in lustre. FIDs are exposed to user land so users can manage them. This provides the users details to assist them. Signed-off-by: Niu Yawei WC-bug-id: https://jira.whamcloud.com/browse/LU-8998 Reviewed-on: https://review.whamcloud.com/24867 Reviewed-by: Andreas Dilger Reviewed-by: Jinshan Xiong Signed-off-by: James Simmons --- .../lustre/include/uapi/linux/lustre/lustre_idl.h | 84 ++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h index bec1028..58321eb 100644 --- a/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -223,6 +223,90 @@ enum { #define LL_HSM_MAX_ARCHIVE (sizeof(__u32) * 8) /** + * Different FID Format + * http://arch.lustre.org/index.php?title=Interoperability_fids_zfs#NEW.0 + * + * FID: + * File IDentifier generated by client from range allocated by the seq service. + * First 0x400 sequences [2^33, 2^33 + 0x400] are reserved for system use. Note + * that on ldiskfs MDTs that IGIF FIDs can use inode numbers starting at 12, + * but this is in the IGIF SEQ rangeand does not conflict with assigned FIDs. + * + * IGIF: + * Inode and Generation In FID, a surrogate FID used to globally identify an + * existing object on OLD formatted MDT file system. This would only be used on + * MDT0 in a DNE filesystem, because there are not expected to be any OLD + * formatted DNE filesystems. Belongs to a sequence in [12, 2^32 - 1] range, + * where sequence number is inode number, and inode generation is used as OID. + * NOTE: This assumes no more than 2^32-1 inodes exist in the MDT filesystem, + * which is the maximum possible for an ldiskfs backend. NOTE: This assumes + * that the reserved ext3/ext4/ldiskfs inode numbers [0-11] are never visible + * to clients, which has always been true. + * + * IDIF: + * Object ID in FID, a surrogate FID used to globally identify an existing + * object on OLD formatted OST file system. Belongs to a sequence in + * [2^32, 2^33 - 1]. Sequence number is calculated as: + * 1 << 32 | (ost_index << 16) | ((objid >> 32) & 0xffff) + * that is, SEQ consists of 16-bit OST index, and higher 16 bits of object ID. + * The generation of unique SEQ values per OST allows the IDIF FIDs to be + * identified in the FLD correctly. The OID field is calculated as: + * objid & 0xffffffff + * that is, it consists of lower 32 bits of object ID. NOTE This assumes that + * no more than 2^48-1 objects have ever been created on an OST, and that no + * more than 65535 OSTs are in use. Both are very reasonable assumptions (can + * uniquely map all objects on an OST that created 1M objects per second for 9 + * years, or combinations thereof). + * + * OST_MDT0: + * Surrogate FID used to identify an existing object on OLD formatted OST + * filesystem. Belongs to the reserved sequence 0, and is used internally prior + * to the introduction of FID-on-OST, at which point IDIF will be used to + * identify objects as residing on a specific OST. + * + * LLOG: + * For Lustre Log objects the object sequence 1 is used. This is compatible with + * both OLD and NEW.1 namespaces, as this SEQ number is in the ext3/ldiskfs + * reserved inode range and does not conflict with IGIF sequence numbers. + * + * ECHO: + * For testing OST IO performance the object sequence 2 is used. This is + * compatible with both OLD and NEW.1 namespaces, as this SEQ number is in the + * ext3/ldiskfs reserved inode range and does not conflict with IGIF sequence + * numbers. + * + * OST_MDT1 .. OST_MAX: + * For testing with multiple MDTs the object sequence 3 through 9 is used, + * allowing direct mapping of MDTs 1 through 7 respectively, for a total of 8 + * MDTs including OST_MDT0. This matches the legacy CMD project "group" + * mappings. However, this SEQ range is only for testing prior to any production + * DNE release, as the objects in this range conflict across all OSTs, as the + * OST index is not part of the FID. + * + * + * For compatibility with existing OLD OST network protocol structures, the FID + * must map onto the o_id and o_gr in a manner that ensures existing objects are + * identified consistently for IO, as well as onto the lock namespace to ensure + * both IDIFs map onto the same objects for IO as well as resources in the DLM. + * + * DLM OLD OBIF/IDIF: + * resource[] = {o_id, o_seq, 0, 0}; // o_seq == 0 for production releases + * + * DLM NEW.1 FID (this is the same for both the MDT and OST): + * resource[] = {SEQ, OID, VER, HASH}; + * + * Note that for mapping IDIF values to DLM resource names the o_id may be + * larger than the 2^33 reserved sequence numbers for IDIF, so it is possible + * for the o_id numbers to overlap FID SEQ numbers in the resource. However, in + * all production releases the OLD o_seq field is always zero, and all valid FID + * OID values are non-zero, so the lock resources will not collide. + * + * For objects within the IDIF range, group extraction (non-CMD) will be: + * o_id = (fid->f_seq & 0x7fff) << 16 | fid->f_oid; + * o_seq = 0; // formerly group number + */ + +/** * Note that reserved SEQ numbers below 12 will conflict with ldiskfs * inodes in the IGIF namespace, so these reserved SEQ numbers can be * used for other purposes and not risk collisions with existing inodes. -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:15 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:15 -0400 Subject: [lustre-devel] [PATCH 05/30] lustre: osc: GPF while doing ELC with no_wait_policy In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-6-git-send-email-jsimmons@infradead.org> From: Andriy Skulysh osc_ldlm_weigh_ast() uses osc_object from ldlm_lock without taking a reference. It should take a reference like osc_ldlm_glimpse_ast()/ osc_dlm_blocking_ast0() does. Signed-off-by: Andriy Skulysh WC-bug-id: https://jira.whamcloud.com/browse/LU-9171 Seagate-bug-id: MRP-4179 Reviewed-on: https://review.whamcloud.com/25700 Reviewed-by: Jinshan Xiong Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/osc/osc_lock.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index d6a275f..6059dba 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -701,7 +701,12 @@ unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock) return 1; LASSERT(dlmlock->l_resource->lr_type == LDLM_EXTENT); + lock_res_and_lock(dlmlock); obj = dlmlock->l_ast_data; + if (obj) + cl_object_get(osc2cl(obj)); + unlock_res_and_lock(dlmlock); + if (!obj) { weight = 1; goto out; @@ -725,6 +730,9 @@ unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock) weight = osc_lock_weight(env, obj, &dlmlock->l_policy_data.l_extent); out: + if (obj) + cl_object_put(env, osc2cl(obj)); + cl_env_put(env, &refcheck); return weight; } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:25 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:25 -0400 Subject: [lustre-devel] [PATCH 15/30] lustre: ptlrpc: drain "ptlrpc_request_buffer_desc" objects In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-16-git-send-email-jsimmons@infradead.org> From: Bruno Faccini Prior to this patch, new "ptlrpc_request_buffer_desc" could be additionally allocated upon need by ptlrpc_check_rqbd_pool(), but will never be freed until OST umount/stop by ptlrpc_service_purge_all(). Now try to release some of them when possible. Signed-off-by: Bruno Faccini WC-bug-id: https://jira.whamcloud.com/browse/LU-9372 Reviewed-on: https://review.whamcloud.com/26752 Reviewed-by: Niu Yawei Reviewed-by: Henri Doreau Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/ptlrpc/service.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 79baadc..6a5a9c5 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -802,11 +802,21 @@ static void ptlrpc_server_drop_request(struct ptlrpc_request *req) spin_lock(&svcpt->scp_lock); /* * now all reqs including the embedded req has been - * disposed, schedule request buffer for re-use. + * disposed, schedule request buffer for re-use + * or free it to drain some in excess. */ LASSERT(atomic_read(&rqbd->rqbd_req.rq_refcount) == 0); - list_add_tail(&rqbd->rqbd_list, &svcpt->scp_rqbd_idle); + if (svcpt->scp_nrqbds_posted >= svc->srv_nbuf_per_group && + !test_req_buffer_pressure) { + /* like in ptlrpc_free_rqbd() */ + svcpt->scp_nrqbds_total--; + kvfree(rqbd->rqbd_buffer); + kfree(rqbd); + } else { + list_add_tail(&rqbd->rqbd_list, + &svcpt->scp_rqbd_idle); + } } spin_unlock(&svcpt->scp_lock); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:14 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:14 -0400 Subject: [lustre-devel] [PATCH 04/30] lustre: ptlrpc: fix wrong error handlers In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-5-git-send-email-jsimmons@infradead.org> From: Alexander Boyko If ptlrpc_request_pack finish with 0, we need to call ptlrpc_req_finished for later errors. Signed-off-by: Alexander Boyko WC-bug-id: https://jira.whamcloud.com/browse/LU-9286 Seagate-bug-id: MRP-4285 Reviewed-on: https://review.whamcloud.com/26319 Reviewed-by: Chris Horn Reviewed-by: Mike Pershin Reviewed-by: Niu Yawei Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/mdc/mdc_request.c | 2 +- drivers/staging/lustre/lustre/osc/osc_request.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index f3c0722..116e973 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -904,7 +904,7 @@ static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid, MDS_BULK_PORTAL, &ptlrpc_bulk_kiov_pin_ops); if (!desc) { - ptlrpc_request_free(req); + ptlrpc_req_finished(req); return -ENOMEM; } diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 7c91c4b..8024b17 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -655,7 +655,7 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp, rc = l_wait_event_abortable_exclusive(cli->cl_destroy_waitq, osc_can_send_destroy(cli)); if (rc) { - ptlrpc_request_free(req); + ptlrpc_req_finished(req); return rc; } } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:18 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:18 -0400 Subject: [lustre-devel] [PATCH 08/30] lustre: mgc: Remove unnecessary checks for config_log_put() In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-9-git-send-email-jsimmons@infradead.org> From: Steve Guminski Make config_log_put() check if its parameter is NULL, which makes it is unnecessary to perform the check prior to calling it. This patch removes the redundant checks. Signed-off-by: Steve Guminski WC-bug-id: https://jira.whamcloud.com/browse/LU-9152 Reviewed-on: https://review.whamcloud.com/25854 Reviewed-by: Bob Glossman Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/mgc/mgc_request.c | 36 +++++++++++-------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index 4552cc5..e6f8d9e 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -131,6 +131,9 @@ static int config_log_get(struct config_llog_data *cld) */ static void config_log_put(struct config_llog_data *cld) { + if (unlikely(!cld)) + return; + CDEBUG(D_INFO, "log %s refs %d\n", cld->cld_logname, atomic_read(&cld->cld_refcount)); LASSERT(atomic_read(&cld->cld_refcount) > 0); @@ -142,12 +145,9 @@ static void config_log_put(struct config_llog_data *cld) CDEBUG(D_MGC, "dropping config log %s\n", cld->cld_logname); - if (cld->cld_recover) - config_log_put(cld->cld_recover); - if (cld->cld_params) - config_log_put(cld->cld_params); - if (cld->cld_sptlrpc) - config_log_put(cld->cld_sptlrpc); + config_log_put(cld->cld_recover); + config_log_put(cld->cld_params); + config_log_put(cld->cld_sptlrpc); if (cld_is_sptlrpc(cld)) sptlrpc_conf_log_stop(cld->cld_logname); @@ -387,6 +387,9 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, static inline void config_mark_cld_stop(struct config_llog_data *cld) { + if (!cld) + return; + mutex_lock(&cld->cld_lock); spin_lock(&config_list_lock); cld->cld_stopping = 1; @@ -436,18 +439,13 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg) cld->cld_sptlrpc = NULL; mutex_unlock(&cld->cld_lock); - if (cld_recover) { - config_mark_cld_stop(cld_recover); - config_log_put(cld_recover); - } + config_mark_cld_stop(cld_recover); + config_log_put(cld_recover); - if (cld_params) { - config_mark_cld_stop(cld_params); - config_log_put(cld_params); - } + config_mark_cld_stop(cld_params); + config_log_put(cld_params); - if (cld_sptlrpc) - config_log_put(cld_sptlrpc); + config_log_put(cld_sptlrpc); /* drop the ref from the find */ config_log_put(cld); @@ -593,8 +591,7 @@ static int mgc_requeue_thread(void *data) cld->cld_lostlock = 0; spin_unlock(&config_list_lock); - if (cld_prev) - config_log_put(cld_prev); + config_log_put(cld_prev); cld_prev = cld; if (likely(!(rq_state & RQ_STOP))) { @@ -606,8 +603,7 @@ static int mgc_requeue_thread(void *data) } } spin_unlock(&config_list_lock); - if (cld_prev) - config_log_put(cld_prev); + config_log_put(cld_prev); /* Wait a bit to see if anyone else needs a requeue */ wait_event_idle(rq_waitq, rq_state & (RQ_NOW | RQ_STOP)); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:27 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:27 -0400 Subject: [lustre-devel] [PATCH 17/30] lustre: llite: protect ll_dentry_data modification In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-18-git-send-email-jsimmons@infradead.org> From: Andriy Skulysh The ll_dentry_data bitfields modification should be protected by a spinlock. Signed-off-by: Andriy Skulysh Signed-off-by: Lai Siyao WC-bug-id: https://jira.whamcloud.com/browse/LU-9241 Seagate-bug-id: MRP-4257 Reviewed-on: https://review.whamcloud.com/26109 Reviewed-by: Niu Yawei Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/llite/llite_nfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c index c66072a..5e91e83 100644 --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c @@ -171,8 +171,9 @@ struct lustre_nfs_fid { * we came from NFS and so opencache needs to be * enabled for this one */ + spin_lock(&result->d_lock); ll_d2d(result)->lld_nfs_dentry = 1; - + spin_unlock(&result->d_lock); return result; } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:28 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:28 -0400 Subject: [lustre-devel] [PATCH 18/30] lustre: llite: llite.stat_blocksize param for fixed st_blksize In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-19-git-send-email-jsimmons@infradead.org> From: Andrew Perepechko llite.stat_blocksize is added to allow configurable st_blksize for stat(2). The latter is treated incorrectly by some applications. For example, glibc pre-2.25 uses this value for stdio buffering which completely ruins performance with random reads. The patch changes the behaviour of getattr rather than inode initialization so that change of the setting causes immediate effect without the need of reclaiming existing inodes. The patch is similar to the patch from bz # 12739 by Aurelien Degremont. Signed-off-by: Andrew Perepechko WC-bug-id: https://jira.whamcloud.com/browse/LU-9413 Reviewed-on: https://review.whamcloud.com/26869 Reviewed-by: Alexander Zarochentsev Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/llite/file.c | 2 +- .../staging/lustre/lustre/llite/llite_internal.h | 6 +++- drivers/staging/lustre/lustre/llite/lproc_llite.c | 33 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index b90c59c..94760eb 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -3267,7 +3267,7 @@ int ll_getattr(const struct path *path, struct kstat *stat, stat->atime = inode->i_atime; stat->mtime = inode->i_mtime; stat->ctime = inode->i_ctime; - stat->blksize = 1 << inode->i_blkbits; + stat->blksize = sbi->ll_stat_blksize ?: BIT(inode->i_blkbits); stat->nlink = inode->i_nlink; stat->size = i_size_read(inode); diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 9d9f623..dcb2fed 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -523,7 +523,11 @@ struct ll_sb_info { struct root_squash_info ll_squash; struct path ll_mnt; - __kernel_fsid_t ll_fsid; + /* st_blksize returned by stat(2), when non-zero */ + unsigned int ll_stat_blksize; + + __kernel_fsid_t ll_fsid; + struct kset ll_kset; /* sysfs object */ struct completion ll_kobj_unregister; }; diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c index f775b4f..d8ef090 100644 --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c @@ -128,6 +128,38 @@ static ssize_t blocksize_show(struct kobject *kobj, struct attribute *attr, } LUSTRE_RO_ATTR(blocksize); +static ssize_t stat_blocksize_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kset.kobj); + + return sprintf(buf, "%u\n", sbi->ll_stat_blksize); +} + +static ssize_t stat_blocksize_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, + size_t count) +{ + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, + ll_kset.kobj); + unsigned int val; + int rc; + + rc = kstrtouint(buffer, 10, &val); + if (rc) + return rc; + + if (val != 0 && (val < PAGE_SIZE || (val & (val - 1))) != 0) + return -ERANGE; + + sbi->ll_stat_blksize = val; + + return count; +} +LUSTRE_RW_ATTR(stat_blocksize); + static ssize_t kbytestotal_show(struct kobject *kobj, struct attribute *attr, char *buf) { @@ -1123,6 +1155,7 @@ static ssize_t ll_nosquash_nids_seq_write(struct file *file, static struct attribute *llite_attrs[] = { &lustre_attr_blocksize.attr, + &lustre_attr_stat_blocksize.attr, &lustre_attr_kbytestotal.attr, &lustre_attr_kbytesfree.attr, &lustre_attr_kbytesavail.attr, -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:23 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:23 -0400 Subject: [lustre-devel] [PATCH 13/30] lustre: ldlm: GPF in _ldlm_lock_debug() In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-14-git-send-email-jsimmons@infradead.org> From: Andriy Skulysh Lock's resource can change on a client. Take a resource reference under spinlock to print debug information. Signed-off-by: Andriy Skulysh WC-bug-id: https://jira.whamcloud.com/browse/LU-7062 Xyratex-bug-id: MRP-2760 Reviewed-on: https://review.whamcloud.com/16139 Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/lustre_dlm.h | 1 + drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 11 +++++++++-- drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index 2a05ab8..a68c7a4 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -1186,6 +1186,7 @@ struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent, const struct ldlm_res_id *, enum ldlm_type type, int create); +struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res); void ldlm_resource_putref(struct ldlm_resource *res); void ldlm_resource_add_lock(struct ldlm_resource *res, struct list_head *head, diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 2fb2e08..3cbdc81 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -1981,10 +1981,16 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, struct libcfs_debug_msg_data *msgdata, const char *fmt, ...) { - va_list args; struct obd_export *exp = lock->l_export; - struct ldlm_resource *resource = lock->l_resource; + struct ldlm_resource *resource = NULL; char *nid = "local"; + va_list args; + + if (spin_trylock(&lock->l_lock)) { + if (lock->l_resource) + resource = ldlm_resource_getref(lock->l_resource); + spin_unlock(&lock->l_lock); + } va_start(args, fmt); @@ -2099,5 +2105,6 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, break; } va_end(args); + ldlm_resource_putref(resource); } EXPORT_SYMBOL(_ldlm_lock_debug); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index 33d73fa..1907a5a 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -402,7 +402,7 @@ static int ldlm_namespace_debugfs_register(struct ldlm_namespace *ns) #undef MAX_STRING_SIZE -static struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res) +struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res) { LASSERT(res); LASSERT(res != LP_POISON); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:33 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:33 -0400 Subject: [lustre-devel] [PATCH 23/30] lustre: osc: adds radix_tree_preload In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-24-git-send-email-jsimmons@infradead.org> From: Alexandr Boyko The client fail with next error osc_page_init()) ASSERTION( result == 0 ) in low memory conditions. The patch fixes the problem above by adding radix_tree_preload. Signed-off-by: Alexandr Boyko WC-bug-id: https://jira.whamcloud.com/browse/LU-9579 Seagate-bug-id: MRP-4424 Reviewed-on: https://review.whamcloud.com/27372 Reviewed-by: Jinshan Xiong Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/osc/osc_page.c | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 189e3e78..ada1eda 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -256,32 +256,37 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj, { struct osc_object *osc = cl2osc(obj); struct osc_page *opg = cl_object_page_slice(obj, page); + struct osc_io *oio = osc_env_io(env); int result; opg->ops_from = 0; opg->ops_to = PAGE_SIZE; + INIT_LIST_HEAD(&opg->ops_lru); result = osc_prep_async_page(osc, opg, page->cp_vmpage, cl_offset(obj, index)); - if (result == 0) { - struct osc_io *oio = osc_env_io(env); + if (result != 0) + return result; - opg->ops_srvlock = osc_io_srvlock(oio); - cl_page_slice_add(page, &opg->ops_cl, obj, index, - &osc_page_ops); - } - INIT_LIST_HEAD(&opg->ops_lru); + opg->ops_srvlock = osc_io_srvlock(oio); + cl_page_slice_add(page, &opg->ops_cl, obj, index, + &osc_page_ops); /* reserve an LRU space for this page */ - if (page->cp_type == CPT_CACHEABLE && result == 0) { + if (page->cp_type == CPT_CACHEABLE) { result = osc_lru_alloc(env, osc_cli(osc), opg); if (result == 0) { - spin_lock(&osc->oo_tree_lock); - result = radix_tree_insert(&osc->oo_tree, index, opg); - if (result == 0) - ++osc->oo_npages; - spin_unlock(&osc->oo_tree_lock); - LASSERT(result == 0); + result = radix_tree_preload(GFP_KERNEL); + if (result == 0) { + spin_lock(&osc->oo_tree_lock); + result = radix_tree_insert(&osc->oo_tree, + index, opg); + if (result == 0) + ++osc->oo_npages; + spin_unlock(&osc->oo_tree_lock); + + radix_tree_preload_end(); + } } } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:40 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:40 -0400 Subject: [lustre-devel] [PATCH 30/30] lustre: clio: fix spare bit handling In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-31-git-send-email-jsimmons@infradead.org> Expanded testing of the earlier patch that changed lustre so not to use the spare bits in iattr.ia_valid exposed a bug with HSM. The bugs was that ll_setattr_raw() was ignoring the changes to ctime. Signed-off-by: James Simmons WC-bug-id: https://jira.whamcloud.com/browse/LU-10030 Reviewed-on: https://review.whamcloud.com/32825 Reviewed-by: Andreas Dilger Reviewed-by: Bobi Jam Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/llite/llite_lib.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 99d0b72..3de6e886 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1529,7 +1529,8 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, } /* We mark all of the fields "set" so MDS/OST does not re-set them */ - if (attr->ia_valid & ATTR_CTIME) { + if (!(xvalid & OP_ATTR_CTIME_SET) && + attr->ia_valid & ATTR_CTIME) { attr->ia_ctime = current_time(inode); xvalid |= OP_ATTR_CTIME_SET; } @@ -1584,9 +1585,9 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, goto out; } - if (attr->ia_valid & (ATTR_SIZE | - ATTR_ATIME | ATTR_ATIME_SET | - ATTR_MTIME | ATTR_MTIME_SET)) { + if (attr->ia_valid & (ATTR_SIZE | ATTR_ATIME | ATTR_ATIME_SET | + ATTR_MTIME | ATTR_MTIME_SET | ATTR_CTIME) || + xvalid & OP_ATTR_CTIME_SET) { /* For truncate and utimes sending attributes to OSTs, setting * mtime/atime to the past will be performed under PW [0:EOF] * extent lock (new_size:EOF for truncate). It may seem -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:22 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:22 -0400 Subject: [lustre-devel] [PATCH 12/30] lustre: kuc: initialize kkuc_groups at module init time In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-13-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" Some kkuc functions use kkuc_groups[group].next == NULL to test for an empty group list. This is incorrect if the group was previously added to but not empty. Remove all next == NULL tests and use module load time initialization of the kkuc_groups array. Signed-off-by: John L. Hammond WC-bug-id: https://jira.whamcloud.com/browse/LU-9306 Reviewed-on: https://review.whamcloud.com/26883 Reviewed-by: Frank Zago Reviewed-by: Faccini Bruno Reviewed-by: Henri Doreau Reviewed-by: Quentin Bouget Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../lustre/lustre/include/lustre_kernelcomm.h | 1 + drivers/staging/lustre/lustre/obdclass/class_obd.c | 3 ++ .../staging/lustre/lustre/obdclass/kernelcomm.c | 38 +++++++++++++++------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h b/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h index 2b3fa84..8e3a990 100644 --- a/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h +++ b/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h @@ -45,6 +45,7 @@ typedef int (*libcfs_kkuc_cb_t)(void *data, void *cb_arg); /* Kernel methods */ +void libcfs_kkuc_init(void); int libcfs_kkuc_msg_put(struct file *fp, void *payload); int libcfs_kkuc_group_put(unsigned int group, void *payload); int libcfs_kkuc_group_add(struct file *fp, int uid, unsigned int group, diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index eabaafe..2d23608 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -664,6 +665,8 @@ static int __init obdclass_init(void) if (err) return err; + libcfs_kkuc_init(); + err = obd_zombie_impexp_init(); if (err) return err; diff --git a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c index 304288d..0fcfecf 100644 --- a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c +++ b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c @@ -96,10 +96,23 @@ struct kkuc_reg { char kr_data[0]; }; -static struct list_head kkuc_groups[KUC_GRP_MAX + 1] = {}; +static struct list_head kkuc_groups[KUC_GRP_MAX + 1]; /* Protect message sending against remove and adds */ static DECLARE_RWSEM(kg_sem); +static inline bool libcfs_kkuc_group_is_valid(int group) +{ + return 0 <= group && group < ARRAY_SIZE(kkuc_groups); +} + +void libcfs_kkuc_init(void) +{ + int group; + + for (group = 0; group < ARRAY_SIZE(kkuc_groups); group++) + INIT_LIST_HEAD(&kkuc_groups[group]); +} + /** Add a receiver to a broadcast group * @param filp pipe to write into * @param uid identifier for this receiver @@ -111,7 +124,7 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, unsigned int group, { struct kkuc_reg *reg; - if (group > KUC_GRP_MAX) { + if (!libcfs_kkuc_group_is_valid(group)) { CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); return -EINVAL; } @@ -130,8 +143,6 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, unsigned int group, memcpy(reg->kr_data, data, data_len); down_write(&kg_sem); - if (!kkuc_groups[group].next) - INIT_LIST_HEAD(&kkuc_groups[group]); list_add(®->kr_chain, &kkuc_groups[group]); up_write(&kg_sem); @@ -145,8 +156,10 @@ int libcfs_kkuc_group_rem(int uid, unsigned int group) { struct kkuc_reg *reg, *next; - if (!kkuc_groups[group].next) - return 0; + if (!libcfs_kkuc_group_is_valid(group)) { + CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); + return -EINVAL; + } if (!uid) { /* Broadcast a shutdown message */ @@ -182,9 +195,14 @@ int libcfs_kkuc_group_put(unsigned int group, void *payload) int rc = 0; int one_success = 0; + if (!libcfs_kkuc_group_is_valid(group)) { + CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); + return -EINVAL; + } + down_write(&kg_sem); - if (unlikely(!kkuc_groups[group].next) || + if (unlikely(list_empty(&kkuc_groups[group])) || unlikely(OBD_FAIL_CHECK(OBD_FAIL_MDS_HSM_CT_REGISTER_NET))) { /* no agent have fully registered, CDT will retry */ up_write(&kg_sem); @@ -227,15 +245,11 @@ int libcfs_kkuc_group_foreach(unsigned int group, libcfs_kkuc_cb_t cb_func, struct kkuc_reg *reg; int rc = 0; - if (group > KUC_GRP_MAX) { + if (!libcfs_kkuc_group_is_valid(group)) { CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); return -EINVAL; } - /* no link for this group */ - if (!kkuc_groups[group].next) - return 0; - down_read(&kg_sem); list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { if (reg->kr_fp) -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:24 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:24 -0400 Subject: [lustre-devel] [PATCH 14/30] lustre: ldlm: cond_resched in ldlm_bl_thread_main In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-15-git-send-email-jsimmons@infradead.org> From: Patrick Farrell When clearing all of the ldlm LRUs (as Cray does at the end of a job), a ldlm_bl_work_item is generated for each namespace and then they are placed on a list for the ldlm_bl threads to iterate over. If the number of namespaces greatly exceeds the number of ldlm_bl threads, a given thread will iterate over many namespaces without sleeping looking for work. This can go on for an extremely long time and result in an RCU stall. This patch adds a cond_resched() between completing one work item and looking for the next. This is a fairly cheap operation, as it will only schedule if there is an interrupt waiting, and it will not be called too much - Even the largest file systems have < 100 namespaces per ldlm_bl_thread currently. Signed-off-by: Patrick Farrell WC-bug-id: https://jira.whamcloud.com/browse/LU-8307 Reviewed-on: https://review.whamcloud.com/20888 Reviewed-by: Ned Bass Reviewed-by: Ann Koehler Reviewed-by: Ben Evans Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index adc96b6..a8de3d9 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -856,6 +856,12 @@ static int ldlm_bl_thread_main(void *arg) if (rc == LDLM_ITER_STOP) break; + + /* If there are many namespaces, we will not sleep waiting for + * work, and must do a cond_resched to avoid holding the CPU + * for too long + */ + cond_resched(); } atomic_dec(&blp->blp_num_threads); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:16 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:16 -0400 Subject: [lustre-devel] [PATCH 06/30] lustre: ptlrpc: Prevent possible dereference of NULL pointers In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-7-git-send-email-jsimmons@infradead.org> From: Steve Guminski Check pointers for NULL before passing to other functions. Signed-off-by: Steve Guminski WC-bug-id: https://jira.whamcloud.com/browse/LU-9076 Reviewed-on: https://review.whamcloud.com/25909 Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/ptlrpc/client.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 4bf26a4..eddb920 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -1978,12 +1978,14 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) } ptlrpc_rqphase_move(req, RQ_PHASE_COMPLETE); - CDEBUG(req->rq_reqmsg ? D_RPCTRACE : 0, - "Completed RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", - current->comm, imp->imp_obd->obd_uuid.uuid, - lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, - libcfs_nid2str(imp->imp_connection->c_peer.nid), - lustre_msg_get_opc(req->rq_reqmsg)); + if (req->rq_reqmsg) + CDEBUG(D_RPCTRACE, + "Completed RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", + current->comm, imp->imp_obd->obd_uuid.uuid, + lustre_msg_get_status(req->rq_reqmsg), + req->rq_xid, + libcfs_nid2str(imp->imp_connection->c_peer.nid), + lustre_msg_get_opc(req->rq_reqmsg)); spin_lock(&imp->imp_lock); /* -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:19 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:19 -0400 Subject: [lustre-devel] [PATCH 09/30] lustre: obd: remove obsolete OBD_FL_LOCAL_MASK In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-10-git-send-email-jsimmons@infradead.org> From: Wang Shilong Andreas Dilger reported that the OBD_FL_LOCAL_MASK support has not been used since commit e62f0a3c5b9 b=21980 cache ll_obdo_cache: Can't free all objects; which predates the linux client. With the future landing of patch https://review.whamcloud.com/26463 lustre: quota: add project inherit attributes the handling of the "local" flags is broken and since it is unused it is better to be removed entirely. Signed-off-by: Wang Shilong WC-bug-id: https://jira.whamcloud.com/browse/LU-9355 Reviewed-on: https://review.whamcloud.com/26728 Reported-by: Andreas Dilger Reviewed-by: Niu Yawei Reviewed-by: Andreas Dilger Signed-off-by: James Simmons --- drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h | 4 +--- drivers/staging/lustre/lustre/obdclass/obdo.c | 11 ----------- drivers/staging/lustre/lustre/osc/osc_request.c | 5 ++--- drivers/staging/lustre/lustre/ptlrpc/wiretest.c | 1 - 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h index 58321eb..66b15c7 100644 --- a/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/drivers/staging/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -931,15 +931,13 @@ enum obdo_flags { OBD_FL_NOSPC_BLK = 0x00100000, /* no more block space on OST */ OBD_FL_FLUSH = 0x00200000, /* flush pages on the OST */ OBD_FL_SHORT_IO = 0x00400000, /* short io request */ + /* OBD_FL_LOCAL_MASK = 0xF0000000, was local-only flags until 2.10 */ /* Note that while these checksum values are currently separate bits, * in 2.x we can actually allow all values from 1-31 if we wanted. */ OBD_FL_CKSUM_ALL = OBD_FL_CKSUM_CRC32 | OBD_FL_CKSUM_ADLER | OBD_FL_CKSUM_CRC32C, - - /* mask for local-only flag, which won't be sent over network */ - OBD_FL_LOCAL_MASK = 0xF0000000, }; /* diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c index 5b2bfa8..8013c1e 100644 --- a/drivers/staging/lustre/lustre/obdclass/obdo.c +++ b/drivers/staging/lustre/lustre/obdclass/obdo.c @@ -134,7 +134,6 @@ void lustre_set_wire_obdo(const struct obd_connect_data *ocd, struct obdo *wobdo, const struct obdo *lobdo) { *wobdo = *lobdo; - wobdo->o_flags &= ~OBD_FL_LOCAL_MASK; if (!ocd) return; @@ -156,17 +155,7 @@ void lustre_set_wire_obdo(const struct obd_connect_data *ocd, void lustre_get_wire_obdo(const struct obd_connect_data *ocd, struct obdo *lobdo, const struct obdo *wobdo) { - u32 local_flags = 0; - - if (lobdo->o_valid & OBD_MD_FLFLAGS) - local_flags = lobdo->o_flags & OBD_FL_LOCAL_MASK; - *lobdo = *wobdo; - if (local_flags) { - lobdo->o_valid |= OBD_MD_FLFLAGS; - lobdo->o_flags &= ~OBD_FL_LOCAL_MASK; - lobdo->o_flags |= local_flags; - } if (!ocd) return; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 8024b17..5bab8a3 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -1273,10 +1273,9 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli, */ enum cksum_type cksum_type = cli->cl_cksum_type; - if ((body->oa.o_valid & OBD_MD_FLFLAGS) == 0) { - oa->o_flags &= OBD_FL_LOCAL_MASK; + if ((body->oa.o_valid & OBD_MD_FLFLAGS) == 0) body->oa.o_flags = 0; - } + body->oa.o_flags |= cksum_type_pack(cksum_type); body->oa.o_valid |= OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; body->oa.o_cksum = osc_checksum_bulk(requested_nob, diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c index 09b1298..09aef9a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c +++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c @@ -1344,7 +1344,6 @@ void lustre_assert_wire_constants(void) BUILD_BUG_ON(OBD_FL_MMAP != 0x00040000); BUILD_BUG_ON(OBD_FL_RECOV_RESEND != 0x00080000); BUILD_BUG_ON(OBD_FL_NOSPC_BLK != 0x00100000); - BUILD_BUG_ON(OBD_FL_LOCAL_MASK != 0xf0000000); /* Checks for struct lov_ost_data_v1 */ LASSERTF((int)sizeof(struct lov_ost_data_v1) == 24, "found %lld\n", -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:26 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:26 -0400 Subject: [lustre-devel] [PATCH 16/30] lustre: lnet: Change sock_create() to sock_create_kern() In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-17-git-send-email-jsimmons@infradead.org> From: Doug Oucharek Changing all calls from sock_create() to sock_create_kern(). Signed-off-by: Doug Oucharek WC-bug-id: https://jira.whamcloud.com/browse/LU-9456 Reviewed-on: https://review.whamcloud.com/26958 Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Olaf Weber Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/lnet/lib-socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c index 6758090..d9c62d3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-socket.c +++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c @@ -157,7 +157,7 @@ /* All errors are fatal except bind failure if the port is in use */ *fatal = 1; - rc = sock_create(PF_INET, SOCK_STREAM, 0, &sock); + rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock); *sockp = sock; if (rc) { CERROR("Can't create socket: %d\n", rc); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:37 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:37 -0400 Subject: [lustre-devel] [PATCH 27/30] lustre: ptlrpc: increase sleep time in ptlrpc_request_bufs_pack() In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-28-git-send-email-jsimmons@infradead.org> From: Vitaly Fertman schedule_timeout_uninterruptible() does not necessarily expire. Increase the sleeping time in ptlrpc_request_bufs_pack() as 2 seconds is too short, given the 1 second sleep used in the test suite. Signed-off-by: Vitaly Fertman Signed-off-by: Andreas Dilger WC-bug-id: https://jira.whamcloud.com/browse/LU-8062 Reviewed-on: https://review.whamcloud.com/26815 Reviewed-by: James Simmons Reviewed-by: Fan Yong Reviewed-by: John L. Hammond Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/ptlrpc/client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index eddb920..6d503d7 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -36,7 +36,9 @@ #define DEBUG_SUBSYSTEM S_RPC #include +#include #include + #include #include #include @@ -763,7 +765,7 @@ int ptlrpc_request_bufs_pack(struct ptlrpc_request *request, /* The RPC is infected, let the test change the * fail_loc */ - schedule_timeout_uninterruptible(2 * HZ); + msleep(4 * MSEC_PER_SEC); } } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:17 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:17 -0400 Subject: [lustre-devel] [PATCH 07/30] lustre: llog: update llog print format to use FIDs In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-8-git-send-email-jsimmons@infradead.org> From: Andreas Dilger Print llog identifiers using FIDs instead of OSTID format, which has been deprecated since 2.3. Signed-off-by: Andreas Dilger WC-bug-id: https://jira.whamcloud.com/browse/LU-9153 Reviewed-on: https://review.whamcloud.com/25640 Reviewed-by: Henri Doreau Reviewed-by: Faccini Bruno Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/obdclass/llog_cat.c | 28 ++++++++++++---------- drivers/staging/lustre/lustre/obdclass/llog_swab.c | 4 ++-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c index 58dbd50..172a368 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c @@ -79,10 +79,10 @@ static int llog_cat_id2handle(const struct lu_env *env, if (ostid_id(&cgl->lgl_oi) == ostid_id(&logid->lgl_oi) && ostid_seq(&cgl->lgl_oi) == ostid_seq(&logid->lgl_oi)) { if (cgl->lgl_ogen != logid->lgl_ogen) { - CERROR("%s: log " DOSTID " generation %x != %x\n", - loghandle->lgh_ctxt->loc_obd->obd_name, - POSTID(&logid->lgl_oi), cgl->lgl_ogen, - logid->lgl_ogen); + CWARN("%s: log " DFID " generation %x != %x\n", + loghandle->lgh_ctxt->loc_obd->obd_name, + PFID(&logid->lgl_oi.oi_fid), + cgl->lgl_ogen, logid->lgl_ogen); continue; } loghandle->u.phd.phd_cat_handle = cathandle; @@ -96,9 +96,9 @@ static int llog_cat_id2handle(const struct lu_env *env, rc = llog_open(env, cathandle->lgh_ctxt, &loghandle, logid, NULL, LLOG_OPEN_EXISTS); if (rc < 0) { - CERROR("%s: error opening log id " DOSTID ":%x: rc = %d\n", + CERROR("%s: error opening log id " DFID ":%x: rc = %d\n", cathandle->lgh_ctxt->loc_obd->obd_name, - POSTID(&logid->lgl_oi), logid->lgl_ogen, rc); + PFID(&logid->lgl_oi.oi_fid), logid->lgl_ogen, rc); return rc; } @@ -153,15 +153,16 @@ static int llog_cat_process_cb(const struct lu_env *env, CERROR("invalid record in catalog\n"); return -EINVAL; } - CDEBUG(D_HA, "processing log " DOSTID ":%x at index %u of catalog " - DOSTID "\n", POSTID(&lir->lid_id.lgl_oi), lir->lid_id.lgl_ogen, - rec->lrh_index, POSTID(&cat_llh->lgh_id.lgl_oi)); + CDEBUG(D_HA, + "processing log " DFID ":%x at index %u of catalog " DFID "\n", + PFID(&lir->lid_id.lgl_oi.oi_fid), lir->lid_id.lgl_ogen, + rec->lrh_index, PFID(&cat_llh->lgh_id.lgl_oi.oi_fid)); rc = llog_cat_id2handle(env, cat_llh, &llh, &lir->lid_id); if (rc) { - CERROR("%s: cannot find handle for llog " DOSTID ": %d\n", + CERROR("%s: cannot find handle for llog " DFID ": %d\n", cat_llh->lgh_ctxt->loc_obd->obd_name, - POSTID(&lir->lid_id.lgl_oi), rc); + PFID(&lir->lid_id.lgl_oi.oi_fid), rc); return rc; } @@ -206,8 +207,9 @@ static int llog_cat_process_or_fork(const struct lu_env *env, if (llh->llh_cat_idx > cat_llh->lgh_last_idx) { struct llog_process_cat_data cd; - CWARN("catlog " DOSTID " crosses index zero\n", - POSTID(&cat_llh->lgh_id.lgl_oi)); + CWARN("%s: catlog " DFID " crosses index zero\n", + cat_llh->lgh_ctxt->loc_obd->obd_name, + PFID(&cat_llh->lgh_id.lgl_oi.oi_fid)); cd.lpcd_first_idx = llh->llh_cat_idx; cd.lpcd_last_idx = 0; diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c index 3803056..f18330f 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c @@ -45,8 +45,8 @@ static void print_llogd_body(struct llogd_body *d) { CDEBUG(D_OTHER, "llogd body: %p\n", d); - CDEBUG(D_OTHER, "\tlgd_logid.lgl_oi: " DOSTID "\n", - POSTID(&d->lgd_logid.lgl_oi)); + CDEBUG(D_OTHER, "\tlgd_logid.lgl_oi: " DFID "\n", + PFID(&d->lgd_logid.lgl_oi.oi_fid)); CDEBUG(D_OTHER, "\tlgd_logid.lgl_ogen: %#x\n", d->lgd_logid.lgl_ogen); CDEBUG(D_OTHER, "\tlgd_ctxt_idx: %#x\n", d->lgd_ctxt_idx); CDEBUG(D_OTHER, "\tlgd_llh_flags: %#x\n", d->lgd_llh_flags); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:20 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:20 -0400 Subject: [lustre-devel] [PATCH 10/30] lustre: ptlrpc: set rq_sent when send fails due to -ENOMEM In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-11-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" In ptl_send_rpc() set rq_sent when we fail to send the RPC due to insufficient memory, since this is what the upper layers expect. Signed-off-by: John L. Hammond WC-bug-id: https://jira.whamcloud.com/browse/LU-9296 Reviewed-on: https://review.whamcloud.com/26470 Reviewed-by: Jinshan Xiong Reviewed-by: Mike Pershin Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index 0e13fb9..3cfd7b8 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -571,15 +571,8 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) mpflag = memalloc_noreclaim_save(); rc = sptlrpc_cli_wrap_request(request); - if (rc) { - /* - * set rq_sent so that this request is treated - * as a delayed send in the upper layers - */ - if (rc == -ENOMEM) - request->rq_sent = ktime_get_seconds(); + if (rc) goto out; - } /* bulk register should be done after wrap_request() */ if (request->rq_bulk) { @@ -724,9 +717,18 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) * the chance to have long unlink to sluggish net is smaller here. */ ptlrpc_unregister_bulk(request, 0); - out: +out: + if (rc == -ENOMEM) { + /* + * set rq_sent so that this request is treated + * as a delayed send in the upper layers + */ + request->rq_sent = ktime_get_seconds(); + } + if (request->rq_memalloc) memalloc_noreclaim_restore(mpflag); + return rc; } EXPORT_SYMBOL(ptl_send_rpc); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:30 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:30 -0400 Subject: [lustre-devel] [PATCH 20/30] lustre: osc: osc page lru list race In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-21-git-send-email-jsimmons@infradead.org> From: Bobi Jam In osc_lru_use() the osc page's ops_lru access is not protected, which could race with osc_lru_del() and ensuing that client_obd::cl_lru_in_list counter decreased twice for a single page. Signed-off-by: Bobi Jam WC-bug-id: https://jira.whamcloud.com/browse/LU-9229 Reviewed-on: https://review.whamcloud.com/26086 Reviewed-by: Jinshan Xiong Reviewed-by: Li Xi Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/osc/osc_page.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c index 20c553e..189e3e78 100644 --- a/drivers/staging/lustre/lustre/osc/osc_page.c +++ b/drivers/staging/lustre/lustre/osc/osc_page.c @@ -478,18 +478,20 @@ static void osc_lru_del(struct client_obd *cli, struct osc_page *opg) } /** - * Delete page from LRUlist for redirty. + * Delete page from LRU list for redirty. */ static void osc_lru_use(struct client_obd *cli, struct osc_page *opg) { /* If page is being transferred for the first time, * ops_lru should be empty */ - if (opg->ops_in_lru && !list_empty(&opg->ops_lru)) { + if (opg->ops_in_lru) { spin_lock(&cli->cl_lru_list_lock); - __osc_lru_del(cli, opg); + if (!list_empty(&opg->ops_lru)) { + __osc_lru_del(cli, opg); + atomic_long_inc(&cli->cl_lru_busy); + } spin_unlock(&cli->cl_lru_list_lock); - atomic_long_inc(&cli->cl_lru_busy); } } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:13 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:13 -0400 Subject: [lustre-devel] [PATCH 03/30] lustre: osc: fix for cl_env_get in low memory In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-4-git-send-email-jsimmons@infradead.org> From: Alexander Boyko In low memory situation cl_env_get->cl_env_new->kmem_cache_alloc could fail with ENOMEM error. Some parts doesn`t handle error case, for example: ...(osc_lock_upcall()) ASSERTION( !IS_ERR(env) ) failed: ...(osc_lock.c:315:osc_lock_upcall()) LBUG For osc_lock_upcall() the patch changes cl_env_get to cl_env_percpu_peek, this prevents memory allocation and couldn`t fail in low memory case. For osc_extent_truncate() the patch adds error handle. Signed-off-by: Alexander Boyko WC-bug-id: https://jira.whamcloud.com/browse/LU-9065 Seagate-bug-id: MRP-4120 Reviewed-on: https://review.whamcloud.com/25171 Reviewed-by: Jinshan Xiong Reviewed-by: Andrew Perepechko Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/osc/osc_cache.c | 3 +++ drivers/staging/lustre/lustre/osc/osc_lock.c | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index e44822a..326f663 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -1038,6 +1038,9 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index, * it's from lov_io_sub and not fully initialized. */ env = cl_env_get(&refcheck); + if (IS_ERR(env)) + return PTR_ERR(env); + io = &osc_env_info(env)->oti_io; io->ci_obj = cl_object_top(osc2cl(obj)); io->ci_ignore_layout = 1; diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c index d93d33d..d6a275f 100644 --- a/drivers/staging/lustre/lustre/osc/osc_lock.c +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c @@ -297,9 +297,8 @@ static int osc_lock_upcall(void *cookie, struct lustre_handle *lockh, struct cl_lock_slice *slice = &oscl->ols_cl; struct lu_env *env; int rc; - u16 refcheck; - env = cl_env_get(&refcheck); + env = cl_env_percpu_get(); /* should never happen, similar to osc_ldlm_blocking_ast(). */ LASSERT(!IS_ERR(env)); @@ -338,7 +337,7 @@ static int osc_lock_upcall(void *cookie, struct lustre_handle *lockh, if (oscl->ols_owner) cl_sync_io_note(env, oscl->ols_owner, rc); - cl_env_put(env, &refcheck); + cl_env_percpu_put(env); return rc; } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:21 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:21 -0400 Subject: [lustre-devel] [PATCH 11/30] lustre: mdc: allow setting readdir RPC size parameter In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-12-git-send-email-jsimmons@infradead.org> From: Andreas Dilger Allow the mdc.*.max_pages_per_rpc tunable to set the MDS bulk readdir RPC size, rather than always using the default 1MB RPC size. The tunable is set in the MDC, as it should be, rather than in the llite superblock, which requires extra code just to get it up from the MDC's connect_data only to send it back down. The RPC size could be tuned independently if different types of MDSes are used (e.g. local vs. remote). Remove the md_op_data.op_max_pages and ll_sb_info.ll_md_brw_pages fields that previously were used to pass the readdir size from llite to mdc_read_page(). Reorder some 32-bit fields in md_op_data to avoid struct holes. Move osc's max_pages_per_rpc_store() to obdclass along with max_pages_per_rpc_show(). Signed-off-by: Andreas Dilger WC-bug-id: https://jira.whamcloud.com/browse/LU-3308 Reviewed-on: https://review.whamcloud.com/26088 Reviewed-by: Niu Yawei Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/lustre/include/lprocfs_status.h | 5 ++ drivers/staging/lustre/lustre/include/lustre_net.h | 8 ++-- drivers/staging/lustre/lustre/include/obd.h | 5 +- drivers/staging/lustre/lustre/llite/dir.c | 12 +---- drivers/staging/lustre/lustre/llite/lcommon_cl.c | 19 +++----- .../staging/lustre/lustre/llite/llite_internal.h | 2 - drivers/staging/lustre/lustre/llite/llite_lib.c | 5 -- drivers/staging/lustre/lustre/llite/llite_nfs.c | 1 - drivers/staging/lustre/lustre/llite/statahead.c | 4 -- drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 20 +------- drivers/staging/lustre/lustre/mdc/mdc_request.c | 13 +++--- .../lustre/lustre/obdclass/lprocfs_status.c | 54 ++++++++++++++++++++++ drivers/staging/lustre/lustre/osc/lproc_osc.c | 46 ------------------ drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 2 +- 14 files changed, 82 insertions(+), 114 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index c841aba..5da26e3 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -584,6 +584,11 @@ ssize_t lustre_attr_store(struct kobject *kobj, struct attribute *attr, extern const struct sysfs_ops lustre_sysfs_ops; +ssize_t max_pages_per_rpc_show(struct kobject *kobj, struct attribute *attr, + char *buf); +ssize_t max_pages_per_rpc_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count); + struct root_squash_info; int lprocfs_wr_root_squash(const char __user *buffer, unsigned long count, struct root_squash_info *squash, char *name); diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index 2dbd208..cf630db 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -104,15 +104,15 @@ * currently supported maximum between peers at connect via ocd_brw_size. */ #define PTLRPC_MAX_BRW_BITS (LNET_MTU_BITS + PTLRPC_BULK_OPS_BITS) -#define PTLRPC_MAX_BRW_SIZE (1 << PTLRPC_MAX_BRW_BITS) +#define PTLRPC_MAX_BRW_SIZE BIT(PTLRPC_MAX_BRW_BITS) #define PTLRPC_MAX_BRW_PAGES (PTLRPC_MAX_BRW_SIZE >> PAGE_SHIFT) -#define ONE_MB_BRW_SIZE (1 << LNET_MTU_BITS) -#define MD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) +#define ONE_MB_BRW_SIZE BIT(LNET_MTU_BITS) +#define MD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) #define MD_MAX_BRW_PAGES (MD_MAX_BRW_SIZE >> PAGE_SHIFT) #define DT_MAX_BRW_SIZE PTLRPC_MAX_BRW_SIZE #define DT_MAX_BRW_PAGES (DT_MAX_BRW_SIZE >> PAGE_SHIFT) -#define OFD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) +#define OFD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) /* When PAGE_SIZE is a constant, we can check our arithmetic here with cpp! */ # if ((PTLRPC_MAX_BRW_PAGES & (PTLRPC_MAX_BRW_PAGES - 1)) != 0) diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 329bae9..50e97b4 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -717,11 +717,11 @@ struct md_op_data { struct lu_fid op_fid3; /* 2 extra fids to find conflicting */ struct lu_fid op_fid4; /* to the operation locks. */ u32 op_mds; /* what mds server open will go to */ + u32 op_mode; struct lustre_handle op_handle; s64 op_mod_time; const char *op_name; size_t op_namelen; - __u32 op_mode; struct lmv_stripe_md *op_mea1; struct lmv_stripe_md *op_mea2; __u32 op_suppgids[2]; @@ -746,9 +746,6 @@ struct md_op_data { /* Used by readdir */ __u64 op_offset; - /* Used by readdir */ - __u32 op_max_pages; - /* used to transfer info between the stacks of MD client * see enum op_cli_flags */ diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index f352fab..26b0c2d 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -231,18 +231,11 @@ int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data, __u64 ino; hash = le64_to_cpu(ent->lde_hash); - if (hash < pos) - /* - * Skip until we find target hash - * value. - */ + if (hash < pos) /* Skip until we find target hash */ continue; namelen = le16_to_cpu(ent->lde_namelen); - if (namelen == 0) - /* - * Skip dummy record. - */ + if (namelen == 0) /* Skip dummy record. */ continue; if (is_api32 && is_hash64) @@ -351,7 +344,6 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx) } } } - op_data->op_max_pages = sbi->ll_md_brw_pages; ctx->pos = pos; rc = ll_dir_read(inode, &pos, op_data, ctx); pos = ctx->pos; diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c index 6c9fe49..d3b0445 100644 --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c @@ -267,27 +267,22 @@ void cl_inode_fini(struct inode *inode) /** * build inode number from passed @fid */ -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) +u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) { if (BITS_PER_LONG == 32 || api32) return fid_flatten32(fid); - else - return fid_flatten(fid); + + return fid_flatten(fid); } /** * build inode generation from passed @fid. If our FID overflows the 32-bit * inode number then return a non-zero generation to distinguish them. */ -__u32 cl_fid_build_gen(const struct lu_fid *fid) +u32 cl_fid_build_gen(const struct lu_fid *fid) { - __u32 gen; - - if (fid_is_igif(fid)) { - gen = lu_igif_gen(fid); - return gen; - } + if (fid_is_igif(fid)) + return lu_igif_gen(fid); - gen = fid_flatten(fid) >> 32; - return gen; + return fid_flatten(fid) >> 32; } diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index bf679c9..9d9f623 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -490,8 +490,6 @@ struct ll_sb_info { unsigned int ll_namelen; const struct file_operations *ll_fop; - unsigned int ll_md_brw_pages; /* readdir pages per RPC */ - struct lu_site *ll_site; struct cl_device *ll_cl; /* Statistics */ diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index f0fe21f..b5bafc4 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -343,11 +343,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) if (data->ocd_connect_flags & OBD_CONNECT_64BITHASH) sbi->ll_flags |= LL_SBI_64BIT_HASH; - if (data->ocd_connect_flags & OBD_CONNECT_BRW_SIZE) - sbi->ll_md_brw_pages = data->ocd_brw_size >> PAGE_SHIFT; - else - sbi->ll_md_brw_pages = 1; - if (data->ocd_connect_flags & OBD_CONNECT_LAYOUTLOCK) sbi->ll_flags |= LL_SBI_LAYOUT_LOCK; diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c index 9efb20e..c66072a 100644 --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c @@ -261,7 +261,6 @@ static int ll_get_name(struct dentry *dentry, char *name, goto out; } - op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages; inode_lock(dir); rc = ll_dir_read(dir, &pos, op_data, &lgd.ctx); inode_unlock(dir); diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index ea2a002..1ad308c 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -961,8 +961,6 @@ static int ll_statahead_thread(void *arg) goto out; } - op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages; - while (pos != MDS_DIR_END_OFF && sai->sai_task) { struct lu_dirpage *dp; struct lu_dirent *ent; @@ -1215,8 +1213,6 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry) /** * FIXME choose the start offset of the readdir */ - op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages; - page = ll_get_dir_page(dir, op_data, pos); while (1) { diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index 3bff8b5..a205c61 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -134,6 +134,8 @@ static ssize_t max_mod_rpcs_in_flight_store(struct kobject *kobj, } LUSTRE_RW_ATTR(max_mod_rpcs_in_flight); +LUSTRE_RW_ATTR(max_pages_per_rpc); + #define mdc_conn_uuid_show conn_uuid_show LUSTRE_RO_ATTR(mdc_conn_uuid); @@ -165,24 +167,6 @@ static ssize_t mdc_rpc_stats_seq_write(struct file *file, LPROC_SEQ_FOPS_RO_TYPE(mdc, timeouts); LPROC_SEQ_FOPS_RO_TYPE(mdc, state); -/* - * Note: below sysfs entry is provided, but not currently in use, instead - * sbi->sb_md_brw_size is used, the per obd variable should be used - * when DNE is enabled, and dir pages are managed in MDC layer. - * Don't forget to enable sysfs store function then. - */ -static ssize_t max_pages_per_rpc_show(struct kobject *kobj, - struct attribute *attr, - char *buf) -{ - struct obd_device *dev = container_of(kobj, struct obd_device, - obd_kset.kobj); - struct client_obd *cli = &dev->u.cli; - - return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); -} -LUSTRE_RO_ATTR(max_pages_per_rpc); - LPROC_SEQ_FOPS_RW_TYPE(mdc, import); LPROC_SEQ_FOPS_RW_TYPE(mdc, pinger_recov); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 116e973..37bf486 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -1166,17 +1166,17 @@ static int mdc_read_page_remote(void *data, struct page *page0) struct page **page_pool; struct page *page; struct lu_dirpage *dp; - int rd_pgs = 0; /* number of pages read actually */ - int npages; struct md_op_data *op_data = rp->rp_mod; struct ptlrpc_request *req; - int max_pages = op_data->op_max_pages; struct inode *inode; struct lu_fid *fid; - int i; + int rd_pgs = 0; /* number of pages read actually */ + int max_pages; + int npages; int rc; + int i; - LASSERT(max_pages > 0 && max_pages <= PTLRPC_MAX_BRW_PAGES); + max_pages = rp->rp_exp->exp_obd->u.cli.cl_max_pages_per_rpc; inode = op_data->op_data; fid = &op_data->op_fid1; LASSERT(inode); @@ -1200,8 +1200,7 @@ static int mdc_read_page_remote(void *data, struct page *page0) if (!rc) { int lu_pgs = req->rq_bulk->bd_nob_transferred; - rd_pgs = (req->rq_bulk->bd_nob_transferred + - PAGE_SIZE - 1) >> PAGE_SHIFT; + rd_pgs = (lu_pgs + PAGE_SIZE - 1) >> PAGE_SHIFT; lu_pgs >>= LU_PAGE_SHIFT; LASSERT(!(req->rq_bulk->bd_nob_transferred & ~LU_PAGE_MASK)); diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 84e5a8c..a540abb 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -1785,3 +1785,57 @@ ssize_t lustre_attr_store(struct kobject *kobj, struct attribute *attr, .store = lustre_attr_store, }; EXPORT_SYMBOL_GPL(lustre_sysfs_ops); + +ssize_t max_pages_per_rpc_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kset.kobj); + struct client_obd *cli = &dev->u.cli; + + return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); +} +EXPORT_SYMBOL(max_pages_per_rpc_show); + +ssize_t max_pages_per_rpc_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) +{ + struct obd_device *dev = container_of(kobj, struct obd_device, + obd_kset.kobj); + struct client_obd *cli = &dev->u.cli; + struct obd_connect_data *ocd; + unsigned long long val; + int chunk_mask; + int rc; + + rc = kstrtoull(buffer, 10, &val); + if (rc) + return rc; + + /* if the max_pages is specified in bytes, convert to pages */ + if (val >= ONE_MB_BRW_SIZE) + val >>= PAGE_SHIFT; + + rc = lprocfs_climp_check(dev); + if (rc) + return rc; + + ocd = &cli->cl_import->imp_connect_data; + chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_SHIFT)) - 1); + /* max_pages_per_rpc must be chunk aligned */ + val = (val + ~chunk_mask) & chunk_mask; + if (!val || (ocd->ocd_brw_size && + val > ocd->ocd_brw_size >> PAGE_SHIFT)) { + up_read(&dev->u.cli.cl_sem); + return -ERANGE; + } + + spin_lock(&cli->cl_loi_list_lock); + cli->cl_max_pages_per_rpc = val; + client_adjust_max_dirty(cli); + spin_unlock(&cli->cl_loi_list_lock); + + up_read(&dev->u.cli.cl_sem); + return count; +} +EXPORT_SYMBOL(max_pages_per_rpc_store); diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index cd28295..bf576f1 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -570,52 +570,6 @@ static ssize_t destroys_in_flight_show(struct kobject *kobj, atomic_read(&obd->u.cli.cl_destroy_in_flight)); } LUSTRE_RO_ATTR(destroys_in_flight); - -static ssize_t max_pages_per_rpc_show(struct kobject *kobj, - struct attribute *attr, - char *buf) -{ - struct obd_device *dev = container_of(kobj, struct obd_device, - obd_kset.kobj); - struct client_obd *cli = &dev->u.cli; - - return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); -} - -static ssize_t max_pages_per_rpc_store(struct kobject *kobj, - struct attribute *attr, - const char *buffer, - size_t count) -{ - struct obd_device *dev = container_of(kobj, struct obd_device, - obd_kset.kobj); - struct client_obd *cli = &dev->u.cli; - struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data; - int chunk_mask, rc; - unsigned long long val; - - rc = kstrtoull(buffer, 10, &val); - if (rc) - return rc; - - /* if the max_pages is specified in bytes, convert to pages */ - if (val >= ONE_MB_BRW_SIZE) - val >>= PAGE_SHIFT; - - chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_SHIFT)) - 1); - /* max_pages_per_rpc must be chunk aligned */ - val = (val + ~chunk_mask) & chunk_mask; - if (!val || (ocd->ocd_brw_size && - val > ocd->ocd_brw_size >> PAGE_SHIFT)) { - return -ERANGE; - } - spin_lock(&cli->cl_loi_list_lock); - cli->cl_max_pages_per_rpc = val; - client_adjust_max_dirty(cli); - spin_unlock(&cli->cl_loi_list_lock); - - return count; -} LUSTRE_RW_ATTR(max_pages_per_rpc); static int osc_unstable_stats_seq_show(struct seq_file *m, void *v) diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index 625b952..3d336d9 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -232,7 +232,7 @@ static unsigned long enc_pools_shrink_count(struct shrinker *s, } LASSERT(page_pools.epp_idle_idx <= IDLE_IDX_MAX); - return max((int)page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES, 0) * + return max(page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES, 0UL) * (IDLE_IDX_MAX - page_pools.epp_idle_idx) / IDLE_IDX_MAX; } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:34 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:34 -0400 Subject: [lustre-devel] [PATCH 24/30] lustre: llite: rcu-walk check should not depend on statahead In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-25-git-send-email-jsimmons@infradead.org> From: Steve Guminski Moves the check for the LOOKUP_RCU flag, so that it does not depend on the statahead setting. The caller is now informed if rcu-walk was requested but the filesystem does not support it, regardless of whether statahead is enabled or disabled. Signed-off-by: Steve Guminski WC-bug-id: https://jira.whamcloud.com/browse/LU-8891 Reviewed-on: https://review.whamcloud.com/24195 Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/llite/dcache.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c index 11b82c63..ee1ba16 100644 --- a/drivers/staging/lustre/lustre/llite/dcache.c +++ b/drivers/staging/lustre/lustre/llite/dcache.c @@ -270,13 +270,12 @@ static int ll_revalidate_dentry(struct dentry *dentry, if (lookup_flags & LOOKUP_REVAL) return 0; - if (!dentry_may_statahead(dir, dentry)) - return 1; - if (lookup_flags & LOOKUP_RCU) return -ECHILD; - ll_statahead(dir, &dentry, !d_inode(dentry)); + if (dentry_may_statahead(dir, dentry)) + ll_statahead(dir, &dentry, !d_inode(dentry)); + return 1; } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:35 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:35 -0400 Subject: [lustre-devel] [PATCH 25/30] lustre: llite: check the return value of cl_file_inode_init() In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-26-git-send-email-jsimmons@infradead.org> From: Bobi Jam ll_update_inode() does not check the return value of cl_file_inode_init(), and it should check. Signed-off-by: Bobi Jam WC-bug-id: https://jira.whamcloud.com/browse/LU-9485 Reviewed-on: https://review.whamcloud.com/27658 Reviewed-by: Fan Yong Reviewed-by: Jinshan Xiong Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/llite/llite_lib.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b5bafc4..99d0b72 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1792,13 +1792,15 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) struct ll_inode_info *lli = ll_i2info(inode); struct mdt_body *body = md->body; struct ll_sb_info *sbi = ll_i2sbi(inode); + int rc = 0; - if (body->mbo_valid & OBD_MD_FLEASIZE) - cl_file_inode_init(inode, md); + if (body->mbo_valid & OBD_MD_FLEASIZE) { + rc = cl_file_inode_init(inode, md); + if (rc) + return rc; + } if (S_ISDIR(inode->i_mode)) { - int rc; - rc = ll_update_lsm_md(inode, md); if (rc) return rc; -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:36 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:36 -0400 Subject: [lustre-devel] [PATCH 26/30] lustre: ptlrpc: add replay request into unreplied list In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-27-git-send-email-jsimmons@infradead.org> From: Niu Yawei ptlrpc_prepare_replay() may fail to add replay request into unreplied list if the request hasn't been on replay list yet, so in ptlrpc_replay_next() before sending replay, we'd always make sure the replay request is on unreplied list. Signed-off-by: Niu Yawei WC-bug-id: https://jira.whamcloud.com/browse/LU-9274 Reviewed-on: https://review.whamcloud.com/27920 Reviewed-by: Fan Yong Reviewed-by: Yang Sheng Reviewed-by: Mike Pershin Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/ptlrpc/recover.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c index 2ea0a7f..9d369f8 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/recover.c +++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c @@ -136,11 +136,14 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight) if (req && imp->imp_resend_replay) lustre_msg_add_flags(req->rq_reqmsg, MSG_RESENT); - /* The resend replay request may have been removed from the + /* ptlrpc_prepare_replay() may fail to add the request into unreplied + * list if the request hasn't been added to replay list then. Another + * exception is that resend replay could have been removed from the * unreplied list. */ - if (req && imp->imp_resend_replay && - list_empty(&req->rq_unreplied_list)) { + if (req && list_empty(&req->rq_unreplied_list)) { + DEBUG_REQ(D_HA, req, "resend_replay: %d, last_transno: %llu\n", + imp->imp_resend_replay, last_transno); ptlrpc_add_unreplied(req); imp->imp_known_replied_xid = ptlrpc_known_replied_xid(imp); } @@ -149,9 +152,6 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight) spin_unlock(&imp->imp_lock); if (req) { - /* The request should have been added back in unreplied list - * by ptlrpc_prepare_replay(). - */ LASSERT(!list_empty(&req->rq_unreplied_list)); rc = ptlrpc_replay_req(req); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:38 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:38 -0400 Subject: [lustre-devel] [PATCH 28/30] lustre: ptlrpc: free reply buffer earlier for open RPC In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-29-git-send-email-jsimmons@infradead.org> From: Fan Yong It is unnecessary to keep the reply buffer for open RPC. Replay related data has already been saved in the request buffer when the RPC replied. If the open replay really happen, the replay logic will alloc the reply buffer when needed. On the other hand, the client always tries to alloc big enough space to hold the open RPC reply since the client does not exactly know how much data the server will reply to the client. So the reply buffer may be quite larger than the real needed. Under such case, keeping the large reply buffer for the open RPC will occupy a lot of RAM as to OOM if the are too many open RPCs to be replayed. This patch frees the reply buffer for the open RPC when only the replay logic holds the last reference of the RPC. Signed-off-by: Fan Yong WC-bug-id: https://jira.whamcloud.com/browse/LU-9514 Reviewed-on: https://review.whamcloud.com/27208 Reviewed-by: Niu Yawei Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/lustre_net.h | 6 ++- drivers/staging/lustre/lustre/mdc/mdc_request.c | 20 ++++++++- drivers/staging/lustre/lustre/ptlrpc/client.c | 49 +++++++++++++++++----- .../staging/lustre/lustre/ptlrpc/pack_generic.c | 26 ++++++++---- .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h | 1 + 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index cf630db..e755e99 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -738,7 +738,8 @@ struct ptlrpc_request { /** Lock to protect request flags and some other important bits, like * rq_list */ - spinlock_t rq_lock; + spinlock_t rq_lock; + spinlock_t rq_early_free_lock; /** client-side flags are serialized by rq_lock @{ */ unsigned int rq_intr:1, rq_replied:1, rq_err:1, rq_timedout:1, rq_resend:1, rq_restart:1, @@ -770,7 +771,8 @@ struct ptlrpc_request { */ rq_allow_replay:1, /* bulk request, sent to server, but uncommitted */ - rq_unstable:1; + rq_unstable:1, + rq_early_free_repbuf:1; /* free reply buffer in advance */ /** @} */ /** server-side flags @{ */ diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 37bf486..2108877 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -573,8 +573,15 @@ void mdc_replay_open(struct ptlrpc_request *req) body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); + spin_lock(&req->rq_lock); och = mod->mod_och; - if (och) { + if (och && och->och_fh.cookie) + req->rq_early_free_repbuf = 1; + else + req->rq_early_free_repbuf = 0; + spin_unlock(&req->rq_lock); + + if (req->rq_early_free_repbuf) { struct lustre_handle *file_fh; LASSERT(och->och_magic == OBD_CLIENT_HANDLE_MAGIC); @@ -585,6 +592,7 @@ void mdc_replay_open(struct ptlrpc_request *req) old = *file_fh; *file_fh = body->mbo_handle; } + close_req = mod->mod_close_req; if (close_req) { __u32 opc = lustre_msg_get_opc(close_req->rq_reqmsg); @@ -595,8 +603,9 @@ void mdc_replay_open(struct ptlrpc_request *req) &RMF_MDT_EPOCH); LASSERT(epoch); - if (och) + if (req->rq_early_free_repbuf) LASSERT(!memcmp(&old, &epoch->mio_handle, sizeof(old))); + DEBUG_REQ(D_HA, close_req, "updating close body with new fh"); epoch->mio_handle = body->mbo_handle; } @@ -677,6 +686,7 @@ int mdc_set_open_replay_data(struct obd_export *exp, mod->mod_open_req = open_req; open_req->rq_cb_data = mod; open_req->rq_commit_cb = mdc_commit_open; + open_req->rq_early_free_repbuf = 1; spin_unlock(&open_req->rq_lock); } @@ -731,6 +741,12 @@ static int mdc_clear_open_replay_data(struct obd_export *exp, LASSERT(mod != LP_POISON); LASSERT(mod->mod_open_req); + + spin_lock(&mod->mod_open_req->rq_lock); + if (mod->mod_och) + mod->mod_och->och_fh.cookie = 0; + mod->mod_open_req->rq_early_free_repbuf = 0; + spin_unlock(&mod->mod_open_req->rq_lock); mdc_free_open(mod); mod->mod_och = NULL; diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 6d503d7..8fafc8d 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -2413,28 +2413,54 @@ static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked) * Drops one reference count for request \a request. * \a locked set indicates that caller holds import imp_lock. * Frees the request when reference count reaches zero. + * + * RETURN 1 the request is freed + * RETURN 0 some others still hold references on the request */ static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked) { + int count; + if (!request) return 1; - if (request == LP_POISON || - request->rq_reqmsg == LP_POISON) { - CERROR("dereferencing freed request (bug 575)\n"); - LBUG(); - return 1; - } + LASSERT(request != LP_POISON); + LASSERT(request->rq_reqmsg != LP_POISON); DEBUG_REQ(D_INFO, request, "refcount now %u", atomic_read(&request->rq_refcount) - 1); - if (atomic_dec_and_test(&request->rq_refcount)) { - __ptlrpc_free_req(request, locked); - return 1; + spin_lock(&request->rq_lock); + count = atomic_dec_return(&request->rq_refcount); + LASSERTF(count >= 0, "Invalid ref count %d\n", count); + + /* For open RPC, the client does not know the EA size (LOV, ACL, and + * so on) before replied, then the client has to reserve very large + * reply buffer. Such buffer will not be released until the RPC freed. + * Since The open RPC is replayable, we need to keep it in the replay + * list until close. If there are a lot of files opened concurrently, + * then the client may be OOM. + * + * If fact, it is unnecessary to keep reply buffer for open replay, + * related EAs have already been saved via mdc_save_lovea() before + * coming here. So it is safe to free the reply buffer some earlier + * before releasing the RPC to avoid client OOM. LU-9514 + */ + if (count == 1 && request->rq_early_free_repbuf && request->rq_repbuf) { + spin_lock(&request->rq_early_free_lock); + sptlrpc_cli_free_repbuf(request); + request->rq_repbuf = NULL; + request->rq_repbuf_len = 0; + request->rq_repdata = NULL; + request->rq_reqdata_len = 0; + spin_unlock(&request->rq_early_free_lock); } + spin_unlock(&request->rq_lock); - return 0; + if (!count) + __ptlrpc_free_req(request, locked); + + return !count; } /** @@ -2920,6 +2946,9 @@ int ptlrpc_replay_req(struct ptlrpc_request *req) DEBUG_REQ(D_HA, req, "REPLAY"); atomic_inc(&req->rq_import->imp_replay_inflight); + spin_lock(&req->rq_lock); + req->rq_early_free_repbuf = 0; + spin_unlock(&req->rq_lock); ptlrpc_request_addref(req); /* ptlrpcd needs a ref */ ptlrpcd_add_req(req); diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index 86a64a6..96d0377 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -2169,7 +2169,8 @@ static inline int req_ptlrpc_body_swabbed(struct ptlrpc_request *req) static inline int rep_ptlrpc_body_swabbed(struct ptlrpc_request *req) { - LASSERT(req->rq_repmsg); + if (unlikely(!req->rq_repmsg)) + return 0; switch (req->rq_repmsg->lm_magic) { case LUSTRE_MSG_MAGIC_V2: @@ -2181,19 +2182,30 @@ static inline int rep_ptlrpc_body_swabbed(struct ptlrpc_request *req) } void _debug_req(struct ptlrpc_request *req, - struct libcfs_debug_msg_data *msgdata, - const char *fmt, ...) + struct libcfs_debug_msg_data *msgdata, const char *fmt, ...) { - int req_ok = req->rq_reqmsg != NULL; - int rep_ok = req->rq_repmsg != NULL; + bool req_ok = req->rq_reqmsg != NULL; + bool rep_ok = false; lnet_nid_t nid = LNET_NID_ANY; + int rep_flags = -1; + int rep_status = -1; va_list args; + spin_lock(&req->rq_early_free_lock); + if (req->rq_repmsg) + rep_ok = true; + if (ptlrpc_req_need_swab(req)) { req_ok = req_ok && req_ptlrpc_body_swabbed(req); rep_ok = rep_ok && rep_ptlrpc_body_swabbed(req); } + if (rep_ok) { + rep_flags = lustre_msg_get_flags(req->rq_repmsg); + rep_status = lustre_msg_get_status(req->rq_repmsg); + } + spin_unlock(&req->rq_early_free_lock); + if (req->rq_import && req->rq_import->imp_connection) nid = req->rq_import->imp_connection->c_peer.nid; else if (req->rq_export && req->rq_export->exp_connection) @@ -2218,9 +2230,7 @@ void _debug_req(struct ptlrpc_request *req, atomic_read(&req->rq_refcount), DEBUG_REQ_FLAGS(req), req_ok ? lustre_msg_get_flags(req->rq_reqmsg) : -1, - rep_ok ? lustre_msg_get_flags(req->rq_repmsg) : -1, - req->rq_status, - rep_ok ? lustre_msg_get_status(req->rq_repmsg) : -1); + rep_flags, req->rq_status, rep_status); va_end(args); } EXPORT_SYMBOL(_debug_req); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h index 134b742..0e4a215 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h @@ -309,6 +309,7 @@ static inline void ptlrpc_reqset_put(struct ptlrpc_request_set *set) static inline void ptlrpc_req_comm_init(struct ptlrpc_request *req) { spin_lock_init(&req->rq_lock); + spin_lock_init(&req->rq_early_free_lock); atomic_set(&req->rq_refcount, 1); INIT_LIST_HEAD(&req->rq_list); INIT_LIST_HEAD(&req->rq_replay_list); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:29 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:29 -0400 Subject: [lustre-devel] [PATCH 19/30] lustre: llite: set sec ctx on client's inode at create time In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-20-git-send-email-jsimmons@infradead.org> From: Sebastien Buisson On client side, security context must be set on the inode of every new dir or file that is being created. With LL_SBI_FILE_SECCTX, security context is obtained from the dentry thanks to a call to ll_dentry_init_security(). And it is saved to security.xxx xattr directly on MDS side when processing the create request. So it is only necessary to call security_inode_notifysecctx() to set the sec ctx on the client's inode. Without LL_SBI_FILE_SECCTX, security context can only be obtained from the inode, ie after the file has been created on MDS side. So use ll_inode_init_security() that will set the sec ctx on the client's inode, and at the same time save it on disk to security.xxx xattr, generating an additional request to the MDS. Signed-off-by: Sebastien Buisson WC-bug-id: https://jira.whamcloud.com/browse/LU-8956 Reviewed-on: https://review.whamcloud.com/24426 Reviewed-by: Faccini Bruno Reviewed-by: Jean-Baptiste Riaux Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/llite/dir.c | 10 ++++- drivers/staging/lustre/lustre/llite/namei.c | 59 ++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 26b0c2d..aa55bfd 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -42,6 +42,7 @@ #include /* for wait_on_buffer */ #include #include +#include #define DEBUG_SUBSYSTEM S_LLITE @@ -468,8 +469,15 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump, dentry.d_inode = inode; - if (!(sbi->ll_flags & LL_SBI_FILE_SECCTX)) + if (sbi->ll_flags & LL_SBI_FILE_SECCTX) { + inode_lock(inode); + err = security_inode_notifysecctx(inode, + op_data->op_file_secctx, + op_data->op_file_secctx_size); + inode_unlock(inode); + } else { err = ll_inode_init_security(&dentry, inode, parent); + } out_inode: iput(inode); diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index ca81e0c..09cdf02 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -47,7 +47,7 @@ #include "llite_internal.h" static int ll_create_it(struct inode *dir, struct dentry *dentry, - struct lookup_intent *it); + struct lookup_intent *it, void *secctx, u32 secctxlen); /* called from iget5_locked->find_inode() under inode_hash_lock spinlock */ static int ll_test_inode(struct inode *inode, void *opaque) @@ -527,7 +527,8 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request, } static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, - struct lookup_intent *it) + struct lookup_intent *it, void **secctx, + u32 *secctxlen) { struct lookup_intent lookup_it = { .it_op = IT_LOOKUP }; struct dentry *save = dentry, *retval; @@ -590,6 +591,10 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, retval = ERR_PTR(rc); goto out; } + if (secctx) + *secctx = op_data->op_file_secctx; + if (secctxlen) + *secctxlen = op_data->op_file_secctx_size; } rc = md_intent_lock(ll_i2mdexp(parent), op_data, it, &req, @@ -649,8 +654,16 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, else retval = dentry; out: - if (op_data && !IS_ERR(op_data)) + if (op_data && !IS_ERR(op_data)) { + if (secctx && secctxlen) { + /* caller needs sec ctx info, so reset it in op_data to + * prevent it from being freed + */ + op_data->op_file_secctx = NULL; + op_data->op_file_secctx_size = 0; + } ll_finish_md_op_data(op_data); + } ptlrpc_req_finished(req); return retval; @@ -677,7 +690,7 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, itp = NULL; else itp = ⁢ - de = ll_lookup_it(parent, dentry, itp); + de = ll_lookup_it(parent, dentry, itp, NULL, NULL); if (itp) ll_intent_release(itp); @@ -694,6 +707,8 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, umode_t mode) { struct lookup_intent *it; + void *secctx = NULL; + u32 secctxlen = 0; struct dentry *de; int rc = 0; @@ -730,7 +745,7 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, it->it_flags &= ~MDS_OPEN_FL_INTERNAL; /* Dentry added to dcache tree in ll_lookup_it */ - de = ll_lookup_it(dir, dentry, it); + de = ll_lookup_it(dir, dentry, it, &secctx, &secctxlen); if (IS_ERR(de)) rc = PTR_ERR(de); else if (de) @@ -739,7 +754,8 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, if (!rc) { if (it_disposition(it, DISP_OPEN_CREATE)) { /* Dentry instantiated in ll_create_it. */ - rc = ll_create_it(dir, dentry, it); + rc = ll_create_it(dir, dentry, it, secctx, secctxlen); + security_release_secctx(secctx, secctxlen); if (rc) { /* We dget in ll_splice_alias. */ if (de) @@ -828,7 +844,7 @@ static struct inode *ll_create_node(struct inode *dir, struct lookup_intent *it) * with d_instantiate(). */ static int ll_create_it(struct inode *dir, struct dentry *dentry, - struct lookup_intent *it) + struct lookup_intent *it, void *secctx, u32 secctxlen) { struct inode *inode; int rc = 0; @@ -844,6 +860,18 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) return PTR_ERR(inode); + if ((ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX) && secctx) { + inode_lock(inode); + /* must be done before d_instantiate, because it calls + * security_d_instantiate, which means a getxattr if security + * context is not set yet + */ + rc = security_inode_notifysecctx(inode, secctx, secctxlen); + inode_unlock(inode); + if (rc) + return rc; + } + d_instantiate(dentry, inode); if (!(ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX)) @@ -906,8 +934,6 @@ static int ll_new_node(struct inode *dir, struct dentry *dentry, from_kuid(&init_user_ns, current_fsuid()), from_kgid(&init_user_ns, current_fsgid()), current_cap(), rdev, &request); - ll_finish_md_op_data(op_data); - op_data = NULL; if (err < 0 && err != -EREMOTE) goto err_exit; @@ -944,6 +970,7 @@ static int ll_new_node(struct inode *dir, struct dentry *dentry, ptlrpc_req_finished(request); request = NULL; + ll_finish_md_op_data(op_data); goto again; } @@ -953,6 +980,20 @@ static int ll_new_node(struct inode *dir, struct dentry *dentry, if (err) goto err_exit; + if (sbi->ll_flags & LL_SBI_FILE_SECCTX) { + inode_lock(inode); + /* must be done before d_instantiate, because it calls + * security_d_instantiate, which means a getxattr if security + * context is not set yet + */ + err = security_inode_notifysecctx(inode, + op_data->op_file_secctx, + op_data->op_file_secctx_size); + inode_unlock(inode); + if (err) + goto err_exit; + } + d_instantiate(dentry, inode); if (!(sbi->ll_flags & LL_SBI_FILE_SECCTX)) -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:31 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:31 -0400 Subject: [lustre-devel] [PATCH 21/30] lustre: ldlm: use static initializer macros where possible In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-22-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" In lustre/ldlm/ replace module load time initialization of several mutexes with static initialization using the kernel provided macros. Signed-off-by: John L. Hammond WC-bug-id: https://jira.whamcloud.com/browse/LU-9010 Reviewed-on: https://review.whamcloud.com/24824 Reviewed-by: Dmitry Eremin Reviewed-by: James Simmons Reviewed-by: Andreas Dilger Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/lustre_dlm.h | 3 +-- drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c | 6 +----- drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h index a68c7a4..e2bbcaa 100644 --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h @@ -742,8 +742,7 @@ struct ldlm_lock { * The lists this could be linked into are: * waiting_locks_list (protected by waiting_locks_spinlock), * then if the lock timed out, it is moved to - * expired_lock_thread.elt_expired_locks for further processing. - * Protected by elt_lock. + * expired_lock_list for further processing. */ struct list_head l_pending_chain; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index a8de3d9..986c378 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -53,7 +53,7 @@ module_param(ldlm_cpts, charp, 0444); MODULE_PARM_DESC(ldlm_cpts, "CPU partitions ldlm threads should run on"); -static struct mutex ldlm_ref_mutex; +static DEFINE_MUTEX(ldlm_ref_mutex); static int ldlm_refcount; static struct kobject *ldlm_kobj; @@ -69,10 +69,6 @@ struct ldlm_cb_async_args { static struct ldlm_state *ldlm_state; -#define ELT_STOPPED 0 -#define ELT_READY 1 -#define ELT_TERMINATE 2 - struct ldlm_bl_pool { spinlock_t blp_lock; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index 1907a5a..bd5622d 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -49,10 +49,10 @@ int ldlm_srv_namespace_nr; int ldlm_cli_namespace_nr; -struct mutex ldlm_srv_namespace_lock; +DEFINE_MUTEX(ldlm_srv_namespace_lock); LIST_HEAD(ldlm_srv_namespace_list); -struct mutex ldlm_cli_namespace_lock; +DEFINE_MUTEX(ldlm_cli_namespace_lock); /* Client Namespaces that have active resources in them. * Once all resources go away, ldlm_poold moves such namespaces to the * inactive list -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:32 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:32 -0400 Subject: [lustre-devel] [PATCH 22/30] lustre: osc: update timestamps on write only In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-23-git-send-email-jsimmons@infradead.org> From: Niu Yawei In osc_io_submit(), we should only update timestamps on write. Signed-off-by: Niu Yawei WC-bug-id: https://jira.whamcloud.com/browse/LU-9470 Reviewed-on: https://review.whamcloud.com/27348 Reviewed-by: Bobi Jam Reviewed-by: John L. Hammond Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/osc/osc_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index 628743b..e7151ed 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -212,7 +212,7 @@ static int osc_io_submit(const struct lu_env *env, result = osc_queue_sync_pages(env, osc, &list, cmd, brw_flags); /* Update c/mtime for sync write. LU-7310 */ - if (qout->pl_nr > 0 && !result) { + if (crt == CRT_WRITE && qout->pl_nr > 0 && !result) { struct cl_attr *attr = &osc_env_info(env)->oti_attr; struct cl_object *obj = ios->cis_obj; -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:21 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:21 -0400 Subject: [lustre-devel] [PATCH 8/8] lustre: obd: add md_stats to MDC and LMV devices In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-9-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" Enable md_stats for MDC and LMV devices. These stats track usage of the md_ops methods (from the OBD layer, not to be confused with md_device methods) and are exported through the files /sys/fs/lustre/{lmv,mdc}/*/md_stats. Rename m_sync to m_fsync making the counter name (fsync) more intuitive. The operations counted are close, create, enqueue, getattr, intent_lock, link, rename, setattr, fsync, readpage, unlink, setxattr, getxattr, intent_getattr_async, and revalidate_lock. Signed-off-by: John L. Hammond WC-bug-id: https://jira.whamcloud.com/browse/LU-2484 Reviewed-on: http://review.whamcloud.com/4827 Reviewed-by: Andreas Dilger Reviewed-by: wangdi Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/obd.h | 4 ++-- drivers/staging/lustre/lustre/include/obd_class.h | 6 +++--- drivers/staging/lustre/lustre/llite/file.c | 2 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 9 +++++---- drivers/staging/lustre/lustre/lmv/lproc_lmv.c | 6 ++++++ drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 7 +++++++ drivers/staging/lustre/lustre/mdc/mdc_request.c | 8 +++++--- 7 files changed, 29 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 6e78c50..11e7ae8 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -942,8 +942,8 @@ struct md_ops { struct ptlrpc_request **); int (*setattr)(struct obd_export *, struct md_op_data *, void *, size_t, struct ptlrpc_request **); - int (*sync)(struct obd_export *, const struct lu_fid *, - struct ptlrpc_request **); + int (*fsync)(struct obd_export *, const struct lu_fid *, + struct ptlrpc_request **); int (*read_page)(struct obd_export *, struct md_op_data *, struct md_callback *cb_op, __u64 hash_offset, struct page **ppage); diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 2514b39..824d378 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -1350,8 +1350,8 @@ static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data, return MDP(exp->exp_obd, setattr)(exp, op_data, ea, ealen, request); } -static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid, - struct ptlrpc_request **request) +static inline int md_fsync(struct obd_export *exp, const struct lu_fid *fid, + struct ptlrpc_request **request) { int rc; @@ -1362,7 +1362,7 @@ static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid, lprocfs_counter_incr(exp->exp_obd->obd_md_stats, LPROC_MD_FSYNC); - return MDP(exp->exp_obd, sync)(exp, fid, request); + return MDP(exp->exp_obd, fsync)(exp, fid, request); } static inline int md_read_page(struct obd_export *exp, diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 94760eb..092fa99 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -2656,7 +2656,7 @@ int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync) } } - err = md_sync(ll_i2sbi(inode)->ll_md_exp, ll_inode2fid(inode), &req); + err = md_fsync(ll_i2sbi(inode)->ll_md_exp, ll_inode2fid(inode), &req); if (!rc) rc = err; if (!err) diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index cf2a4c6..71bd843 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -1989,8 +1989,8 @@ static int lmv_setattr(struct obd_export *exp, struct md_op_data *op_data, return md_setattr(tgt->ltd_exp, op_data, ea, ealen, request); } -static int lmv_sync(struct obd_export *exp, const struct lu_fid *fid, - struct ptlrpc_request **request) +static int lmv_fsync(struct obd_export *exp, const struct lu_fid *fid, + struct ptlrpc_request **request) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; @@ -2000,7 +2000,7 @@ static int lmv_sync(struct obd_export *exp, const struct lu_fid *fid, if (IS_ERR(tgt)) return PTR_ERR(tgt); - return md_sync(tgt->ltd_exp, fid, request); + return md_fsync(tgt->ltd_exp, fid, request); } /** @@ -2502,6 +2502,7 @@ static int lmv_precleanup(struct obd_device *obd) { fld_client_debugfs_fini(&obd->u.lmv.lmv_fld); lprocfs_obd_cleanup(obd); + ldebugfs_free_md_stats(obd); return 0; } @@ -3079,7 +3080,7 @@ static int lmv_merge_attr(struct obd_export *exp, .rename = lmv_rename, .setattr = lmv_setattr, .setxattr = lmv_setxattr, - .sync = lmv_sync, + .fsync = lmv_fsync, .read_page = lmv_read_page, .unlink = lmv_unlink, .init_ea_size = lmv_init_ea_size, diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c index efc12ad..4e30026 100644 --- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c +++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c @@ -168,6 +168,12 @@ int lmv_tunables_init(struct obd_device *obd) if (rc) return rc; + rc = ldebugfs_alloc_md_stats(obd, 0); + if (rc) { + lprocfs_obd_cleanup(obd); + return rc; + } + debugfs_create_file("target_obd", 0444, obd->obd_debugfs_entry, obd, &lmv_debugfs_target_fops); diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index a205c61..ffc1085 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -210,8 +210,15 @@ int mdc_tunables_init(struct obd_device *obd) if (rc) return rc; + rc = ldebugfs_alloc_md_stats(obd, 0); + if (rc) { + lprocfs_obd_cleanup(obd); + return rc; + } + rc = sptlrpc_lprocfs_cliobd_attach(obd); if (rc) { + ldebugfs_free_md_stats(obd); lprocfs_obd_cleanup(obd); return rc; } diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 2108877..8f8e3d2 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2487,8 +2487,8 @@ static int mdc_get_info(const struct lu_env *env, struct obd_export *exp, return rc; } -static int mdc_sync(struct obd_export *exp, const struct lu_fid *fid, - struct ptlrpc_request **request) +static int mdc_fsync(struct obd_export *exp, const struct lu_fid *fid, + struct ptlrpc_request **request) { struct ptlrpc_request *req; int rc; @@ -2677,6 +2677,7 @@ static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg) return 0; err_llog_cleanup: + ldebugfs_free_md_stats(obd); ptlrpc_lprocfs_unregister_obd(obd); err_osc_cleanup: client_obd_cleanup(obd); @@ -2716,6 +2717,7 @@ static int mdc_precleanup(struct obd_device *obd) obd_cleanup_client_import(obd); ptlrpc_lprocfs_unregister_obd(obd); lprocfs_obd_cleanup(obd); + ldebugfs_free_md_stats(obd); mdc_llog_finish(obd); return 0; } @@ -2772,7 +2774,7 @@ static int mdc_process_config(struct obd_device *obd, u32 len, void *buf) .setattr = mdc_setattr, .setxattr = mdc_setxattr, .getxattr = mdc_getxattr, - .sync = mdc_sync, + .fsync = mdc_fsync, .read_page = mdc_read_page, .unlink = mdc_unlink, .cancel_unused = mdc_cancel_unused, -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:30:39 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:30:39 -0400 Subject: [lustre-devel] [PATCH 29/30] lustre: libcfs: use save_stack_trace for stack dump In-Reply-To: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205440-6656-30-git-send-email-jsimmons@infradead.org> From: Yang Sheng The function libcfs_debug_dumpstack() was removed due to it being x86 specific upstream. This restores this functionality using save_stack_trace_tsk for stack trace dumps. This will be used for the restored ptlrpc watchdog that will be landed in the future. Signed-off-by: Yang Sheng WC-bug-id: https://jira.whamcloud.com/browse/LU-11062 Reviewed-on: https://review.whamcloud.com/32952 Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../lustre/include/linux/libcfs/libcfs_debug.h | 1 + drivers/staging/lustre/lnet/libcfs/debug.c | 46 ++++++++++++++++++++-- drivers/staging/lustre/lustre/ldlm/ldlm_lock.c | 2 +- drivers/staging/lustre/lustre/osc/osc_object.c | 2 +- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h index 17534a7..27a3b12 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h @@ -58,6 +58,7 @@ int libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys); int libcfs_debug_str2mask(int *mask, const char *str, int is_subsys); +void libcfs_debug_dumpstack(struct task_struct *tsk); /* Has there been an LBUG? */ extern unsigned int libcfs_catastrophe; diff --git a/drivers/staging/lustre/lnet/libcfs/debug.c b/drivers/staging/lustre/lnet/libcfs/debug.c index dd06a4c..90d756c 100644 --- a/drivers/staging/lustre/lnet/libcfs/debug.c +++ b/drivers/staging/lustre/lnet/libcfs/debug.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include "tracefile.h" static char debug_file_name[1024]; @@ -435,17 +437,55 @@ void __noreturn lbug_with_loc(struct libcfs_debug_msg_data *msgdata) /* not reached */ } - dump_stack(); - if (!libcfs_panic_on_lbug) - libcfs_debug_dumplog(); + libcfs_debug_dumpstack(NULL); if (libcfs_panic_on_lbug) panic("LBUG"); + else + libcfs_debug_dumplog(); set_current_state(TASK_UNINTERRUPTIBLE); while (1) schedule(); } EXPORT_SYMBOL(lbug_with_loc); +#ifdef CONFIG_STACKTRACE +#define MAX_ST_ENTRIES 100 +static DEFINE_SPINLOCK(st_lock); + +static void libcfs_call_trace(struct task_struct *tsk) +{ + static unsigned long entries[MAX_ST_ENTRIES]; + struct stack_trace trace; + + trace.nr_entries = 0; + trace.max_entries = MAX_ST_ENTRIES; + trace.entries = entries; + trace.skip = 0; + + spin_lock(&st_lock); + pr_info("Pid: %d, comm: %.20s %s %s\n", tsk->pid, tsk->comm, + init_utsname()->release, init_utsname()->version); + pr_info("Call Trace:\n"); + save_stack_trace_tsk(tsk, &trace); + print_stack_trace(&trace, 0); + spin_unlock(&st_lock); +} +#else /* !CONFIG_STACKTRACE */ +static void libcfs_call_trace(struct task_struct *tsk) +{ + if (tsk == current) + dump_stack(); + else + CWARN("can't show stack: kernel doesn't export show_task\n"); +} +#endif /* !CONFIG_STACKTRACE */ + +void libcfs_debug_dumpstack(struct task_struct *tsk) +{ + libcfs_call_trace(tsk ?: current); +} +EXPORT_SYMBOL(libcfs_debug_dumpstack); + static int panic_notifier(struct notifier_block *self, unsigned long unused1, void *unused2) { diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 3cbdc81..bc6b122 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -1503,7 +1503,7 @@ int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill, break; default: LDLM_ERROR(lock, "Unknown LVB type: %d", lock->l_lvb_type); - dump_stack(); + libcfs_debug_dumpstack(NULL); return -EINVAL; } diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c index b9bf2b8..a86d4c2 100644 --- a/drivers/staging/lustre/lustre/osc/osc_object.c +++ b/drivers/staging/lustre/lustre/osc/osc_object.c @@ -399,7 +399,7 @@ static void osc_req_attr_set(const struct lu_env *env, struct cl_object *obj, osc_export(cl2osc(obj))->exp_obd->obd_namespace, NULL, resname, LDLM_EXTENT, 0); ldlm_resource_dump(D_ERROR, res); - + libcfs_debug_dumpstack(NULL); LBUG(); } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:18 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:18 -0400 Subject: [lustre-devel] [PATCH 5/8] lustre: obd: remove obd_{get,put}ref() In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-6-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" obd_getref() and obd_putref() are only used in the lov layer and only implemented by the lov layer. So they can be removed in favor of direct calls. Rename lov_{get,put}ref() to lov_tgts_{get,put}ref() since they do not manage references on the lov device but on its targets array. Signed-off-by: John L. Hammond WC-bug-id: https://jira.whamcloud.com/browse/LU-11051 Reviewed-on: https://review.whamcloud.com/32529 Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/obd.h | 7 ---- drivers/staging/lustre/lustre/include/obd_class.h | 16 --------- drivers/staging/lustre/lustre/lov/lov_dev.c | 12 ++++--- drivers/staging/lustre/lustre/lov/lov_internal.h | 2 ++ drivers/staging/lustre/lustre/lov/lov_obd.c | 44 +++++++++++------------ drivers/staging/lustre/lustre/lov/lov_pool.c | 10 +++--- drivers/staging/lustre/lustre/lov/lov_request.c | 4 +-- 7 files changed, 39 insertions(+), 56 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 50e97b4..44f9b10 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -882,13 +882,6 @@ struct obd_ops { char *ostname); int (*pool_rem)(struct obd_device *obd, char *poolname, char *ostname); - void (*getref)(struct obd_device *obd); - void (*putref)(struct obd_device *obd); - /* - * NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line - * to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c. - * Also, add a wrapper function in include/linux/obd_class.h. - */ }; /* lmv structures */ diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index aab1092..eb0a53d 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -927,22 +927,6 @@ static inline int obd_pool_rem(struct obd_device *obd, return rc; } -static inline void obd_getref(struct obd_device *obd) -{ - if (obd->obd_type && OBP(obd, getref)) { - OBD_COUNTER_INCREMENT(obd, getref); - OBP(obd, getref)(obd); - } -} - -static inline void obd_putref(struct obd_device *obd) -{ - if (obd->obd_type && OBP(obd, putref)) { - OBD_COUNTER_INCREMENT(obd, putref); - OBP(obd, putref)(obd); - } -} - static inline int obd_init_export(struct obd_export *exp) { int rc = 0; diff --git a/drivers/staging/lustre/lustre/lov/lov_dev.c b/drivers/staging/lustre/lustre/lov/lov_dev.c index c7db234..abf2ede 100644 --- a/drivers/staging/lustre/lustre/lov/lov_dev.c +++ b/drivers/staging/lustre/lustre/lov/lov_dev.c @@ -266,7 +266,7 @@ static int lov_cl_add_target(const struct lu_env *env, struct lu_device *dev, struct cl_device *cl; int rc; - obd_getref(obd); + lov_tgts_getref(obd); tgt = obd->u.lov.lov_tgts[index]; @@ -291,7 +291,9 @@ static int lov_cl_add_target(const struct lu_env *env, struct lu_device *dev, rc = PTR_ERR(cl); } } - obd_putref(obd); + + lov_tgts_putref(obd); + return rc; } @@ -304,7 +306,7 @@ static int lov_process_config(const struct lu_env *env, int gen; __u32 index; - obd_getref(obd); + lov_tgts_getref(obd); cmd = cfg->lcfg_command; rc = lov_process_config_base(d->ld_obd, cfg, &index, &gen); @@ -321,7 +323,9 @@ static int lov_process_config(const struct lu_env *env, break; } } - obd_putref(obd); + + lov_tgts_putref(obd); + return rc; } diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index dbb79d4..44a997e 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -207,6 +207,8 @@ int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo, int lov_fini_statfs_set(struct lov_request_set *set); /* lov_obd.c */ +void lov_tgts_getref(struct obd_device *obd); +void lov_tgts_putref(struct obd_device *obd); void lov_stripe_lock(struct lov_stripe_md *md); void lov_stripe_unlock(struct lov_stripe_md *md); void lov_fix_desc(struct lov_desc *desc); diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 3483f9b..6959b91 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -62,7 +62,7 @@ /* Keep a refcount of lov->tgt usage to prevent racing with addition/deletion. * Any function that expects lov_tgts to remain stationary must take a ref. */ -static void lov_getref(struct obd_device *obd) +void lov_tgts_getref(struct obd_device *obd) { struct lov_obd *lov = &obd->u.lov; @@ -74,7 +74,7 @@ static void lov_getref(struct obd_device *obd) static void __lov_del_obd(struct obd_device *obd, struct lov_tgt_desc *tgt); -static void lov_putref(struct obd_device *obd) +void lov_tgts_putref(struct obd_device *obd) { struct lov_obd *lov = &obd->u.lov; @@ -231,7 +231,7 @@ static int lov_connect(const struct lu_env *env, if (data) lov->lov_ocd = *data; - obd_getref(obd); + lov_tgts_getref(obd); lov->lov_tgts_kobj = kobject_create_and_add("target_obds", &obd->obd_kset.kobj); @@ -258,7 +258,7 @@ static int lov_connect(const struct lu_env *env, obd->obd_name, rc); } } - obd_putref(obd); + lov_tgts_putref(obd); return 0; } @@ -326,7 +326,7 @@ static int lov_disconnect(struct obd_export *exp) /* Let's hold another reference so lov_del_obd doesn't spin through * putref every time */ - obd_getref(obd); + lov_tgts_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { if (lov->lov_tgts[i] && lov->lov_tgts[i]->ltd_exp) { @@ -335,7 +335,7 @@ static int lov_disconnect(struct obd_export *exp) } } - obd_putref(obd); + lov_tgts_putref(obd); out: rc = class_disconnect(exp); /* bz 9811 */ @@ -359,7 +359,7 @@ static int lov_set_osc_active(struct obd_device *obd, struct obd_uuid *uuid, CDEBUG(D_INFO, "Searching in lov %p for uuid %s event(%d)\n", lov, uuid->uuid, ev); - obd_getref(obd); + lov_tgts_getref(obd); for (index = 0; index < lov->desc.ld_tgt_count; index++) { tgt = lov->lov_tgts[index]; if (!tgt) @@ -426,7 +426,7 @@ static int lov_set_osc_active(struct obd_device *obd, struct obd_uuid *uuid, } out: - obd_putref(obd); + lov_tgts_putref(obd); return index; } @@ -574,7 +574,7 @@ static int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, return 0; } - obd_getref(obd); + lov_tgts_getref(obd); rc = lov_connect_obd(obd, index, active, &lov->lov_ocd); if (rc) @@ -604,7 +604,7 @@ static int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp, obd_uuid2str(&tgt->ltd_uuid)); lov_del_target(obd, index, NULL, 0); } - obd_putref(obd); + lov_tgts_putref(obd); return rc; } @@ -624,7 +624,7 @@ int lov_del_target(struct obd_device *obd, __u32 index, /* to make sure there's no ongoing lov_notify() now */ down_write(&lov->lov_notify_lock); - obd_getref(obd); + lov_tgts_getref(obd); if (!lov->lov_tgts[index]) { CERROR("LOV target at index %d is not setup.\n", index); @@ -647,9 +647,9 @@ int lov_del_target(struct obd_device *obd, __u32 index, lov->lov_tgts[index]->ltd_reap = 1; lov->lov_death_row++; - /* we really delete it from obd_putref */ + /* we really delete it from lov_tgts_putref */ out: - obd_putref(obd); + lov_tgts_putref(obd); up_write(&lov->lov_notify_lock); return rc; @@ -812,7 +812,7 @@ static int lov_cleanup(struct obd_device *obd) if (lov->lov_tgts) { int i; - obd_getref(obd); + lov_tgts_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { if (!lov->lov_tgts[i]) continue; @@ -829,7 +829,7 @@ static int lov_cleanup(struct obd_device *obd) atomic_read(&lov->lov_refcount)); lov_del_target(obd, i, NULL, 0); } - obd_putref(obd); + lov_tgts_putref(obd); kfree(lov->lov_tgts); lov->lov_tgt_size = 0; } @@ -1182,7 +1182,7 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp, if (!vallen || !val) return -EFAULT; - obd_getref(obddev); + lov_tgts_getref(obddev); if (KEY_IS(KEY_MAX_EASIZE)) { u32 max_stripe_count = min_t(u32, ld->ld_active_tgt_count, @@ -1200,7 +1200,7 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp, rc = -EINVAL; } - obd_putref(obddev); + lov_tgts_putref(obddev); return rc; } @@ -1222,7 +1222,7 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp, return -ENOMEM; } - obd_getref(obddev); + lov_tgts_getref(obddev); count = lov->desc.ld_tgt_count; if (KEY_IS(KEY_CHECKSUM)) { @@ -1251,7 +1251,7 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp, rc = err; } - obd_putref(obddev); + lov_tgts_putref(obddev); if (no_set) { err = ptlrpc_set_wait(set); if (!rc) @@ -1294,7 +1294,7 @@ static int lov_quotactl(struct obd_device *obd, struct obd_export *exp, } /* for lov tgt */ - obd_getref(obd); + lov_tgts_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { int err; @@ -1326,7 +1326,7 @@ static int lov_quotactl(struct obd_device *obd, struct obd_export *exp, bhardlimit += oqctl->qc_dqblk.dqb_bhardlimit; } } - obd_putref(obd); + lov_tgts_putref(obd); if (oqctl->qc_cmd == Q_GETOQUOTA) { oqctl->qc_dqblk.dqb_curspace = curspace; @@ -1352,8 +1352,6 @@ static int lov_quotactl(struct obd_device *obd, struct obd_export *exp, .pool_rem = lov_pool_remove, .pool_add = lov_pool_add, .pool_del = lov_pool_del, - .getref = lov_getref, - .putref = lov_putref, .quotactl = lov_quotactl, }; diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c index b2a88ba..c79c2ae 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pool.c +++ b/drivers/staging/lustre/lustre/lov/lov_pool.c @@ -470,7 +470,7 @@ int lov_pool_add(struct obd_device *obd, char *poolname, char *ostname) obd_str2uuid(&ost_uuid, ostname); /* search ost in lov array */ - obd_getref(obd); + lov_tgts_getref(obd); for (lov_idx = 0; lov_idx < lov->desc.ld_tgt_count; lov_idx++) { if (!lov->lov_tgts[lov_idx]) continue; @@ -492,8 +492,9 @@ int lov_pool_add(struct obd_device *obd, char *poolname, char *ostname) ostname, poolname, pool_tgt_count(pool)); out: - obd_putref(obd); + lov_tgts_putref(obd); lov_pool_putref(pool); + return rc; } @@ -517,7 +518,7 @@ int lov_pool_remove(struct obd_device *obd, char *poolname, char *ostname) obd_str2uuid(&ost_uuid, ostname); - obd_getref(obd); + lov_tgts_getref(obd); /* search ost in lov array, to get index */ for (lov_idx = 0; lov_idx < lov->desc.ld_tgt_count; lov_idx++) { if (!lov->lov_tgts[lov_idx]) @@ -540,7 +541,8 @@ int lov_pool_remove(struct obd_device *obd, char *poolname, char *ostname) poolname); out: - obd_putref(obd); + lov_tgts_putref(obd); lov_pool_putref(pool); + return rc; } diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c index cb8567f..8ca13ed 100644 --- a/drivers/staging/lustre/lustre/lov/lov_request.c +++ b/drivers/staging/lustre/lustre/lov/lov_request.c @@ -266,7 +266,7 @@ static int cb_statfs_update(void *cookie, int rc) if (rc) goto out; - obd_getref(lovobd); + lov_tgts_getref(lovobd); tgt = lov->lov_tgts[lovreq->rq_idx]; if (!tgt || !tgt->ltd_active) goto out_update; @@ -280,7 +280,7 @@ static int cb_statfs_update(void *cookie, int rc) out_update: lov_update_statfs(osfs, lov_sfs, success); - obd_putref(lovobd); + lov_tgts_putref(lovobd); out: return 0; } -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:19 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:19 -0400 Subject: [lustre-devel] [PATCH 6/8] lustre: obd: remove OBD ops based stats In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-7-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" Stats maintained via the OBD operations wrappers (obd_setup(), obd_cleanup(), ...) are less and less interesting to the point that we should remove them. The only stats files affected by this are obdfilter.*.stats, obdfilter.*.exports.*.stats and obdecho.*.stats which are server side only. Signed-off-by: John L. Hammond WC-bug-id: https://jira.whamcloud.com/browse/LU-11052 Reviewed-on: https://review.whamcloud.com/32602 Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Jesse Hanley Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/obd.h | 1 - drivers/staging/lustre/lustre/include/obd_class.h | 66 +---------------------- 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 44f9b10..8691aec 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -598,7 +598,6 @@ struct obd_device { /* Fields used by LProcFS */ struct lprocfs_stats *obd_stats; - unsigned int obd_cntr_base; struct lprocfs_stats *md_stats; unsigned int md_cntr_base; diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index eb0a53d..0c1922e 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -334,33 +334,6 @@ static inline int obd_check_dev_active(struct obd_device *obd) return rc; } -#define OBD_COUNTER_OFFSET(op) \ - ((offsetof(struct obd_ops, op) - \ - offsetof(struct obd_ops, iocontrol)) \ - / sizeof(((struct obd_ops *)(0))->iocontrol)) - -#define OBD_COUNTER_INCREMENT(obdx, op) \ -do { \ - if ((obdx)->obd_stats) { \ - unsigned int coffset; \ - coffset = (unsigned int)((obdx)->obd_cntr_base) + \ - OBD_COUNTER_OFFSET(op); \ - LASSERT(coffset < (obdx)->obd_stats->ls_num); \ - lprocfs_counter_incr((obdx)->obd_stats, coffset); \ - } \ -} while (0) - -#define EXP_COUNTER_INCREMENT(export, op) \ -do { \ - if ((export)->exp_obd->obd_stats) { \ - unsigned int coffset; \ - coffset = (unsigned int)((export)->exp_obd->obd_cntr_base) + \ - OBD_COUNTER_OFFSET(op); \ - LASSERT(coffset < (export)->exp_obd->obd_stats->ls_num); \ - lprocfs_counter_incr((export)->exp_obd->obd_stats, coffset); \ - } \ -} while (0) - #define MD_COUNTER_OFFSET(op) \ ((offsetof(struct md_ops, op) - \ offsetof(struct md_ops, get_root)) \ @@ -422,7 +395,6 @@ static inline int obd_get_info(const struct lu_env *env, exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, get_info); rc = OBP(exp->exp_obd, get_info)(env, exp, keylen, key, vallen, val); return rc; @@ -444,7 +416,6 @@ static inline int obd_set_info_async(const struct lu_env *env, exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, set_info_async); rc = OBP(exp->exp_obd, set_info_async)(env, exp, keylen, key, vallen, val, set); @@ -506,7 +477,6 @@ static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, setup); rc = OBP(obd, setup)(obd, cfg); } return rc; @@ -530,8 +500,6 @@ static inline int obd_precleanup(struct obd_device *obd) if (!obd->obd_type->typ_dt_ops->precleanup) return 0; - OBD_COUNTER_INCREMENT(obd, precleanup); - rc = OBP(obd, precleanup)(obd); return rc; } @@ -555,8 +523,6 @@ static inline int obd_cleanup(struct obd_device *obd) if (!obd->obd_type->typ_dt_ops->cleanup) return 0; - OBD_COUNTER_INCREMENT(obd, cleanup); - rc = OBP(obd, cleanup)(obd); return rc; } @@ -605,7 +571,6 @@ static inline int obd_process_config(struct obd_device *obd, int datalen, } rc = OBP(obd, process_config)(obd, datalen, data); } - OBD_COUNTER_INCREMENT(obd, process_config); obd->obd_process_conf = 0; return rc; @@ -625,7 +590,6 @@ static inline int obd_create(const struct lu_env *env, struct obd_export *exp, exp->exp_obd->obd_name, __func__); return -EOPNOTSUPP; } - EXP_COUNTER_INCREMENT(exp, create); rc = OBP(exp->exp_obd, create)(env, exp, obdo); return rc; @@ -645,7 +609,6 @@ static inline int obd_destroy(const struct lu_env *env, struct obd_export *exp, exp->exp_obd->obd_name, __func__); return -EOPNOTSUPP; } - EXP_COUNTER_INCREMENT(exp, destroy); rc = OBP(exp->exp_obd, destroy)(env, exp, obdo); return rc; @@ -665,7 +628,6 @@ static inline int obd_getattr(const struct lu_env *env, struct obd_export *exp, exp->exp_obd->obd_name, __func__); return -EOPNOTSUPP; } - EXP_COUNTER_INCREMENT(exp, getattr); rc = OBP(exp->exp_obd, getattr)(env, exp, oa); return rc; @@ -685,7 +647,6 @@ static inline int obd_setattr(const struct lu_env *env, struct obd_export *exp, exp->exp_obd->obd_name, __func__); return -EOPNOTSUPP; } - EXP_COUNTER_INCREMENT(exp, setattr); rc = OBP(exp->exp_obd, setattr)(env, exp, oa); return rc; @@ -705,7 +666,6 @@ static inline int obd_add_conn(struct obd_import *imp, struct obd_uuid *uuid, CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, add_conn); rc = OBP(obd, add_conn)(imp, uuid, priority); return rc; @@ -724,7 +684,6 @@ static inline int obd_del_conn(struct obd_import *imp, struct obd_uuid *uuid) CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, del_conn); rc = OBP(obd, del_conn)(imp, uuid); return rc; @@ -738,8 +697,6 @@ static inline struct obd_uuid *obd_get_uuid(struct obd_export *exp) !exp->exp_obd->obd_type->typ_dt_ops->get_uuid) return NULL; - EXP_COUNTER_INCREMENT(exp, get_uuid); - uuid = OBP(exp->exp_obd, get_uuid)(exp); return uuid; } @@ -768,7 +725,6 @@ static inline int obd_connect(const struct lu_env *env, CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, connect); rc = OBP(obd, connect)(env, exp, obd, cluuid, data, localdata); /* check that only subset is granted */ @@ -794,8 +750,6 @@ static inline int obd_reconnect(const struct lu_env *env, if (!obd->obd_type || !obd->obd_type->typ_dt_ops->reconnect) return 0; - OBD_COUNTER_INCREMENT(obd, reconnect); - rc = OBP(obd, reconnect)(env, exp, obd, cluuid, d, localdata); /* check that only subset is granted */ LASSERT(ergo(d, (d->ocd_connect_flags & ocf) == d->ocd_connect_flags)); @@ -815,7 +769,6 @@ static inline int obd_disconnect(struct obd_export *exp) exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, disconnect); rc = OBP(exp->exp_obd, disconnect)(exp); return rc; @@ -828,7 +781,6 @@ static inline int obd_fid_init(struct obd_device *obd, struct obd_export *exp, if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_init) return 0; - OBD_COUNTER_INCREMENT(obd, fid_init); rc = OBP(obd, fid_init)(obd, exp, type); return rc; @@ -840,7 +792,6 @@ static inline int obd_fid_fini(struct obd_device *obd) if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_fini) return 0; - OBD_COUNTER_INCREMENT(obd, fid_fini); rc = OBP(obd, fid_fini)(obd); return rc; @@ -862,7 +813,6 @@ static inline int obd_fid_alloc(const struct lu_env *env, exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, fid_alloc); rc = OBP(exp->exp_obd, fid_alloc)(env, exp, fid, op_data); return rc; @@ -876,7 +826,6 @@ static inline int obd_pool_new(struct obd_device *obd, char *poolname) CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, pool_new); rc = OBP(obd, pool_new)(obd, poolname); return rc; @@ -890,7 +839,6 @@ static inline int obd_pool_del(struct obd_device *obd, char *poolname) CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, pool_del); rc = OBP(obd, pool_del)(obd, poolname); return rc; @@ -905,7 +853,6 @@ static inline int obd_pool_add(struct obd_device *obd, char *poolname, CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, pool_add); rc = OBP(obd, pool_add)(obd, poolname, ostname); return rc; @@ -921,7 +868,6 @@ static inline int obd_pool_rem(struct obd_device *obd, CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, pool_rem); rc = OBP(obd, pool_rem)(obd, poolname, ostname); return rc; @@ -966,7 +912,6 @@ static inline int obd_statfs_async(struct obd_export *exp, CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, statfs); CDEBUG(D_SUPER, "%s: osfs %p age %llu, max_age %llu\n", obd->obd_name, &obd->obd_osfs, obd->obd_osfs_age, max_age); @@ -1029,7 +974,6 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp, CERROR("%s: no %s operation\n", obd->obd_name, __func__); return -EOPNOTSUPP; } - OBD_COUNTER_INCREMENT(obd, statfs); CDEBUG(D_SUPER, "osfs %llu, max_age %llu\n", obd->obd_osfs_age, max_age); @@ -1071,7 +1015,6 @@ static inline int obd_preprw(const struct lu_env *env, int cmd, exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, preprw); rc = OBP(exp->exp_obd, preprw)(env, cmd, exp, oa, objcount, obj, remote, pages, local); @@ -1095,7 +1038,6 @@ static inline int obd_commitrw(const struct lu_env *env, int cmd, exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, commitrw); rc = OBP(exp->exp_obd, commitrw)(env, cmd, exp, oa, objcount, obj, rnb, pages, local, orig_rc); @@ -1116,7 +1058,6 @@ static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp, exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, iocontrol); rc = OBP(exp->exp_obd, iocontrol)(cmd, exp, len, karg, uarg); return rc; @@ -1130,10 +1071,9 @@ static inline void obd_import_event(struct obd_device *obd, CERROR("NULL device\n"); return; } - if (obd->obd_set_up && OBP(obd, import_event)) { - OBD_COUNTER_INCREMENT(obd, import_event); + + if (obd->obd_set_up && OBP(obd, import_event)) OBP(obd, import_event)(obd, imp, event); - } } static inline int obd_notify(struct obd_device *obd, @@ -1156,7 +1096,6 @@ static inline int obd_notify(struct obd_device *obd, return -ENOSYS; } - OBD_COUNTER_INCREMENT(obd, notify); rc = OBP(obd, notify)(obd, watched, ev); return rc; } @@ -1196,7 +1135,6 @@ static inline int obd_quotactl(struct obd_export *exp, exp->exp_obd->obd_name, __func__); return -ENOTSUPP; } - EXP_COUNTER_INCREMENT(exp, quotactl); rc = OBP(exp->exp_obd, quotactl)(exp->exp_obd, exp, oqctl); return rc; -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:16 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:16 -0400 Subject: [lustre-devel] [PATCH 3/8] lustre: obdclass: Code cleanup In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-4-git-send-email-jsimmons@infradead.org> From: Ben Evans Remove uuid.c, and unroll class_uuid_unparse Rewrite CL_ENV_INC and DEC Remove D_KUC #define Signed-off-by: Ben Evans WC-bug-id: https://jira.whamcloud.com/browse/LU-9855 Reviewed-on: https://review.whamcloud.com/28458 Reviewed-by: John L. Hammond Reviewed-by: Dmitry Eremin Reviewed-by: Patrick Farrell Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/obd_class.h | 40 +++++++------------ drivers/staging/lustre/lustre/llite/llite_lib.c | 3 +- drivers/staging/lustre/lustre/obdclass/Makefile | 5 +-- drivers/staging/lustre/lustre/obdclass/cl_object.c | 21 ++++++---- drivers/staging/lustre/lustre/obdclass/class_obd.c | 1 - .../staging/lustre/lustre/obdclass/kernelcomm.c | 7 ++-- drivers/staging/lustre/lustre/obdclass/obd_mount.c | 2 +- drivers/staging/lustre/lustre/obdclass/uuid.c | 45 ---------------------- 8 files changed, 34 insertions(+), 90 deletions(-) delete mode 100644 drivers/staging/lustre/lustre/obdclass/uuid.c diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 39a5eca..c6fb2e1 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -497,9 +497,9 @@ static inline int obd_set_info_async(const struct lu_env *env, static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) { - int rc; struct lu_device_type *ldt; struct lu_device *d; + int rc; ldt = obd->obd_type->typ_lu; if (ldt) { @@ -536,15 +536,10 @@ static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) static inline int obd_precleanup(struct obd_device *obd) { + struct lu_device_type *ldt = obd->obd_type->typ_lu; + struct lu_device *d = obd->obd_lu_dev; int rc; - struct lu_device_type *ldt; - struct lu_device *d; - rc = obd_check_dev(obd); - if (rc) - return rc; - ldt = obd->obd_type->typ_lu; - d = obd->obd_lu_dev; if (ldt && d) { struct lu_env env; @@ -563,16 +558,10 @@ static inline int obd_precleanup(struct obd_device *obd) static inline int obd_cleanup(struct obd_device *obd) { + struct lu_device_type *ldt = obd->obd_type->typ_lu; + struct lu_device *d = obd->obd_lu_dev; int rc; - struct lu_device_type *ldt; - struct lu_device *d; - rc = obd_check_dev(obd); - if (rc) - return rc; - - ldt = obd->obd_type->typ_lu; - d = obd->obd_lu_dev; if (ldt && d) { struct lu_env env; @@ -613,17 +602,11 @@ static inline void obd_cleanup_client_import(struct obd_device *obd) static inline int obd_process_config(struct obd_device *obd, int datalen, void *data) { + struct lu_device_type *ldt = obd->obd_type->typ_lu; + struct lu_device *d = obd->obd_lu_dev; int rc; - struct lu_device_type *ldt; - struct lu_device *d; - - rc = obd_check_dev(obd); - if (rc) - return rc; obd->obd_process_conf = 1; - ldt = obd->obd_type->typ_lu; - d = obd->obd_lu_dev; if (ldt && d) { struct lu_env env; @@ -1554,9 +1537,12 @@ struct lwp_register_item { /* obd_mount.c */ int lustre_check_exclusion(struct super_block *sb, char *svname); -/* uuid.c */ -typedef __u8 class_uuid_t[16]; -void class_uuid_unparse(class_uuid_t in, struct obd_uuid *out); +typedef u8 class_uuid_t[16]; + +static inline void class_uuid_unparse(class_uuid_t uu, struct obd_uuid *out) +{ + sprintf(out->uuid, "%pU", uu); +} /* lustre_peer.c */ int lustre_uuid_to_peer(const char *uuid, lnet_nid_t *peer_nid, int index); diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 3de6e886..22b545e 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -98,7 +98,8 @@ static struct ll_sb_info *ll_init_sbi(void) SBI_DEFAULT_READAHEAD_WHOLE_MAX; ll_generate_random_uuid(uuid); - class_uuid_unparse(uuid, &sbi->ll_sb_uuid); + sprintf(sbi->ll_sb_uuid.uuid, "%pU", uuid); + CDEBUG(D_CONFIG, "generated uuid: %s\n", sbi->ll_sb_uuid.uuid); sbi->ll_flags |= LL_SBI_VERBOSE; diff --git a/drivers/staging/lustre/lustre/obdclass/Makefile b/drivers/staging/lustre/lustre/obdclass/Makefile index 19c8bd9..b1fac48 100644 --- a/drivers/staging/lustre/lustre/obdclass/Makefile +++ b/drivers/staging/lustre/lustre/obdclass/Makefile @@ -4,9 +4,8 @@ ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include obj-$(CONFIG_LUSTRE_FS) += obdclass.o -obdclass-y := obd_sysfs.o \ - llog.o llog_cat.o llog_obd.o llog_swab.o class_obd.o debug.o \ - genops.o uuid.o lprocfs_status.o lprocfs_counters.o \ +obdclass-y := llog.o llog_cat.o llog_obd.o llog_swab.o class_obd.o debug.o \ + genops.o obd_sysfs.o lprocfs_status.o lprocfs_counters.o \ lustre_handles.o lustre_peer.o statfs_pack.o linkea.o \ obdo.o obd_config.o obd_mount.o lu_object.o lu_ref.o \ cl_object.o cl_page.o cl_lock.o cl_io.o kernelcomm.o diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index d1d7bec..09fc7e7 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -572,8 +572,13 @@ struct cl_env { void *ce_debug; }; -#define CL_ENV_INC(counter) -#define CL_ENV_DEC(counter) +static void cl_env_inc(enum cache_stats_item item) +{ +} + +static void cl_env_dec(enum cache_stats_item item) +{ +} static void cl_env_init0(struct cl_env *cle, void *debug) { @@ -583,7 +588,7 @@ static void cl_env_init0(struct cl_env *cle, void *debug) cle->ce_ref = 1; cle->ce_debug = debug; - CL_ENV_INC(busy); + cl_env_inc(CS_busy); } static struct lu_env *cl_env_new(__u32 ctx_tags, __u32 ses_tags, void *debug) @@ -614,8 +619,8 @@ static struct lu_env *cl_env_new(__u32 ctx_tags, __u32 ses_tags, void *debug) kmem_cache_free(cl_env_kmem, cle); env = ERR_PTR(rc); } else { - CL_ENV_INC(create); - CL_ENV_INC(total); + cl_env_inc(CS_create); + cl_env_inc(CS_total); } } else { env = ERR_PTR(-ENOMEM); @@ -625,7 +630,7 @@ static struct lu_env *cl_env_new(__u32 ctx_tags, __u32 ses_tags, void *debug) static void cl_env_fini(struct cl_env *cle) { - CL_ENV_DEC(total); + cl_env_dec(CS_total); lu_context_fini(&cle->ce_lu.le_ctx); lu_context_fini(&cle->ce_ses); kmem_cache_free(cl_env_kmem, cle); @@ -781,7 +786,7 @@ void cl_env_put(struct lu_env *env, u16 *refcheck) if (--cle->ce_ref == 0) { int cpu = get_cpu(); - CL_ENV_DEC(busy); + cl_env_dec(CS_busy); cle->ce_debug = NULL; cl_env_exit(cle); /* @@ -902,7 +907,7 @@ void cl_env_percpu_put(struct lu_env *env) cle->ce_ref--; LASSERT(cle->ce_ref == 0); - CL_ENV_DEC(busy); + cl_env_dec(CS_busy); cle->ce_debug = NULL; put_cpu(); diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 2d23608..2103d2a 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -585,7 +585,6 @@ static long obd_class_ioctl(struct file *filp, unsigned int cmd, .fops = &obd_psdev_fops, }; -#define OBD_INIT_CHECK static int obd_init_checks(void) { __u64 u64val, div64val; diff --git a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c index 0fcfecf..3b006df 100644 --- a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c +++ b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c @@ -37,7 +37,6 @@ */ #define DEBUG_SUBSYSTEM S_CLASS -#define D_KUC D_OTHER #include #include @@ -77,7 +76,7 @@ int libcfs_kkuc_msg_put(struct file *filp, void *payload) if (rc < 0) CWARN("message send failed (%d)\n", rc); else - CDEBUG(D_KUC, "Sent message rc=%d, fp=%p\n", rc, filp); + CDEBUG(D_HSM, "Sent message rc=%d, fp=%p\n", rc, filp); return rc; } @@ -146,7 +145,7 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, unsigned int group, list_add(®->kr_chain, &kkuc_groups[group]); up_write(&kg_sem); - CDEBUG(D_KUC, "Added uid=%d fp=%p to group %d\n", uid, filp, group); + CDEBUG(D_HSM, "Added uid=%d fp=%p to group %d\n", uid, filp, group); return 0; } @@ -176,7 +175,7 @@ int libcfs_kkuc_group_rem(int uid, unsigned int group) list_for_each_entry_safe(reg, next, &kkuc_groups[group], kr_chain) { if (!uid || (uid == reg->kr_uid)) { list_del(®->kr_chain); - CDEBUG(D_KUC, "Removed uid=%d fp=%p from group %d\n", + CDEBUG(D_HSM, "Removed uid=%d fp=%p from group %d\n", reg->kr_uid, reg->kr_fp, group); if (reg->kr_fp) fput(reg->kr_fp); diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index f59e7c4..33a67fd 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -336,7 +336,7 @@ int lustre_start_mgc(struct super_block *sb) } ll_generate_random_uuid(uuidc); - class_uuid_unparse(uuidc, uuid); + sprintf(uuid->uuid, "%pU", uuidc); /* Start the MGC */ rc = lustre_start_simple(mgcname, LUSTRE_MGC_NAME, diff --git a/drivers/staging/lustre/lustre/obdclass/uuid.c b/drivers/staging/lustre/lustre/obdclass/uuid.c deleted file mode 100644 index ec8c6dc..0000000 --- a/drivers/staging/lustre/lustre/obdclass/uuid.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.gnu.org/licenses/gpl-2.0.html - * - * GPL HEADER END - */ -/* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/obdclass/uuid.c - * - * Public include file for the UUID library - */ - -#define DEBUG_SUBSYSTEM S_CLASS - -#include -#include - -void class_uuid_unparse(class_uuid_t uu, struct obd_uuid *out) -{ - sprintf(out->uuid, "%pU", uu); -} -EXPORT_SYMBOL(class_uuid_unparse); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:20 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:20 -0400 Subject: [lustre-devel] [PATCH 7/8] lustre: obdclass: restore md_stats code In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-8-git-send-email-jsimmons@infradead.org> Originally the linux lustre client contained the md_stats code but no one used it at that time so some parts of the code was removed. The remaining md_stats code is layered in many levels of macros that make the code difficult to read as well as introduce undetected errors. This patch peels away the macro wrappers by replacing it with the function lprocfs_count_incr() which doesn't care about the order of the function pointers in struct md_ops as the original code did. Signed-off-by: James Simmons WC-bug-id: https://jira.whamcloud.com/browse/LU-9855 Reviewed-on: https://review.whamcloud.com/32822 Reviewed-by: Ben Evans Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/lustre/include/lprocfs_status.h | 5 +- drivers/staging/lustre/lustre/include/obd.h | 8 +- drivers/staging/lustre/lustre/include/obd_class.h | 233 +++++++++++---------- drivers/staging/lustre/lustre/obdclass/genops.c | 3 - .../lustre/lustre/obdclass/lprocfs_status.c | 66 +++++- 5 files changed, 192 insertions(+), 123 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h index 5da26e3..c22ae3d 100644 --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h @@ -442,11 +442,12 @@ __u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx, lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags); void lprocfs_clear_stats(struct lprocfs_stats *stats); void lprocfs_free_stats(struct lprocfs_stats **stats); +int ldebugfs_alloc_md_stats(struct obd_device *obddev, + unsigned int num_private_stats); +void ldebugfs_free_md_stats(struct obd_device *obddev); void lprocfs_counter_init(struct lprocfs_stats *stats, int index, unsigned int conf, const char *name, const char *units); -struct obd_export; -int lprocfs_exp_cleanup(struct obd_export *exp); extern const struct file_operations lprocfs_stats_seq_fops; /* lprocfs_status.c */ diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 8691aec..6e78c50 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -599,8 +599,7 @@ struct obd_device { /* Fields used by LProcFS */ struct lprocfs_stats *obd_stats; - struct lprocfs_stats *md_stats; - unsigned int md_cntr_base; + struct lprocfs_stats *obd_md_stats; struct dentry *obd_debugfs_entry; struct dentry *obd_svc_debugfs_entry; @@ -1000,11 +999,6 @@ struct md_ops { int (*unpackmd)(struct obd_export *exp, struct lmv_stripe_md **plsm, const union lmv_mds_md *lmv, size_t lmv_size); - /* - * NOTE: If adding ops, add another LPROCFS_MD_OP_INIT() line to - * lprocfs_alloc_md_stats() in obdclass/lprocfs_status.c. Also, add a - * wrapper function in include/linux/obd_class.h. - */ }; static inline struct md_open_data *obd_mod_alloc(void) diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 0c1922e..2514b39 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -334,36 +334,6 @@ static inline int obd_check_dev_active(struct obd_device *obd) return rc; } -#define MD_COUNTER_OFFSET(op) \ - ((offsetof(struct md_ops, op) - \ - offsetof(struct md_ops, get_root)) \ - / sizeof(((struct md_ops *)(0))->get_root)) - -#define MD_COUNTER_INCREMENT(obdx, op) \ -do { \ - if ((obd)->md_stats) { \ - unsigned int coffset; \ - coffset = (unsigned int)((obdx)->md_cntr_base) + \ - MD_COUNTER_OFFSET(op); \ - LASSERT(coffset < (obdx)->md_stats->ls_num); \ - lprocfs_counter_incr((obdx)->md_stats, coffset); \ - } \ -} while (0) - -#define EXP_MD_COUNTER_INCREMENT(export, op) \ -do { \ - if ((export)->exp_obd->obd_stats) { \ - unsigned int coffset; \ - coffset = (unsigned int)((export)->exp_obd->md_cntr_base) + \ - MD_COUNTER_OFFSET(op); \ - LASSERT(coffset < (export)->exp_obd->md_stats->ls_num); \ - lprocfs_counter_incr((export)->exp_obd->md_stats, coffset); \ - if ((export)->exp_md_stats) \ - lprocfs_counter_incr( \ - (export)->exp_md_stats, coffset); \ - } \ -} while (0) - static inline int exp_check_ops(struct obd_export *exp) { if (!exp) @@ -1186,6 +1156,25 @@ static inline int obd_register_observer(struct obd_device *obd, } /* metadata helpers */ +enum mps_stat_idx { + LPROC_MD_CLOSE, + LPROC_MD_CREATE, + LPROC_MD_ENQUEUE, + LPROC_MD_GETATTR, + LPROC_MD_INTENT_LOCK, + LPROC_MD_LINK, + LPROC_MD_RENAME, + LPROC_MD_SETATTR, + LPROC_MD_FSYNC, + LPROC_MD_READ_PAGE, + LPROC_MD_UNLINK, + LPROC_MD_SETXATTR, + LPROC_MD_GETXATTR, + LPROC_MD_INTENT_GETATTR_ASYNC, + LPROC_MD_REVALIDATE_LOCK, + LPROC_MD_LAST_OPC, +}; + static inline int md_get_root(struct obd_export *exp, const char *fileset, struct lu_fid *fid) { @@ -1194,9 +1183,8 @@ static inline int md_get_root(struct obd_export *exp, const char *fileset, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, get_root); - rc = MDP(exp->exp_obd, get_root)(exp, fileset, fid); - return rc; + + return MDP(exp->exp_obd, get_root)(exp, fileset, fid); } static inline int md_getattr(struct obd_export *exp, struct md_op_data *op_data, @@ -1207,9 +1195,11 @@ static inline int md_getattr(struct obd_export *exp, struct md_op_data *op_data, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, getattr); - rc = MDP(exp->exp_obd, getattr)(exp, op_data, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_GETATTR); + + return MDP(exp->exp_obd, getattr)(exp, op_data, request); } static inline int md_null_inode(struct obd_export *exp, @@ -1220,9 +1210,8 @@ static inline int md_null_inode(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, null_inode); - rc = MDP(exp->exp_obd, null_inode)(exp, fid); - return rc; + + return MDP(exp->exp_obd, null_inode)(exp, fid); } static inline int md_close(struct obd_export *exp, struct md_op_data *op_data, @@ -1234,25 +1223,29 @@ static inline int md_close(struct obd_export *exp, struct md_op_data *op_data, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, close); - rc = MDP(exp->exp_obd, close)(exp, op_data, mod, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_CLOSE); + + return MDP(exp->exp_obd, close)(exp, op_data, mod, request); } static inline int md_create(struct obd_export *exp, struct md_op_data *op_data, const void *data, size_t datalen, umode_t mode, uid_t uid, gid_t gid, kernel_cap_t cap_effective, - __u64 rdev, struct ptlrpc_request **request) + u64 rdev, struct ptlrpc_request **request) { int rc; rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, create); - rc = MDP(exp->exp_obd, create)(exp, op_data, data, datalen, mode, - uid, gid, cap_effective, rdev, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_CREATE); + + return MDP(exp->exp_obd, create)(exp, op_data, data, datalen, mode, + uid, gid, cap_effective, rdev, request); } static inline int md_enqueue(struct obd_export *exp, @@ -1260,17 +1253,19 @@ static inline int md_enqueue(struct obd_export *exp, const union ldlm_policy_data *policy, struct md_op_data *op_data, struct lustre_handle *lockh, - __u64 extra_lock_flags) + u64 extra_lock_flags) { int rc; rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, enqueue); - rc = MDP(exp->exp_obd, enqueue)(exp, einfo, policy, op_data, lockh, - extra_lock_flags); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_ENQUEUE); + + return MDP(exp->exp_obd, enqueue)(exp, einfo, policy, op_data, lockh, + extra_lock_flags); } static inline int md_getattr_name(struct obd_export *exp, @@ -1282,9 +1277,8 @@ static inline int md_getattr_name(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, getattr_name); - rc = MDP(exp->exp_obd, getattr_name)(exp, op_data, request); - return rc; + + return MDP(exp->exp_obd, getattr_name)(exp, op_data, request); } static inline int md_intent_lock(struct obd_export *exp, @@ -1292,17 +1286,19 @@ static inline int md_intent_lock(struct obd_export *exp, struct lookup_intent *it, struct ptlrpc_request **reqp, ldlm_blocking_callback cb_blocking, - __u64 extra_lock_flags) + u64 extra_lock_flags) { int rc; rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, intent_lock); - rc = MDP(exp->exp_obd, intent_lock)(exp, op_data, it, reqp, - cb_blocking, extra_lock_flags); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_INTENT_LOCK); + + return MDP(exp->exp_obd, intent_lock)(exp, op_data, it, reqp, + cb_blocking, extra_lock_flags); } static inline int md_link(struct obd_export *exp, struct md_op_data *op_data, @@ -1313,24 +1309,29 @@ static inline int md_link(struct obd_export *exp, struct md_op_data *op_data, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, link); - rc = MDP(exp->exp_obd, link)(exp, op_data, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_LINK); + + return MDP(exp->exp_obd, link)(exp, op_data, request); } static inline int md_rename(struct obd_export *exp, struct md_op_data *op_data, - const char *old, size_t oldlen, const char *new, - size_t newlen, struct ptlrpc_request **request) + const char *old_name, size_t oldlen, + const char *new_name, size_t newlen, + struct ptlrpc_request **request) { int rc; rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, rename); - rc = MDP(exp->exp_obd, rename)(exp, op_data, old, oldlen, new, - newlen, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_RENAME); + + return MDP(exp->exp_obd, rename)(exp, op_data, old_name, oldlen, + new_name, newlen, request); } static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data, @@ -1342,9 +1343,11 @@ static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, setattr); - rc = MDP(exp->exp_obd, setattr)(exp, op_data, ea, ealen, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_SETATTR); + + return MDP(exp->exp_obd, setattr)(exp, op_data, ea, ealen, request); } static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid, @@ -1355,15 +1358,17 @@ static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, sync); - rc = MDP(exp->exp_obd, sync)(exp, fid, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_FSYNC); + + return MDP(exp->exp_obd, sync)(exp, fid, request); } static inline int md_read_page(struct obd_export *exp, struct md_op_data *op_data, struct md_callback *cb_op, - __u64 hash_offset, + u64 hash_offset, struct page **ppage) { int rc; @@ -1371,10 +1376,12 @@ static inline int md_read_page(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, read_page); - rc = MDP(exp->exp_obd, read_page)(exp, op_data, cb_op, hash_offset, - ppage); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_READ_PAGE); + + return MDP(exp->exp_obd, read_page)(exp, op_data, cb_op, hash_offset, + ppage); } static inline int md_unlink(struct obd_export *exp, struct md_op_data *op_data, @@ -1385,9 +1392,11 @@ static inline int md_unlink(struct obd_export *exp, struct md_op_data *op_data, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, unlink); - rc = MDP(exp->exp_obd, unlink)(exp, op_data, request); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_UNLINK); + + return MDP(exp->exp_obd, unlink)(exp, op_data, request); } static inline int md_get_lustre_md(struct obd_export *exp, @@ -1401,7 +1410,7 @@ static inline int md_get_lustre_md(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, get_lustre_md); + return MDP(exp->exp_obd, get_lustre_md)(exp, req, dt_exp, md_exp, md); } @@ -1413,7 +1422,7 @@ static inline int md_free_lustre_md(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, free_lustre_md); + return MDP(exp->exp_obd, free_lustre_md)(exp, md); } @@ -1427,7 +1436,7 @@ static inline int md_merge_attr(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, merge_attr); + return MDP(exp->exp_obd, merge_attr)(exp, lsm, attr, cb); } @@ -1442,7 +1451,10 @@ static inline int md_setxattr(struct obd_export *exp, const struct lu_fid *fid, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, setxattr); + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_SETXATTR); + return MDP(exp->exp_obd, setxattr)(exp, fid, obd_md_valid, name, value, value_size, xattr_flags, suppgid, request); @@ -1457,7 +1469,10 @@ static inline int md_getxattr(struct obd_export *exp, const struct lu_fid *fid, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, getxattr); + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_GETXATTR); + return MDP(exp->exp_obd, getxattr)(exp, fid, obd_md_valid, name, buf_size, req); } @@ -1471,7 +1486,7 @@ static inline int md_set_open_replay_data(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, set_open_replay_data); + return MDP(exp->exp_obd, set_open_replay_data)(exp, och, it); } @@ -1483,7 +1498,7 @@ static inline int md_clear_open_replay_data(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, clear_open_replay_data); + return MDP(exp->exp_obd, clear_open_replay_data)(exp, och); } @@ -1496,7 +1511,7 @@ static inline int md_set_lock_data(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, set_lock_data); + return MDP(exp->exp_obd, set_lock_data)(exp, lockh, data, bits); } @@ -1512,11 +1527,9 @@ static inline int md_cancel_unused(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, cancel_unused); - rc = MDP(exp->exp_obd, cancel_unused)(exp, fid, policy, mode, - flags, opaque); - return rc; + return MDP(exp->exp_obd, cancel_unused)(exp, fid, policy, mode, + flags, opaque); } static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, @@ -1531,7 +1544,7 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, lock_match); + return MDP(exp->exp_obd, lock_match)(exp, flags, fid, type, policy, mode, lockh); } @@ -1544,7 +1557,7 @@ static inline int md_init_ea_size(struct obd_export *exp, u32 easize, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, init_ea_size); + return MDP(exp->exp_obd, init_ea_size)(exp, easize, def_asize); } @@ -1556,9 +1569,11 @@ static inline int md_intent_getattr_async(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, intent_getattr_async); - rc = MDP(exp->exp_obd, intent_getattr_async)(exp, minfo); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_INTENT_GETATTR_ASYNC); + + return MDP(exp->exp_obd, intent_getattr_async)(exp, minfo); } static inline int md_revalidate_lock(struct obd_export *exp, @@ -1570,9 +1585,11 @@ static inline int md_revalidate_lock(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, revalidate_lock); - rc = MDP(exp->exp_obd, revalidate_lock)(exp, it, fid, bits); - return rc; + + lprocfs_counter_incr(exp->exp_obd->obd_md_stats, + LPROC_MD_REVALIDATE_LOCK); + + return MDP(exp->exp_obd, revalidate_lock)(exp, it, fid, bits); } static inline int md_get_fid_from_lsm(struct obd_export *exp, @@ -1585,9 +1602,8 @@ static inline int md_get_fid_from_lsm(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, get_fid_from_lsm); - rc = MDP(exp->exp_obd, get_fid_from_lsm)(exp, lsm, name, namelen, fid); - return rc; + + return MDP(exp->exp_obd, get_fid_from_lsm)(exp, lsm, name, namelen, fid); } /* @@ -1606,9 +1622,8 @@ static inline int md_unpackmd(struct obd_export *exp, rc = exp_check_ops(exp); if (rc) return rc; - EXP_MD_COUNTER_INCREMENT(exp, unpackmd); - rc = MDP(exp->exp_obd, unpackmd)(exp, plsm, lmm, lmm_size); - return rc; + + return MDP(exp->exp_obd, unpackmd)(exp, plsm, lmm, lmm_size); } /* OBD Metadata Support */ diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c index 29ed498..59891a8 100644 --- a/drivers/staging/lustre/lustre/obdclass/genops.c +++ b/drivers/staging/lustre/lustre/obdclass/genops.c @@ -712,9 +712,6 @@ void class_export_put(struct obd_export *exp) CDEBUG(D_IOCTL, "final put %p/%s\n", exp, exp->exp_client_uuid.uuid); - /* release nid stat refererence */ - lprocfs_exp_cleanup(exp); - obd_zombie_export_add(exp); } } diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index a540abb..dc1d540 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -1403,11 +1403,73 @@ void lprocfs_counter_init(struct lprocfs_stats *stats, int index, } EXPORT_SYMBOL(lprocfs_counter_init); -int lprocfs_exp_cleanup(struct obd_export *exp) +static const char * const mps_stats[] = { + [LPROC_MD_CLOSE] = "close", + [LPROC_MD_CREATE] = "create", + [LPROC_MD_ENQUEUE] = "enqueue", + [LPROC_MD_GETATTR] = "getattr", + [LPROC_MD_INTENT_LOCK] = "intent_lock", + [LPROC_MD_LINK] = "link", + [LPROC_MD_RENAME] = "rename", + [LPROC_MD_SETATTR] = "setattr", + [LPROC_MD_FSYNC] = "fsync", + [LPROC_MD_READ_PAGE] = "read_page", + [LPROC_MD_UNLINK] = "unlink", + [LPROC_MD_SETXATTR] = "setxattr", + [LPROC_MD_GETXATTR] = "getxattr", + [LPROC_MD_INTENT_GETATTR_ASYNC] = "intent_getattr_async", + [LPROC_MD_REVALIDATE_LOCK] = "revalidate_lock", +}; + +int ldebugfs_alloc_md_stats(struct obd_device *obd, + unsigned int num_private_stats) { + struct lprocfs_stats *stats; + unsigned int num_stats; + int i; + + /* No obd device debugfs tree to attach too */ + if (!obd->obd_debugfs_entry) { + CWARN("%s: missing debugfs tree for registering md_stats.\n", + obd->obd_name); + return 0; + } + + if (obd->obd_md_stats) + return -EINVAL; + + num_stats = ARRAY_SIZE(mps_stats) + num_private_stats; + stats = lprocfs_alloc_stats(num_stats, 0); + if (!stats) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(mps_stats); i++) { + lprocfs_counter_init(stats, i, 0, mps_stats[i], "reqs"); + if (!stats->ls_cnt_header[i].lc_name) { + CERROR("Missing md_stat initializer md_op operation at offset %d. Aborting.\n", + i); + LBUG(); + } + } + obd->obd_md_stats = stats; + + debugfs_create_file("md_stats", 0644, obd->obd_debugfs_entry, + obd->obd_md_stats, &lprocfs_stats_seq_fops); return 0; } -EXPORT_SYMBOL(lprocfs_exp_cleanup); +EXPORT_SYMBOL(ldebugfs_alloc_md_stats); + +void ldebugfs_free_md_stats(struct obd_device *obd) +{ + struct lprocfs_stats *stats = obd->obd_md_stats; + + if (!stats) + return; + + obd->obd_md_stats = NULL; + lprocfs_free_stats(&stats); +} +EXPORT_SYMBOL(ldebugfs_free_md_stats); __s64 lprocfs_read_helper(struct lprocfs_counter *lc, struct lprocfs_counter_header *header, -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:14 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:14 -0400 Subject: [lustre-devel] [PATCH 1/8] lustre: obdclass: remove CL_PAGE_INVOKE et. al. In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-2-git-send-email-jsimmons@infradead.org> From: Ben Evans CL_PAGE_INVOKE, CL_PAGE_INVOID and CL_PAGE_INVOKE_REVERSE merely obscure the list_for_each_entry calls to various virtual functions specified by CL_PAGE_OP, and arguments stuck into va_args. These defines and their equivalent functions have been removed, and the list_for_each_entry has been put in place. CL_PAGE_OP has also been removed. Signed-off-by: Ben Evans WC-bug-id: https://jira.whamcloud.com/browse/LU-9523 Reviewed-on: https://review.whamcloud.com/27168 Reviewed-by: Jinshan Xiong Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/obdclass/cl_page.c | 275 ++++++++++++----------- 1 file changed, 140 insertions(+), 135 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 916cf81..00df94b 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -363,82 +363,6 @@ const struct cl_page_slice *cl_page_at(const struct cl_page *page, } EXPORT_SYMBOL(cl_page_at); -#define CL_PAGE_OP(opname) offsetof(struct cl_page_operations, opname) - -#define CL_PAGE_INVOKE(_env, _page, _op, _proto, ...) \ -({ \ - const struct lu_env *__env = (_env); \ - struct cl_page *__page = (_page); \ - const struct cl_page_slice *__scan; \ - int __result; \ - ptrdiff_t __op = (_op); \ - int (*__method)_proto; \ - \ - __result = 0; \ - list_for_each_entry(__scan, &__page->cp_layers, cpl_linkage) { \ - __method = *(void **)((char *)__scan->cpl_ops + __op); \ - if (__method) { \ - __result = (*__method)(__env, __scan, ## __VA_ARGS__); \ - if (__result != 0) \ - break; \ - } \ - } \ - if (__result > 0) \ - __result = 0; \ - __result; \ -}) - -#define CL_PAGE_INVOID(_env, _page, _op, _proto, ...) \ -do { \ - const struct lu_env *__env = (_env); \ - struct cl_page *__page = (_page); \ - const struct cl_page_slice *__scan; \ - ptrdiff_t __op = (_op); \ - void (*__method)_proto; \ - \ - list_for_each_entry(__scan, &__page->cp_layers, cpl_linkage) { \ - __method = *(void **)((char *)__scan->cpl_ops + __op); \ - if (__method) \ - (*__method)(__env, __scan, ## __VA_ARGS__); \ - } \ -} while (0) - -#define CL_PAGE_INVOID_REVERSE(_env, _page, _op, _proto, ...) \ -do { \ - const struct lu_env *__env = (_env); \ - struct cl_page *__page = (_page); \ - const struct cl_page_slice *__scan; \ - ptrdiff_t __op = (_op); \ - void (*__method)_proto; \ - \ - list_for_each_entry_reverse(__scan, &__page->cp_layers, cpl_linkage) { \ - __method = *(void **)((char *)__scan->cpl_ops + __op); \ - if (__method) \ - (*__method)(__env, __scan, ## __VA_ARGS__); \ - } \ -} while (0) - -static int cl_page_invoke(const struct lu_env *env, - struct cl_io *io, struct cl_page *page, ptrdiff_t op) - -{ - PINVRNT(env, page, cl_object_same(page->cp_obj, io->ci_obj)); - return CL_PAGE_INVOKE(env, page, op, - (const struct lu_env *, - const struct cl_page_slice *, struct cl_io *), - io); -} - -static void cl_page_invoid(const struct lu_env *env, - struct cl_io *io, struct cl_page *page, ptrdiff_t op) - -{ - PINVRNT(env, page, cl_object_same(page->cp_obj, io->ci_obj)); - CL_PAGE_INVOID(env, page, op, - (const struct lu_env *, - const struct cl_page_slice *, struct cl_io *), io); -} - static void cl_page_owner_clear(struct cl_page *page) { if (page->cp_owner) { @@ -456,6 +380,7 @@ static void cl_page_owner_set(struct cl_page *page) void cl_page_disown0(const struct lu_env *env, struct cl_io *io, struct cl_page *pg) { + const struct cl_page_slice *slice; enum cl_page_state state; state = pg->cp_state; @@ -470,10 +395,10 @@ void cl_page_disown0(const struct lu_env *env, * uppermost layer (llite), responsible for VFS/VM interaction runs * last and can release locks safely. */ - CL_PAGE_INVOID_REVERSE(env, pg, CL_PAGE_OP(cpo_disown), - (const struct lu_env *, - const struct cl_page_slice *, struct cl_io *), - io); + list_for_each_entry_reverse(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_disown) + (*slice->cpl_ops->cpo_disown)(env, slice, io); + } } /** @@ -511,7 +436,8 @@ int cl_page_is_owned(const struct cl_page *pg, const struct cl_io *io) static int cl_page_own0(const struct lu_env *env, struct cl_io *io, struct cl_page *pg, int nonblock) { - int result; + const struct cl_page_slice *slice; + int result = 0; PINVRNT(env, pg, !cl_page_is_owned(pg, io)); @@ -519,24 +445,31 @@ static int cl_page_own0(const struct lu_env *env, struct cl_io *io, if (pg->cp_state == CPS_FREEING) { result = -ENOENT; - } else { - result = CL_PAGE_INVOKE(env, pg, CL_PAGE_OP(cpo_own), - (const struct lu_env *, - const struct cl_page_slice *, - struct cl_io *, int), - io, nonblock); - if (result == 0) { - PASSERT(env, pg, !pg->cp_owner); - pg->cp_owner = cl_io_top(io); - cl_page_owner_set(pg); - if (pg->cp_state != CPS_FREEING) { - cl_page_state_set(env, pg, CPS_OWNED); - } else { - cl_page_disown0(env, io, pg); - result = -ENOENT; - } + goto out; + } + + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_own) + result = (*slice->cpl_ops->cpo_own)(env, slice, + io, nonblock); + if (result != 0) + break; + } + if (result > 0) + result = 0; + + if (result == 0) { + PASSERT(env, pg, !pg->cp_owner); + pg->cp_owner = cl_io_top(io); + cl_page_owner_set(pg); + if (pg->cp_state != CPS_FREEING) { + cl_page_state_set(env, pg, CPS_OWNED); + } else { + cl_page_disown0(env, io, pg); + result = -ENOENT; } } +out: PINVRNT(env, pg, ergo(result == 0, cl_page_invariant(pg))); return result; } @@ -577,11 +510,17 @@ int cl_page_own_try(const struct lu_env *env, struct cl_io *io, void cl_page_assume(const struct lu_env *env, struct cl_io *io, struct cl_page *pg) { + const struct cl_page_slice *slice; + PINVRNT(env, pg, cl_object_same(pg->cp_obj, io->ci_obj)); io = cl_io_top(io); - cl_page_invoid(env, io, pg, CL_PAGE_OP(cpo_assume)); + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_assume) + (*slice->cpl_ops->cpo_assume)(env, slice, io); + } + PASSERT(env, pg, !pg->cp_owner); pg->cp_owner = cl_io_top(io); cl_page_owner_set(pg); @@ -603,16 +542,19 @@ void cl_page_assume(const struct lu_env *env, void cl_page_unassume(const struct lu_env *env, struct cl_io *io, struct cl_page *pg) { + const struct cl_page_slice *slice; + PINVRNT(env, pg, cl_page_is_owned(pg, io)); PINVRNT(env, pg, cl_page_invariant(pg)); io = cl_io_top(io); cl_page_owner_clear(pg); cl_page_state_set(env, pg, CPS_CACHED); - CL_PAGE_INVOID_REVERSE(env, pg, CL_PAGE_OP(cpo_unassume), - (const struct lu_env *, - const struct cl_page_slice *, struct cl_io *), - io); + + list_for_each_entry_reverse(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_unassume) + (*slice->cpl_ops->cpo_unassume)(env, slice, io); + } } EXPORT_SYMBOL(cl_page_unassume); @@ -651,10 +593,15 @@ void cl_page_disown(const struct lu_env *env, void cl_page_discard(const struct lu_env *env, struct cl_io *io, struct cl_page *pg) { + const struct cl_page_slice *slice; + PINVRNT(env, pg, cl_page_is_owned(pg, io)); PINVRNT(env, pg, cl_page_invariant(pg)); - cl_page_invoid(env, io, pg, CL_PAGE_OP(cpo_discard)); + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_discard) + (*slice->cpl_ops->cpo_discard)(env, slice, io); + } } EXPORT_SYMBOL(cl_page_discard); @@ -665,18 +612,20 @@ void cl_page_discard(const struct lu_env *env, */ static void cl_page_delete0(const struct lu_env *env, struct cl_page *pg) { + const struct cl_page_slice *slice; + PASSERT(env, pg, pg->cp_state != CPS_FREEING); /* * Sever all ways to obtain new pointers to @pg. */ cl_page_owner_clear(pg); - cl_page_state_set0(env, pg, CPS_FREEING); - CL_PAGE_INVOID_REVERSE(env, pg, CL_PAGE_OP(cpo_delete), - (const struct lu_env *, - const struct cl_page_slice *)); + list_for_each_entry_reverse(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_delete) + (*slice->cpl_ops->cpo_delete)(env, slice); + } } /** @@ -721,10 +670,14 @@ void cl_page_delete(const struct lu_env *env, struct cl_page *pg) */ void cl_page_export(const struct lu_env *env, struct cl_page *pg, int uptodate) { + const struct cl_page_slice *slice; + PINVRNT(env, pg, cl_page_invariant(pg)); - CL_PAGE_INVOID(env, pg, CL_PAGE_OP(cpo_export), - (const struct lu_env *, - const struct cl_page_slice *, int), uptodate); + + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_export) + (*slice->cpl_ops->cpo_export)(env, slice, uptodate); + } } EXPORT_SYMBOL(cl_page_export); @@ -734,8 +687,8 @@ void cl_page_export(const struct lu_env *env, struct cl_page *pg, int uptodate) */ int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg) { - int result; const struct cl_page_slice *slice; + int result; slice = container_of(pg->cp_layers.next, const struct cl_page_slice, cpl_linkage); @@ -776,7 +729,8 @@ static void cl_page_io_start(const struct lu_env *env, int cl_page_prep(const struct lu_env *env, struct cl_io *io, struct cl_page *pg, enum cl_req_type crt) { - int result; + const struct cl_page_slice *slice; + int result = 0; PINVRNT(env, pg, cl_page_is_owned(pg, io)); PINVRNT(env, pg, cl_page_invariant(pg)); @@ -789,9 +743,19 @@ int cl_page_prep(const struct lu_env *env, struct cl_io *io, */ if (crt >= CRT_NR) return -EINVAL; - result = cl_page_invoke(env, io, pg, CL_PAGE_OP(io[crt].cpo_prep)); - if (result == 0) + + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_own) + result = (*slice->cpl_ops->io[crt].cpo_prep)(env, slice, + io); + if (result != 0) + break; + } + + if (result >= 0) { + result = 0; cl_page_io_start(env, pg, crt); + } CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", crt, result); return result; @@ -817,6 +781,7 @@ void cl_page_completion(const struct lu_env *env, struct cl_page *pg, enum cl_req_type crt, int ioret) { struct cl_sync_io *anchor = pg->cp_sync_io; + const struct cl_page_slice *slice; PASSERT(env, pg, crt < CRT_NR); PASSERT(env, pg, pg->cp_state == cl_req_type_state(crt)); @@ -826,9 +791,13 @@ void cl_page_completion(const struct lu_env *env, cl_page_state_set(env, pg, CPS_CACHED); if (crt >= CRT_NR) return; - CL_PAGE_INVOID_REVERSE(env, pg, CL_PAGE_OP(io[crt].cpo_completion), - (const struct lu_env *, - const struct cl_page_slice *, int), ioret); + + list_for_each_entry_reverse(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->io[crt].cpo_completion) + (*slice->cpl_ops->io[crt].cpo_completion)(env, slice, + ioret); + } + if (anchor) { LASSERT(pg->cp_sync_io == anchor); pg->cp_sync_io = NULL; @@ -849,18 +818,26 @@ void cl_page_completion(const struct lu_env *env, int cl_page_make_ready(const struct lu_env *env, struct cl_page *pg, enum cl_req_type crt) { - int result; + const struct cl_page_slice *sli; + int result = 0; PINVRNT(env, pg, crt < CRT_NR); if (crt >= CRT_NR) return -EINVAL; - result = CL_PAGE_INVOKE(env, pg, CL_PAGE_OP(io[crt].cpo_make_ready), - (const struct lu_env *, - const struct cl_page_slice *)); - if (result == 0) { + + list_for_each_entry(sli, &pg->cp_layers, cpl_linkage) { + if (sli->cpl_ops->io[crt].cpo_make_ready) + result = (*sli->cpl_ops->io[crt].cpo_make_ready)(env, + sli); + if (result != 0) + break; + } + + if (result >= 0) { PASSERT(env, pg, pg->cp_state == CPS_CACHED); cl_page_io_start(env, pg, crt); + result = 0; } CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", crt, result); return result; @@ -878,12 +855,20 @@ int cl_page_make_ready(const struct lu_env *env, struct cl_page *pg, int cl_page_flush(const struct lu_env *env, struct cl_io *io, struct cl_page *pg) { - int result; + const struct cl_page_slice *slice; + int result = 0; PINVRNT(env, pg, cl_page_is_owned(pg, io)); PINVRNT(env, pg, cl_page_invariant(pg)); - result = cl_page_invoke(env, io, pg, CL_PAGE_OP(cpo_flush)); + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_flush) + result = (*slice->cpl_ops->cpo_flush)(env, slice, io); + if (result != 0) + break; + } + if (result > 0) + result = 0; CL_PAGE_HEADER(D_TRACE, env, pg, "%d\n", result); return result; @@ -898,13 +883,16 @@ int cl_page_flush(const struct lu_env *env, struct cl_io *io, void cl_page_clip(const struct lu_env *env, struct cl_page *pg, int from, int to) { + const struct cl_page_slice *slice; + PINVRNT(env, pg, cl_page_invariant(pg)); CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", from, to); - CL_PAGE_INVOID(env, pg, CL_PAGE_OP(cpo_clip), - (const struct lu_env *, - const struct cl_page_slice *, int, int), - from, to); + + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_clip) + (*slice->cpl_ops->cpo_clip)(env, slice, from, to); + } } EXPORT_SYMBOL(cl_page_clip); @@ -928,11 +916,18 @@ void cl_page_header_print(const struct lu_env *env, void *cookie, void cl_page_print(const struct lu_env *env, void *cookie, lu_printer_t printer, const struct cl_page *pg) { + const struct cl_page_slice *slice; + int result = 0; + cl_page_header_print(env, cookie, printer, pg); - CL_PAGE_INVOKE(env, (struct cl_page *)pg, CL_PAGE_OP(cpo_print), - (const struct lu_env *env, - const struct cl_page_slice *slice, - void *cookie, lu_printer_t p), cookie, printer); + + list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_print) + result = (*slice->cpl_ops->cpo_print)(env, slice, + cookie, printer); + if (result != 0) + break; + } (*printer)(env, cookie, "end page@%p\n", pg); } EXPORT_SYMBOL(cl_page_print); @@ -942,9 +937,19 @@ void cl_page_print(const struct lu_env *env, void *cookie, */ int cl_page_cancel(const struct lu_env *env, struct cl_page *page) { - return CL_PAGE_INVOKE(env, page, CL_PAGE_OP(cpo_cancel), - (const struct lu_env *, - const struct cl_page_slice *)); + const struct cl_page_slice *slice; + int result = 0; + + list_for_each_entry(slice, &page->cp_layers, cpl_linkage) { + if (slice->cpl_ops->cpo_cancel) + result = (*slice->cpl_ops->cpo_cancel)(env, slice); + if (result != 0) + break; + } + if (result > 0) + result = 0; + + return result; } /** -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:17 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:17 -0400 Subject: [lustre-devel] [PATCH 4/8] lustre: obdclass: cleanup obd_class.h defines In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-5-git-send-email-jsimmons@infradead.org> From: Ben Evans Get rid of OBT and CTXTP defines. Remove OBD_CHECK_DT_OP Convert EXP_CHECK_MD_OP into a function. Remove CTXT_CHECK_OP. Signed-off-by: Ben Evans Signed-off-by: Alexey Lyashkov WC-bug-id: https://jira.whamcloud.com/browse/LU-9855 Reviewed-on: https://review.whamcloud.com/29286 WC-bug-id: https://jira.whamcloud.com/browse/LU-11169 Reviewed-on: https://review.whamcloud.com/#/c/32906 Reviewed-by: John L. Hammond Reviewed-by: Steve Guminski Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/obd_class.h | 437 +++++++++++++++------- drivers/staging/lustre/lustre/obdclass/llog_obd.c | 4 +- 2 files changed, 311 insertions(+), 130 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index c6fb2e1..aab1092 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -303,10 +303,8 @@ static inline int lprocfs_climp_check(struct obd_device *obd) void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj); -#define OBT(dev) ((dev)->obd_type) #define OBP(dev, op) ((dev)->obd_type->typ_dt_ops->op) #define MDP(dev, op) ((dev)->obd_type->typ_md_ops->op) -#define CTXTP(ctxt, op) ((ctxt)->loc_logops->lop_##op) /* * Ensure obd_setup: used for cleanup which must be called @@ -393,56 +391,16 @@ static inline int obd_check_dev_active(struct obd_device *obd) } \ } while (0) -#define EXP_CHECK_MD_OP(exp, op) \ -do { \ - if (!(exp)) { \ - CERROR("obd_" #op ": NULL export\n"); \ - return -ENODEV; \ - } \ - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ - CERROR("obd_" #op ": cleaned up obd\n"); \ - return -EOPNOTSUPP; \ - } \ - if (!OBT((exp)->exp_obd) || !MDP((exp)->exp_obd, op)) { \ - CERROR("%s: obd_" #op ": dev %d no operation\n",\ - (exp)->exp_obd->obd_name, \ - (exp)->exp_obd->obd_minor); \ - return -EOPNOTSUPP; \ - } \ -} while (0) - -#define OBD_CHECK_DT_OP(obd, op, err) \ -do { \ - if (!OBT(obd) || !OBP((obd), op)) { \ - if (err) \ - CERROR("%s: no obd_" #op " operation\n", \ - obd->obd_name); \ - return err; \ - } \ -} while (0) +static inline int exp_check_ops(struct obd_export *exp) +{ + if (!exp) + return -ENODEV; -#define EXP_CHECK_DT_OP(exp, op) \ -do { \ - if (!(exp)) { \ - CERROR("obd_" #op ": NULL export\n"); \ - return -ENODEV; \ - } \ - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ - CERROR("obd_" #op ": cleaned up obd\n"); \ - return -EOPNOTSUPP; \ - } \ - OBD_CHECK_DT_OP((exp)->exp_obd, op, -EOPNOTSUPP); \ -} while (0) + if (!exp->exp_obd || !exp->exp_obd->obd_type) + return -EOPNOTSUPP; -#define CTXT_CHECK_OP(ctxt, op, err) \ -do { \ - if (!OBT(ctxt->loc_obd) || !CTXTP((ctxt), op)) { \ - if (err) \ - CERROR("%s: no lop_" #op " operation\n", \ - ctxt->loc_obd->obd_name); \ - return err; \ - } \ -} while (0) + return 0; +} static inline int class_devno_max(void) { @@ -455,7 +413,15 @@ static inline int obd_get_info(const struct lu_env *env, { int rc; - EXP_CHECK_DT_OP(exp, get_info); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->get_info) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, get_info); rc = OBP(exp->exp_obd, get_info)(env, exp, keylen, key, vallen, val); @@ -469,7 +435,15 @@ static inline int obd_set_info_async(const struct lu_env *env, { int rc; - EXP_CHECK_DT_OP(exp, set_info_async); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->set_info_async) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, set_info_async); rc = OBP(exp->exp_obd, set_info_async)(env, exp, keylen, key, vallen, @@ -484,14 +458,14 @@ static inline int obd_set_info_async(const struct lu_env *env, * pieces of configuration process are still based on obd devices. * * Specifically, lu_device_type_operations::ldto_device_alloc() methods fully - * subsume ->o_setup() methods of obd devices they replace. The same for - * lu_device_operations::ldo_process_config() and ->o_process_config(). As a + * subsume ->setup() methods of obd devices they replace. The same for + * lu_device_operations::ldo_process_config() and ->process_config(). As a * result, obd_setup() and obd_process_config() branch and call one XOR * another. * * Yet neither lu_device_type_operations::ldto_device_fini() nor * lu_device_type_operations::ldto_device_free() fully implement the - * functionality of ->o_precleanup() and ->o_cleanup() they override. Hence, + * functionality of ->precleanup() and ->o_cleanup() they override. Hence, * obd_precleanup() and obd_cleanup() call both lu_device and obd operations. */ @@ -527,7 +501,11 @@ static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) lu_context_fini(&session_ctx); } else { - OBD_CHECK_DT_OP(obd, setup, -EOPNOTSUPP); + if (!obd->obd_type->typ_dt_ops->setup) { + CERROR("%s: no %s operation\n", obd->obd_name, + __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, setup); rc = OBP(obd, setup)(obd, cfg); } @@ -549,7 +527,9 @@ static inline int obd_precleanup(struct obd_device *obd) lu_env_fini(&env); } } - OBD_CHECK_DT_OP(obd, precleanup, 0); + if (!obd->obd_type->typ_dt_ops->precleanup) + return 0; + OBD_COUNTER_INCREMENT(obd, precleanup); rc = OBP(obd, precleanup)(obd); @@ -572,7 +552,9 @@ static inline int obd_cleanup(struct obd_device *obd) obd->obd_lu_dev = NULL; } } - OBD_CHECK_DT_OP(obd, cleanup, 0); + if (!obd->obd_type->typ_dt_ops->cleanup) + return 0; + OBD_COUNTER_INCREMENT(obd, cleanup); rc = OBP(obd, cleanup)(obd); @@ -599,8 +581,8 @@ static inline void obd_cleanup_client_import(struct obd_device *obd) up_write(&obd->u.cli.cl_sem); } -static inline int -obd_process_config(struct obd_device *obd, int datalen, void *data) +static inline int obd_process_config(struct obd_device *obd, int datalen, + void *data) { struct lu_device_type *ldt = obd->obd_type->typ_lu; struct lu_device *d = obd->obd_lu_dev; @@ -616,7 +598,11 @@ static inline void obd_cleanup_client_import(struct obd_device *obd) lu_env_fini(&env); } } else { - OBD_CHECK_DT_OP(obd, process_config, -EOPNOTSUPP); + if (!obd->obd_type->typ_dt_ops->process_config) { + CERROR("%s: no %s operation\n", + obd->obd_name, __func__); + return -EOPNOTSUPP; + } rc = OBP(obd, process_config)(obd, datalen, data); } OBD_COUNTER_INCREMENT(obd, process_config); @@ -630,7 +616,15 @@ static inline int obd_create(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, create); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->create) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, create); rc = OBP(exp->exp_obd, create)(env, exp, obdo); @@ -642,7 +636,15 @@ static inline int obd_destroy(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, destroy); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->destroy) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, destroy); rc = OBP(exp->exp_obd, destroy)(env, exp, obdo); @@ -654,7 +656,15 @@ static inline int obd_getattr(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, getattr); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->getattr) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, getattr); rc = OBP(exp->exp_obd, getattr)(env, exp, oa); @@ -666,7 +676,15 @@ static inline int obd_setattr(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, setattr); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->setattr) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, setattr); rc = OBP(exp->exp_obd, setattr)(env, exp, oa); @@ -682,7 +700,11 @@ static inline int obd_add_conn(struct obd_import *imp, struct obd_uuid *uuid, rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, add_conn, -EOPNOTSUPP); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->add_conn) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, add_conn); rc = OBP(obd, add_conn)(imp, uuid, priority); @@ -697,7 +719,11 @@ static inline int obd_del_conn(struct obd_import *imp, struct obd_uuid *uuid) rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, del_conn, -EOPNOTSUPP); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->del_conn) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, del_conn); rc = OBP(obd, del_conn)(imp, uuid); @@ -708,7 +734,10 @@ static inline struct obd_uuid *obd_get_uuid(struct obd_export *exp) { struct obd_uuid *uuid; - OBD_CHECK_DT_OP(exp->exp_obd, get_uuid, NULL); + if (!exp->exp_obd->obd_type || + !exp->exp_obd->obd_type->typ_dt_ops->get_uuid) + return NULL; + EXP_COUNTER_INCREMENT(exp, get_uuid); uuid = OBP(exp->exp_obd, get_uuid)(exp); @@ -727,16 +756,18 @@ static inline int obd_connect(const struct lu_env *env, struct obd_connect_data *data, void *localdata) { + /* for post-condition check */ + u64 ocf = data ? data->ocd_connect_flags : 0; int rc; - __u64 ocf = data ? data->ocd_connect_flags : 0; /* - * for post-condition - * check - */ rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, connect, -EOPNOTSUPP); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->connect) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, connect); rc = OBP(obd, connect)(env, exp, obd, cluuid, data, localdata); @@ -753,13 +784,16 @@ static inline int obd_reconnect(const struct lu_env *env, struct obd_connect_data *d, void *localdata) { + u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition check */ int rc; - __u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition check */ rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, reconnect, 0); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->reconnect) + return 0; + OBD_COUNTER_INCREMENT(obd, reconnect); rc = OBP(obd, reconnect)(env, exp, obd, cluuid, d, localdata); @@ -772,7 +806,15 @@ static inline int obd_disconnect(struct obd_export *exp) { int rc; - EXP_CHECK_DT_OP(exp, disconnect); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->disconnect) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, disconnect); rc = OBP(exp->exp_obd, disconnect)(exp); @@ -784,7 +826,8 @@ static inline int obd_fid_init(struct obd_device *obd, struct obd_export *exp, { int rc; - OBD_CHECK_DT_OP(obd, fid_init, 0); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_init) + return 0; OBD_COUNTER_INCREMENT(obd, fid_init); rc = OBP(obd, fid_init)(obd, exp, type); @@ -795,7 +838,8 @@ static inline int obd_fid_fini(struct obd_device *obd) { int rc; - OBD_CHECK_DT_OP(obd, fid_fini, 0); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_fini) + return 0; OBD_COUNTER_INCREMENT(obd, fid_fini); rc = OBP(obd, fid_fini)(obd); @@ -809,7 +853,15 @@ static inline int obd_fid_alloc(const struct lu_env *env, { int rc; - EXP_CHECK_DT_OP(exp, fid_alloc); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->fid_alloc) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, fid_alloc); rc = OBP(exp->exp_obd, fid_alloc)(env, exp, fid, op_data); @@ -820,7 +872,10 @@ static inline int obd_pool_new(struct obd_device *obd, char *poolname) { int rc; - OBD_CHECK_DT_OP(obd, pool_new, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_new) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_new); rc = OBP(obd, pool_new)(obd, poolname); @@ -831,20 +886,25 @@ static inline int obd_pool_del(struct obd_device *obd, char *poolname) { int rc; - OBD_CHECK_DT_OP(obd, pool_del, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_del) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_del); rc = OBP(obd, pool_del)(obd, poolname); return rc; } -static inline int obd_pool_add(struct obd_device *obd, - char *poolname, +static inline int obd_pool_add(struct obd_device *obd, char *poolname, char *ostname) { int rc; - OBD_CHECK_DT_OP(obd, pool_add, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_add) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_add); rc = OBP(obd, pool_add)(obd, poolname, ostname); @@ -857,7 +917,10 @@ static inline int obd_pool_rem(struct obd_device *obd, { int rc; - OBD_CHECK_DT_OP(obd, pool_rem, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_rem) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_rem); rc = OBP(obd, pool_rem)(obd, poolname, ostname); @@ -866,7 +929,7 @@ static inline int obd_pool_rem(struct obd_device *obd, static inline void obd_getref(struct obd_device *obd) { - if (OBT(obd) && OBP(obd, getref)) { + if (obd->obd_type && OBP(obd, getref)) { OBD_COUNTER_INCREMENT(obd, getref); OBP(obd, getref)(obd); } @@ -874,7 +937,7 @@ static inline void obd_getref(struct obd_device *obd) static inline void obd_putref(struct obd_device *obd) { - if (OBT(obd) && OBP(obd, putref)) { + if (obd->obd_type && OBP(obd, putref)) { OBD_COUNTER_INCREMENT(obd, putref); OBP(obd, putref)(obd); } @@ -884,7 +947,7 @@ static inline int obd_init_export(struct obd_export *exp) { int rc = 0; - if ((exp)->exp_obd && OBT((exp)->exp_obd) && + if (exp->exp_obd && exp->exp_obd->obd_type && OBP((exp)->exp_obd, init_export)) rc = OBP(exp->exp_obd, init_export)(exp); return rc; @@ -892,7 +955,7 @@ static inline int obd_init_export(struct obd_export *exp) static inline int obd_destroy_export(struct obd_export *exp) { - if ((exp)->exp_obd && OBT((exp)->exp_obd) && + if (exp->exp_obd && exp->exp_obd->obd_type && OBP((exp)->exp_obd, destroy_export)) OBP(exp->exp_obd, destroy_export)(exp); return 0; @@ -915,7 +978,10 @@ static inline int obd_statfs_async(struct obd_export *exp, return -EINVAL; obd = exp->exp_obd; - OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->statfs) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, statfs); CDEBUG(D_SUPER, "%s: osfs %p age %llu, max_age %llu\n", @@ -969,13 +1035,16 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp, struct obd_statfs *osfs, __u64 max_age, __u32 flags) { - int rc = 0; struct obd_device *obd = exp->exp_obd; + int rc = 0; if (!obd) return -EINVAL; - OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->statfs) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, statfs); CDEBUG(D_SUPER, "osfs %llu, max_age %llu\n", @@ -1009,7 +1078,15 @@ static inline int obd_preprw(const struct lu_env *env, int cmd, { int rc; - EXP_CHECK_DT_OP(exp, preprw); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->preprw) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, preprw); rc = OBP(exp->exp_obd, preprw)(env, cmd, exp, oa, objcount, obj, remote, @@ -1021,13 +1098,23 @@ static inline int obd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int pages, - struct niobuf_local *local, int rc) + struct niobuf_local *local, int orig_rc) { - EXP_CHECK_DT_OP(exp, commitrw); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->commitrw) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, commitrw); rc = OBP(exp->exp_obd, commitrw)(env, cmd, exp, oa, objcount, obj, - rnb, pages, local, rc); + rnb, pages, local, orig_rc); return rc; } @@ -1036,7 +1123,15 @@ static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, iocontrol); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->iocontrol) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, iocontrol); rc = OBP(exp->exp_obd, iocontrol)(cmd, exp, len, karg, uarg); @@ -1108,7 +1203,15 @@ static inline int obd_quotactl(struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, quotactl); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->quotactl) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, quotactl); rc = OBP(exp->exp_obd, quotactl)(exp->exp_obd, exp, oqctl); @@ -1129,7 +1232,7 @@ static inline int obd_health_check(const struct lu_env *env, int rc; /* don't use EXP_CHECK_DT_OP, because NULL method is normal here */ - if (!obd || !OBT(obd)) { + if (!obd || !obd->obd_type) { CERROR("cleaned up obd\n"); return -EOPNOTSUPP; } @@ -1166,7 +1269,9 @@ static inline int md_get_root(struct obd_export *exp, const char *fileset, { int rc; - EXP_CHECK_MD_OP(exp, get_root); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, get_root); rc = MDP(exp->exp_obd, get_root)(exp, fileset, fid); return rc; @@ -1177,7 +1282,9 @@ static inline int md_getattr(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, getattr); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, getattr); rc = MDP(exp->exp_obd, getattr)(exp, op_data, request); return rc; @@ -1188,7 +1295,9 @@ static inline int md_null_inode(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, null_inode); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, null_inode); rc = MDP(exp->exp_obd, null_inode)(exp, fid); return rc; @@ -1200,7 +1309,9 @@ static inline int md_close(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, close); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, close); rc = MDP(exp->exp_obd, close)(exp, op_data, mod, request); return rc; @@ -1213,7 +1324,9 @@ static inline int md_create(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, create); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, create); rc = MDP(exp->exp_obd, create)(exp, op_data, data, datalen, mode, uid, gid, cap_effective, rdev, request); @@ -1229,7 +1342,9 @@ static inline int md_enqueue(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, enqueue); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, enqueue); rc = MDP(exp->exp_obd, enqueue)(exp, einfo, policy, op_data, lockh, extra_lock_flags); @@ -1242,7 +1357,9 @@ static inline int md_getattr_name(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, getattr_name); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, getattr_name); rc = MDP(exp->exp_obd, getattr_name)(exp, op_data, request); return rc; @@ -1257,7 +1374,9 @@ static inline int md_intent_lock(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, intent_lock); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, intent_lock); rc = MDP(exp->exp_obd, intent_lock)(exp, op_data, it, reqp, cb_blocking, extra_lock_flags); @@ -1269,7 +1388,9 @@ static inline int md_link(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, link); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, link); rc = MDP(exp->exp_obd, link)(exp, op_data, request); return rc; @@ -1281,7 +1402,9 @@ static inline int md_rename(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, rename); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, rename); rc = MDP(exp->exp_obd, rename)(exp, op_data, old, oldlen, new, newlen, request); @@ -1294,7 +1417,9 @@ static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, setattr); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, setattr); rc = MDP(exp->exp_obd, setattr)(exp, op_data, ea, ealen, request); return rc; @@ -1305,7 +1430,9 @@ static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid, { int rc; - EXP_CHECK_MD_OP(exp, sync); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, sync); rc = MDP(exp->exp_obd, sync)(exp, fid, request); return rc; @@ -1319,7 +1446,9 @@ static inline int md_read_page(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, read_page); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, read_page); rc = MDP(exp->exp_obd, read_page)(exp, op_data, cb_op, hash_offset, ppage); @@ -1331,7 +1460,9 @@ static inline int md_unlink(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, unlink); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, unlink); rc = MDP(exp->exp_obd, unlink)(exp, op_data, request); return rc; @@ -1343,7 +1474,11 @@ static inline int md_get_lustre_md(struct obd_export *exp, struct obd_export *md_exp, struct lustre_md *md) { - EXP_CHECK_MD_OP(exp, get_lustre_md); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, get_lustre_md); return MDP(exp->exp_obd, get_lustre_md)(exp, req, dt_exp, md_exp, md); } @@ -1351,7 +1486,11 @@ static inline int md_get_lustre_md(struct obd_export *exp, static inline int md_free_lustre_md(struct obd_export *exp, struct lustre_md *md) { - EXP_CHECK_MD_OP(exp, free_lustre_md); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, free_lustre_md); return MDP(exp->exp_obd, free_lustre_md)(exp, md); } @@ -1361,7 +1500,11 @@ static inline int md_merge_attr(struct obd_export *exp, struct cl_attr *attr, ldlm_blocking_callback cb) { - EXP_CHECK_MD_OP(exp, merge_attr); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, merge_attr); return MDP(exp->exp_obd, merge_attr)(exp, lsm, attr, cb); } @@ -1372,7 +1515,11 @@ static inline int md_setxattr(struct obd_export *exp, const struct lu_fid *fid, unsigned int xattr_flags, u32 suppgid, struct ptlrpc_request **request) { - EXP_CHECK_MD_OP(exp, setxattr); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, setxattr); return MDP(exp->exp_obd, setxattr)(exp, fid, obd_md_valid, name, value, value_size, xattr_flags, @@ -1383,7 +1530,11 @@ static inline int md_getxattr(struct obd_export *exp, const struct lu_fid *fid, u64 obd_md_valid, const char *name, size_t buf_size, struct ptlrpc_request **req) { - EXP_CHECK_MD_OP(exp, getxattr); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, getxattr); return MDP(exp->exp_obd, getxattr)(exp, fid, obd_md_valid, name, buf_size, req); @@ -1393,7 +1544,11 @@ static inline int md_set_open_replay_data(struct obd_export *exp, struct obd_client_handle *och, struct lookup_intent *it) { - EXP_CHECK_MD_OP(exp, set_open_replay_data); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, set_open_replay_data); return MDP(exp->exp_obd, set_open_replay_data)(exp, och, it); } @@ -1401,7 +1556,11 @@ static inline int md_set_open_replay_data(struct obd_export *exp, static inline int md_clear_open_replay_data(struct obd_export *exp, struct obd_client_handle *och) { - EXP_CHECK_MD_OP(exp, clear_open_replay_data); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, clear_open_replay_data); return MDP(exp->exp_obd, clear_open_replay_data)(exp, och); } @@ -1410,7 +1569,11 @@ static inline int md_set_lock_data(struct obd_export *exp, const struct lustre_handle *lockh, void *data, __u64 *bits) { - EXP_CHECK_MD_OP(exp, set_lock_data); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, set_lock_data); return MDP(exp->exp_obd, set_lock_data)(exp, lockh, data, bits); } @@ -1424,7 +1587,9 @@ static inline int md_cancel_unused(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, cancel_unused); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, cancel_unused); rc = MDP(exp->exp_obd, cancel_unused)(exp, fid, policy, mode, @@ -1439,7 +1604,11 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, enum ldlm_mode mode, struct lustre_handle *lockh) { - EXP_CHECK_MD_OP(exp, lock_match); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, lock_match); return MDP(exp->exp_obd, lock_match)(exp, flags, fid, type, policy, mode, lockh); @@ -1448,7 +1617,11 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, static inline int md_init_ea_size(struct obd_export *exp, u32 easize, u32 def_asize) { - EXP_CHECK_MD_OP(exp, init_ea_size); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, init_ea_size); return MDP(exp->exp_obd, init_ea_size)(exp, easize, def_asize); } @@ -1458,7 +1631,9 @@ static inline int md_intent_getattr_async(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, intent_getattr_async); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, intent_getattr_async); rc = MDP(exp->exp_obd, intent_getattr_async)(exp, minfo); return rc; @@ -1470,7 +1645,9 @@ static inline int md_revalidate_lock(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, revalidate_lock); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, revalidate_lock); rc = MDP(exp->exp_obd, revalidate_lock)(exp, it, fid, bits); return rc; @@ -1483,7 +1660,9 @@ static inline int md_get_fid_from_lsm(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, get_fid_from_lsm); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, get_fid_from_lsm); rc = MDP(exp->exp_obd, get_fid_from_lsm)(exp, lsm, name, namelen, fid); return rc; @@ -1502,7 +1681,9 @@ static inline int md_unpackmd(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, unpackmd); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, unpackmd); rc = MDP(exp->exp_obd, unpackmd)(exp, plsm, lmm, lmm_size); return rc; diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c index 26aea11..e074b6e 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c @@ -93,8 +93,8 @@ int __llog_ctxt_put(const struct lu_env *env, struct llog_ctxt *ctxt) !!obd->obd_stopping, !!obd->obd_set_up); /* cleanup the llog ctxt here */ - if (CTXTP(ctxt, cleanup)) - rc = CTXTP(ctxt, cleanup)(env, ctxt); + if (ctxt->loc_logops->lop_cleanup) + rc = ctxt->loc_logops->lop_cleanup(env, ctxt); llog_ctxt_destroy(ctxt); wake_up(&olg->olg_waitq); -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:13 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:13 -0400 Subject: [lustre-devel] [PATCH 0/8] lustre: obd: preprocessor cleanups Message-ID: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> The obd.h, obd_class.h, and clio headers are littered with complex macros that are difficult to read. These macros existed to handle the obd stats and md stats which are lacking in the linux client. Newer versions do support md_stats so lets restore them as well as cleanup the ugly macros. This patch set is order dependent and is based on the first batch patch set for lustre 2.10 applied against the lustre-testing branch. Ben Evans (4): lustre: obdclass: remove CL_PAGE_INVOKE et. al. lustre: obdclass: remove cl_for_each defines lustre: obdclass: Code cleanup lustre: obdclass: cleanup obd_class.h defines James Simmons (1): lustre: obdclass: restore md_stats code John L. Hammond (3): lustre: obd: remove obd_{get,put}ref() lustre: obd: remove OBD ops based stats lustre: obd: add md_stats to MDC and LMV devices .../staging/lustre/lustre/include/lprocfs_status.h | 5 +- drivers/staging/lustre/lustre/include/obd.h | 20 +- drivers/staging/lustre/lustre/include/obd_class.h | 788 ++++++++++++--------- drivers/staging/lustre/lustre/llite/file.c | 2 +- drivers/staging/lustre/lustre/llite/llite_lib.c | 3 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 9 +- drivers/staging/lustre/lustre/lmv/lproc_lmv.c | 6 + drivers/staging/lustre/lustre/lov/lov_dev.c | 12 +- drivers/staging/lustre/lustre/lov/lov_internal.h | 2 + drivers/staging/lustre/lustre/lov/lov_obd.c | 44 +- drivers/staging/lustre/lustre/lov/lov_pool.c | 10 +- drivers/staging/lustre/lustre/lov/lov_request.c | 4 +- drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 7 + drivers/staging/lustre/lustre/mdc/mdc_request.c | 8 +- drivers/staging/lustre/lustre/obdclass/Makefile | 5 +- drivers/staging/lustre/lustre/obdclass/cl_io.c | 26 +- drivers/staging/lustre/lustre/obdclass/cl_object.c | 21 +- drivers/staging/lustre/lustre/obdclass/cl_page.c | 275 +++---- drivers/staging/lustre/lustre/obdclass/class_obd.c | 1 - drivers/staging/lustre/lustre/obdclass/genops.c | 3 - .../staging/lustre/lustre/obdclass/kernelcomm.c | 7 +- drivers/staging/lustre/lustre/obdclass/llog_obd.c | 4 +- .../lustre/lustre/obdclass/lprocfs_status.c | 66 +- drivers/staging/lustre/lustre/obdclass/obd_mount.c | 2 +- drivers/staging/lustre/lustre/obdclass/uuid.c | 45 -- 25 files changed, 753 insertions(+), 622 deletions(-) delete mode 100644 drivers/staging/lustre/lustre/obdclass/uuid.c -- 1.8.3.1 From jsimmons at infradead.org Mon Sep 17 17:31:15 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 17 Sep 2018 13:31:15 -0400 Subject: [lustre-devel] [PATCH 2/8] lustre: obdclass: remove cl_for_each defines In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537205481-6899-3-git-send-email-jsimmons@infradead.org> From: Ben Evans cl_for_each and cl_for_each_reverse are simply aliases for list_for_each_entry and list_for_each_entry_reverse There is no point to them so just get rid of them and eliminate any confusion. Signed-off-by: Ben Evans WC-bug-id: https://jira.whamcloud.com/browse/LU-9575 Reviewed-on: https://review.whamcloud.com/27385 Reviewed-by: Dmitry Eremin Reviewed-by: James Simmons Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/obdclass/cl_io.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 3a96d4a..879383ae 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -52,11 +52,6 @@ * */ -#define cl_io_for_each(slice, io) \ - list_for_each_entry((slice), &io->ci_layers, cis_linkage) -#define cl_io_for_each_reverse(slice, io) \ - list_for_each_entry_reverse((slice), &io->ci_layers, cis_linkage) - static inline int cl_io_type_is_valid(enum cl_io_type type) { return CIT_READ <= type && type < CIT_OP_NR; @@ -343,13 +338,14 @@ int cl_io_lock(const struct lu_env *env, struct cl_io *io) LINVRNT(io->ci_state == CIS_IT_STARTED); LINVRNT(cl_io_invariant(io)); - cl_io_for_each(scan, io) { + list_for_each_entry(scan, &io->ci_layers, cis_linkage) { if (!scan->cis_iop->op[io->ci_type].cio_lock) continue; result = scan->cis_iop->op[io->ci_type].cio_lock(env, scan); if (result != 0) break; } + if (result == 0) { cl_io_locks_sort(io); result = cl_lockset_lock(env, io, &io->ci_lockset); @@ -391,7 +387,7 @@ void cl_io_unlock(const struct lu_env *env, struct cl_io *io) link->cill_fini(env, link); } - cl_io_for_each_reverse(scan, io) { + list_for_each_entry_reverse(scan, &io->ci_layers, cis_linkage) { if (scan->cis_iop->op[io->ci_type].cio_unlock) scan->cis_iop->op[io->ci_type].cio_unlock(env, scan); } @@ -416,7 +412,7 @@ int cl_io_iter_init(const struct lu_env *env, struct cl_io *io) LINVRNT(cl_io_invariant(io)); result = 0; - cl_io_for_each(scan, io) { + list_for_each_entry(scan, &io->ci_layers, cis_linkage) { if (!scan->cis_iop->op[io->ci_type].cio_iter_init) continue; result = scan->cis_iop->op[io->ci_type].cio_iter_init(env, @@ -443,7 +439,7 @@ void cl_io_iter_fini(const struct lu_env *env, struct cl_io *io) LINVRNT(io->ci_state == CIS_UNLOCKED); LINVRNT(cl_io_invariant(io)); - cl_io_for_each_reverse(scan, io) { + list_for_each_entry_reverse(scan, &io->ci_layers, cis_linkage) { if (scan->cis_iop->op[io->ci_type].cio_iter_fini) scan->cis_iop->op[io->ci_type].cio_iter_fini(env, scan); } @@ -468,7 +464,7 @@ static void cl_io_rw_advance(const struct lu_env *env, struct cl_io *io, io->u.ci_rw.crw_count -= nob; /* layers have to be notified. */ - cl_io_for_each_reverse(scan, io) { + list_for_each_entry_reverse(scan, &io->ci_layers, cis_linkage) { if (scan->cis_iop->op[io->ci_type].cio_advance) scan->cis_iop->op[io->ci_type].cio_advance(env, scan, nob); @@ -536,7 +532,7 @@ int cl_io_start(const struct lu_env *env, struct cl_io *io) LINVRNT(cl_io_invariant(io)); io->ci_state = CIS_IO_GOING; - cl_io_for_each(scan, io) { + list_for_each_entry(scan, &io->ci_layers, cis_linkage) { if (!scan->cis_iop->op[io->ci_type].cio_start) continue; result = scan->cis_iop->op[io->ci_type].cio_start(env, scan); @@ -561,7 +557,7 @@ void cl_io_end(const struct lu_env *env, struct cl_io *io) LINVRNT(io->ci_state == CIS_IO_GOING); LINVRNT(cl_io_invariant(io)); - cl_io_for_each_reverse(scan, io) { + list_for_each_entry_reverse(scan, &io->ci_layers, cis_linkage) { if (scan->cis_iop->op[io->ci_type].cio_end) scan->cis_iop->op[io->ci_type].cio_end(env, scan); /* TODO: error handling. */ @@ -584,7 +580,7 @@ int cl_io_read_ahead(const struct lu_env *env, struct cl_io *io, LINVRNT(io->ci_type == CIT_READ || io->ci_type == CIT_FAULT); LINVRNT(cl_io_invariant(io)); - cl_io_for_each(scan, io) { + list_for_each_entry(scan, &io->ci_layers, cis_linkage) { if (!scan->cis_iop->cio_read_ahead) continue; @@ -609,7 +605,7 @@ int cl_io_commit_async(const struct lu_env *env, struct cl_io *io, const struct cl_io_slice *scan; int result = 0; - cl_io_for_each(scan, io) { + list_for_each_entry(scan, &io->ci_layers, cis_linkage) { if (!scan->cis_iop->cio_commit_async) continue; result = scan->cis_iop->cio_commit_async(env, scan, queue, @@ -637,7 +633,7 @@ int cl_io_submit_rw(const struct lu_env *env, struct cl_io *io, const struct cl_io_slice *scan; int result = 0; - cl_io_for_each(scan, io) { + list_for_each_entry(scan, &io->ci_layers, cis_linkage) { if (!scan->cis_iop->cio_submit) continue; result = scan->cis_iop->cio_submit(env, scan, crt, queue); -- 1.8.3.1 From neilb at suse.com Tue Sep 18 13:14:43 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 18 Sep 2018 23:14:43 +1000 Subject: [lustre-devel] [PATCH 11/30] lustre: mdc: allow setting readdir RPC size parameter In-Reply-To: <1537205440-6656-12-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-12-git-send-email-jsimmons@infradead.org> Message-ID: <8736u76j7g.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > From: Andreas Dilger > > Allow the mdc.*.max_pages_per_rpc tunable to set the MDS bulk > readdir RPC size, rather than always using the default 1MB RPC > size. The tunable is set in the MDC, as it should be, rather > than in the llite superblock, which requires extra code just to > get it up from the MDC's connect_data only to send it back down. > The RPC size could be tuned independently if different types of > MDSes are used (e.g. local vs. remote). > > Remove the md_op_data.op_max_pages and ll_sb_info.ll_md_brw_pages > fields that previously were used to pass the readdir size from > llite to mdc_read_page(). Reorder some 32-bit fields in md_op_data > to avoid struct holes. > > Move osc's max_pages_per_rpc_store() to obdclass along with > max_pages_per_rpc_show(). > > Signed-off-by: Andreas Dilger > WC-bug-id: https://jira.whamcloud.com/browse/LU-3308 > Reviewed-on: https://review.whamcloud.com/26088 > Reviewed-by: Niu Yawei > Reviewed-by: Lai Siyao > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > .../staging/lustre/lustre/include/lprocfs_status.h | 5 ++ > drivers/staging/lustre/lustre/include/lustre_net.h | 8 ++-- > drivers/staging/lustre/lustre/include/obd.h | 5 +- > drivers/staging/lustre/lustre/llite/dir.c | 12 +---- > drivers/staging/lustre/lustre/llite/lcommon_cl.c | 19 +++----- > .../staging/lustre/lustre/llite/llite_internal.h | 2 - > drivers/staging/lustre/lustre/llite/llite_lib.c | 5 -- > drivers/staging/lustre/lustre/llite/llite_nfs.c | 1 - > drivers/staging/lustre/lustre/llite/statahead.c | 4 -- > drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 20 +------- > drivers/staging/lustre/lustre/mdc/mdc_request.c | 13 +++--- > .../lustre/lustre/obdclass/lprocfs_status.c | 54 ++++++++++++++++++++++ > drivers/staging/lustre/lustre/osc/lproc_osc.c | 46 ------------------ > drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 2 +- > 14 files changed, 82 insertions(+), 114 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h > index c841aba..5da26e3 100644 > --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h > +++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h > @@ -584,6 +584,11 @@ ssize_t lustre_attr_store(struct kobject *kobj, struct attribute *attr, > > extern const struct sysfs_ops lustre_sysfs_ops; > > +ssize_t max_pages_per_rpc_show(struct kobject *kobj, struct attribute *attr, > + char *buf); > +ssize_t max_pages_per_rpc_store(struct kobject *kobj, struct attribute *attr, > + const char *buffer, size_t count); > + > struct root_squash_info; > int lprocfs_wr_root_squash(const char __user *buffer, unsigned long count, > struct root_squash_info *squash, char *name); > diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h > index 2dbd208..cf630db 100644 > --- a/drivers/staging/lustre/lustre/include/lustre_net.h > +++ b/drivers/staging/lustre/lustre/include/lustre_net.h > @@ -104,15 +104,15 @@ > * currently supported maximum between peers at connect via ocd_brw_size. > */ > #define PTLRPC_MAX_BRW_BITS (LNET_MTU_BITS + PTLRPC_BULK_OPS_BITS) > -#define PTLRPC_MAX_BRW_SIZE (1 << PTLRPC_MAX_BRW_BITS) > +#define PTLRPC_MAX_BRW_SIZE BIT(PTLRPC_MAX_BRW_BITS) > #define PTLRPC_MAX_BRW_PAGES (PTLRPC_MAX_BRW_SIZE >> PAGE_SHIFT) > > -#define ONE_MB_BRW_SIZE (1 << LNET_MTU_BITS) > -#define MD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) > +#define ONE_MB_BRW_SIZE BIT(LNET_MTU_BITS) > +#define MD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) > #define MD_MAX_BRW_PAGES (MD_MAX_BRW_SIZE >> PAGE_SHIFT) > #define DT_MAX_BRW_SIZE PTLRPC_MAX_BRW_SIZE > #define DT_MAX_BRW_PAGES (DT_MAX_BRW_SIZE >> PAGE_SHIFT) > -#define OFD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) > +#define OFD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) Argg!! No!! Names are important. "SIZE" means the value is a size, a number. The bit-representation is largely irrelevant, it is the number that is important. BIT(x) returns a single bit - lots of zeros and just one '1' bit. This is not a number, it is a bit pattern. So settings FOO_SIZE to BIT(bar) is wrong. It is a type error. It uses a bit pattern when a number is expected. The C compiler won't notice, but I will. When I apply this (which probably won't be until next week), I'll just remove this section of the patch. > > /* When PAGE_SIZE is a constant, we can check our arithmetic here with cpp! */ > # if ((PTLRPC_MAX_BRW_PAGES & (PTLRPC_MAX_BRW_PAGES - 1)) != 0) > diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h > index 329bae9..50e97b4 100644 > --- a/drivers/staging/lustre/lustre/include/obd.h > +++ b/drivers/staging/lustre/lustre/include/obd.h > @@ -717,11 +717,11 @@ struct md_op_data { > struct lu_fid op_fid3; /* 2 extra fids to find conflicting */ > struct lu_fid op_fid4; /* to the operation locks. */ > u32 op_mds; /* what mds server open will go to */ > + u32 op_mode; > struct lustre_handle op_handle; > s64 op_mod_time; > const char *op_name; > size_t op_namelen; > - __u32 op_mode; > struct lmv_stripe_md *op_mea1; > struct lmv_stripe_md *op_mea2; > __u32 op_suppgids[2]; > @@ -746,9 +746,6 @@ struct md_op_data { > /* Used by readdir */ > __u64 op_offset; > > - /* Used by readdir */ > - __u32 op_max_pages; > - > /* used to transfer info between the stacks of MD client > * see enum op_cli_flags > */ > diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c > index f352fab..26b0c2d 100644 > --- a/drivers/staging/lustre/lustre/llite/dir.c > +++ b/drivers/staging/lustre/lustre/llite/dir.c > @@ -231,18 +231,11 @@ int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data, > __u64 ino; > > hash = le64_to_cpu(ent->lde_hash); > - if (hash < pos) > - /* > - * Skip until we find target hash > - * value. > - */ > + if (hash < pos) /* Skip until we find target hash */ > continue; If these comments are really needed (i++; /* increment i */), then they should be: if (hash < pos) /* skip until we find target hash */ continue; > > namelen = le16_to_cpu(ent->lde_namelen); > - if (namelen == 0) > - /* > - * Skip dummy record. > - */ > + if (namelen == 0) /* Skip dummy record. */ > continue; > > if (is_api32 && is_hash64) > @@ -351,7 +344,6 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx) > } > } > } > - op_data->op_max_pages = sbi->ll_md_brw_pages; > ctx->pos = pos; > rc = ll_dir_read(inode, &pos, op_data, ctx); > pos = ctx->pos; > diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c > index 6c9fe49..d3b0445 100644 > --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c > +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c > @@ -267,27 +267,22 @@ void cl_inode_fini(struct inode *inode) > /** > * build inode number from passed @fid > */ > -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) > +u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) > { > if (BITS_PER_LONG == 32 || api32) > return fid_flatten32(fid); > - else > - return fid_flatten(fid); > + > + return fid_flatten(fid); I preferred that as it was - it makes the either/or nature more obvious. NeilBrown > } > > /** > * build inode generation from passed @fid. If our FID overflows the 32-bit > * inode number then return a non-zero generation to distinguish them. > */ > -__u32 cl_fid_build_gen(const struct lu_fid *fid) > +u32 cl_fid_build_gen(const struct lu_fid *fid) > { > - __u32 gen; > - > - if (fid_is_igif(fid)) { > - gen = lu_igif_gen(fid); > - return gen; > - } > + if (fid_is_igif(fid)) > + return lu_igif_gen(fid); > > - gen = fid_flatten(fid) >> 32; > - return gen; > + return fid_flatten(fid) >> 32; > } > diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h > index bf679c9..9d9f623 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_internal.h > +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h > @@ -490,8 +490,6 @@ struct ll_sb_info { > unsigned int ll_namelen; > const struct file_operations *ll_fop; > > - unsigned int ll_md_brw_pages; /* readdir pages per RPC */ > - > struct lu_site *ll_site; > struct cl_device *ll_cl; > /* Statistics */ > diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c > index f0fe21f..b5bafc4 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_lib.c > +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c > @@ -343,11 +343,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) > if (data->ocd_connect_flags & OBD_CONNECT_64BITHASH) > sbi->ll_flags |= LL_SBI_64BIT_HASH; > > - if (data->ocd_connect_flags & OBD_CONNECT_BRW_SIZE) > - sbi->ll_md_brw_pages = data->ocd_brw_size >> PAGE_SHIFT; > - else > - sbi->ll_md_brw_pages = 1; > - > if (data->ocd_connect_flags & OBD_CONNECT_LAYOUTLOCK) > sbi->ll_flags |= LL_SBI_LAYOUT_LOCK; > > diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c > index 9efb20e..c66072a 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c > +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c > @@ -261,7 +261,6 @@ static int ll_get_name(struct dentry *dentry, char *name, > goto out; > } > > - op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages; > inode_lock(dir); > rc = ll_dir_read(dir, &pos, op_data, &lgd.ctx); > inode_unlock(dir); > diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c > index ea2a002..1ad308c 100644 > --- a/drivers/staging/lustre/lustre/llite/statahead.c > +++ b/drivers/staging/lustre/lustre/llite/statahead.c > @@ -961,8 +961,6 @@ static int ll_statahead_thread(void *arg) > goto out; > } > > - op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages; > - > while (pos != MDS_DIR_END_OFF && sai->sai_task) { > struct lu_dirpage *dp; > struct lu_dirent *ent; > @@ -1215,8 +1213,6 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry) > /** > * FIXME choose the start offset of the readdir > */ > - op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages; > - > page = ll_get_dir_page(dir, op_data, pos); > > while (1) { > diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c > index 3bff8b5..a205c61 100644 > --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c > +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c > @@ -134,6 +134,8 @@ static ssize_t max_mod_rpcs_in_flight_store(struct kobject *kobj, > } > LUSTRE_RW_ATTR(max_mod_rpcs_in_flight); > > +LUSTRE_RW_ATTR(max_pages_per_rpc); > + > #define mdc_conn_uuid_show conn_uuid_show > LUSTRE_RO_ATTR(mdc_conn_uuid); > > @@ -165,24 +167,6 @@ static ssize_t mdc_rpc_stats_seq_write(struct file *file, > LPROC_SEQ_FOPS_RO_TYPE(mdc, timeouts); > LPROC_SEQ_FOPS_RO_TYPE(mdc, state); > > -/* > - * Note: below sysfs entry is provided, but not currently in use, instead > - * sbi->sb_md_brw_size is used, the per obd variable should be used > - * when DNE is enabled, and dir pages are managed in MDC layer. > - * Don't forget to enable sysfs store function then. > - */ > -static ssize_t max_pages_per_rpc_show(struct kobject *kobj, > - struct attribute *attr, > - char *buf) > -{ > - struct obd_device *dev = container_of(kobj, struct obd_device, > - obd_kset.kobj); > - struct client_obd *cli = &dev->u.cli; > - > - return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); > -} > -LUSTRE_RO_ATTR(max_pages_per_rpc); > - > LPROC_SEQ_FOPS_RW_TYPE(mdc, import); > LPROC_SEQ_FOPS_RW_TYPE(mdc, pinger_recov); > > diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c > index 116e973..37bf486 100644 > --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c > +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c > @@ -1166,17 +1166,17 @@ static int mdc_read_page_remote(void *data, struct page *page0) > struct page **page_pool; > struct page *page; > struct lu_dirpage *dp; > - int rd_pgs = 0; /* number of pages read actually */ > - int npages; > struct md_op_data *op_data = rp->rp_mod; > struct ptlrpc_request *req; > - int max_pages = op_data->op_max_pages; > struct inode *inode; > struct lu_fid *fid; > - int i; > + int rd_pgs = 0; /* number of pages read actually */ > + int max_pages; > + int npages; > int rc; > + int i; > > - LASSERT(max_pages > 0 && max_pages <= PTLRPC_MAX_BRW_PAGES); > + max_pages = rp->rp_exp->exp_obd->u.cli.cl_max_pages_per_rpc; > inode = op_data->op_data; > fid = &op_data->op_fid1; > LASSERT(inode); > @@ -1200,8 +1200,7 @@ static int mdc_read_page_remote(void *data, struct page *page0) > if (!rc) { > int lu_pgs = req->rq_bulk->bd_nob_transferred; > > - rd_pgs = (req->rq_bulk->bd_nob_transferred + > - PAGE_SIZE - 1) >> PAGE_SHIFT; > + rd_pgs = (lu_pgs + PAGE_SIZE - 1) >> PAGE_SHIFT; > lu_pgs >>= LU_PAGE_SHIFT; > LASSERT(!(req->rq_bulk->bd_nob_transferred & ~LU_PAGE_MASK)); > > diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c > index 84e5a8c..a540abb 100644 > --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c > +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c > @@ -1785,3 +1785,57 @@ ssize_t lustre_attr_store(struct kobject *kobj, struct attribute *attr, > .store = lustre_attr_store, > }; > EXPORT_SYMBOL_GPL(lustre_sysfs_ops); > + > +ssize_t max_pages_per_rpc_show(struct kobject *kobj, struct attribute *attr, > + char *buf) > +{ > + struct obd_device *dev = container_of(kobj, struct obd_device, > + obd_kset.kobj); > + struct client_obd *cli = &dev->u.cli; > + > + return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); > +} > +EXPORT_SYMBOL(max_pages_per_rpc_show); > + > +ssize_t max_pages_per_rpc_store(struct kobject *kobj, struct attribute *attr, > + const char *buffer, size_t count) > +{ > + struct obd_device *dev = container_of(kobj, struct obd_device, > + obd_kset.kobj); > + struct client_obd *cli = &dev->u.cli; > + struct obd_connect_data *ocd; > + unsigned long long val; > + int chunk_mask; > + int rc; > + > + rc = kstrtoull(buffer, 10, &val); > + if (rc) > + return rc; > + > + /* if the max_pages is specified in bytes, convert to pages */ > + if (val >= ONE_MB_BRW_SIZE) > + val >>= PAGE_SHIFT; > + > + rc = lprocfs_climp_check(dev); > + if (rc) > + return rc; > + > + ocd = &cli->cl_import->imp_connect_data; > + chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_SHIFT)) - 1); > + /* max_pages_per_rpc must be chunk aligned */ > + val = (val + ~chunk_mask) & chunk_mask; > + if (!val || (ocd->ocd_brw_size && > + val > ocd->ocd_brw_size >> PAGE_SHIFT)) { > + up_read(&dev->u.cli.cl_sem); > + return -ERANGE; > + } > + > + spin_lock(&cli->cl_loi_list_lock); > + cli->cl_max_pages_per_rpc = val; > + client_adjust_max_dirty(cli); > + spin_unlock(&cli->cl_loi_list_lock); > + > + up_read(&dev->u.cli.cl_sem); > + return count; > +} > +EXPORT_SYMBOL(max_pages_per_rpc_store); > diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c > index cd28295..bf576f1 100644 > --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c > +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c > @@ -570,52 +570,6 @@ static ssize_t destroys_in_flight_show(struct kobject *kobj, > atomic_read(&obd->u.cli.cl_destroy_in_flight)); > } > LUSTRE_RO_ATTR(destroys_in_flight); > - > -static ssize_t max_pages_per_rpc_show(struct kobject *kobj, > - struct attribute *attr, > - char *buf) > -{ > - struct obd_device *dev = container_of(kobj, struct obd_device, > - obd_kset.kobj); > - struct client_obd *cli = &dev->u.cli; > - > - return sprintf(buf, "%d\n", cli->cl_max_pages_per_rpc); > -} > - > -static ssize_t max_pages_per_rpc_store(struct kobject *kobj, > - struct attribute *attr, > - const char *buffer, > - size_t count) > -{ > - struct obd_device *dev = container_of(kobj, struct obd_device, > - obd_kset.kobj); > - struct client_obd *cli = &dev->u.cli; > - struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data; > - int chunk_mask, rc; > - unsigned long long val; > - > - rc = kstrtoull(buffer, 10, &val); > - if (rc) > - return rc; > - > - /* if the max_pages is specified in bytes, convert to pages */ > - if (val >= ONE_MB_BRW_SIZE) > - val >>= PAGE_SHIFT; > - > - chunk_mask = ~((1 << (cli->cl_chunkbits - PAGE_SHIFT)) - 1); > - /* max_pages_per_rpc must be chunk aligned */ > - val = (val + ~chunk_mask) & chunk_mask; > - if (!val || (ocd->ocd_brw_size && > - val > ocd->ocd_brw_size >> PAGE_SHIFT)) { > - return -ERANGE; > - } > - spin_lock(&cli->cl_loi_list_lock); > - cli->cl_max_pages_per_rpc = val; > - client_adjust_max_dirty(cli); > - spin_unlock(&cli->cl_loi_list_lock); > - > - return count; > -} > LUSTRE_RW_ATTR(max_pages_per_rpc); > > static int osc_unstable_stats_seq_show(struct seq_file *m, void *v) > diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c > index 625b952..3d336d9 100644 > --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c > +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c > @@ -232,7 +232,7 @@ static unsigned long enc_pools_shrink_count(struct shrinker *s, > } > > LASSERT(page_pools.epp_idle_idx <= IDLE_IDX_MAX); > - return max((int)page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES, 0) * > + return max(page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES, 0UL) * > (IDLE_IDX_MAX - page_pools.epp_idle_idx) / IDLE_IDX_MAX; > } > > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From c17817 at cray.com Tue Sep 18 05:29:54 2018 From: c17817 at cray.com (Alexey Lyashkov) Date: Tue, 18 Sep 2018 05:29:54 +0000 Subject: [lustre-devel] [PATCH 4/8] lustre: obdclass: cleanup obd_class.h defines In-Reply-To: <1537205481-6899-5-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> <1537205481-6899-5-git-send-email-jsimmons@infradead.org> Message-ID: <920C9E0E-A2EB-483E-ACB8-0AE680C02CD6@cray.com> NAK. Please use same as original patch ' struct niobuf_local *local, int orig_rc' vs ' struct niobuf_local *local, const int orig_rc'. On 17/09/2018, 20:31, "James Simmons" wrote: From: Ben Evans Get rid of OBT and CTXTP defines. Remove OBD_CHECK_DT_OP Convert EXP_CHECK_MD_OP into a function. Remove CTXT_CHECK_OP. Signed-off-by: Ben Evans Signed-off-by: Alexey Lyashkov WC-bug-id: https://jira.whamcloud.com/browse/LU-9855 Reviewed-on: https://review.whamcloud.com/29286 WC-bug-id: https://jira.whamcloud.com/browse/LU-11169 Reviewed-on: https://review.whamcloud.com/#/c/32906 Reviewed-by: John L. Hammond Reviewed-by: Steve Guminski Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/obd_class.h | 437 +++++++++++++++------- drivers/staging/lustre/lustre/obdclass/llog_obd.c | 4 +- 2 files changed, 311 insertions(+), 130 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index c6fb2e1..aab1092 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -303,10 +303,8 @@ static inline int lprocfs_climp_check(struct obd_device *obd) void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj); -#define OBT(dev) ((dev)->obd_type) #define OBP(dev, op) ((dev)->obd_type->typ_dt_ops->op) #define MDP(dev, op) ((dev)->obd_type->typ_md_ops->op) -#define CTXTP(ctxt, op) ((ctxt)->loc_logops->lop_##op) /* * Ensure obd_setup: used for cleanup which must be called @@ -393,56 +391,16 @@ static inline int obd_check_dev_active(struct obd_device *obd) } \ } while (0) -#define EXP_CHECK_MD_OP(exp, op) \ -do { \ - if (!(exp)) { \ - CERROR("obd_" #op ": NULL export\n"); \ - return -ENODEV; \ - } \ - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ - CERROR("obd_" #op ": cleaned up obd\n"); \ - return -EOPNOTSUPP; \ - } \ - if (!OBT((exp)->exp_obd) || !MDP((exp)->exp_obd, op)) { \ - CERROR("%s: obd_" #op ": dev %d no operation\n",\ - (exp)->exp_obd->obd_name, \ - (exp)->exp_obd->obd_minor); \ - return -EOPNOTSUPP; \ - } \ -} while (0) - -#define OBD_CHECK_DT_OP(obd, op, err) \ -do { \ - if (!OBT(obd) || !OBP((obd), op)) { \ - if (err) \ - CERROR("%s: no obd_" #op " operation\n", \ - obd->obd_name); \ - return err; \ - } \ -} while (0) +static inline int exp_check_ops(struct obd_export *exp) +{ + if (!exp) + return -ENODEV; -#define EXP_CHECK_DT_OP(exp, op) \ -do { \ - if (!(exp)) { \ - CERROR("obd_" #op ": NULL export\n"); \ - return -ENODEV; \ - } \ - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ - CERROR("obd_" #op ": cleaned up obd\n"); \ - return -EOPNOTSUPP; \ - } \ - OBD_CHECK_DT_OP((exp)->exp_obd, op, -EOPNOTSUPP); \ -} while (0) + if (!exp->exp_obd || !exp->exp_obd->obd_type) + return -EOPNOTSUPP; -#define CTXT_CHECK_OP(ctxt, op, err) \ -do { \ - if (!OBT(ctxt->loc_obd) || !CTXTP((ctxt), op)) { \ - if (err) \ - CERROR("%s: no lop_" #op " operation\n", \ - ctxt->loc_obd->obd_name); \ - return err; \ - } \ -} while (0) + return 0; +} static inline int class_devno_max(void) { @@ -455,7 +413,15 @@ static inline int obd_get_info(const struct lu_env *env, { int rc; - EXP_CHECK_DT_OP(exp, get_info); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->get_info) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, get_info); rc = OBP(exp->exp_obd, get_info)(env, exp, keylen, key, vallen, val); @@ -469,7 +435,15 @@ static inline int obd_set_info_async(const struct lu_env *env, { int rc; - EXP_CHECK_DT_OP(exp, set_info_async); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->set_info_async) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, set_info_async); rc = OBP(exp->exp_obd, set_info_async)(env, exp, keylen, key, vallen, @@ -484,14 +458,14 @@ static inline int obd_set_info_async(const struct lu_env *env, * pieces of configuration process are still based on obd devices. * * Specifically, lu_device_type_operations::ldto_device_alloc() methods fully - * subsume ->o_setup() methods of obd devices they replace. The same for - * lu_device_operations::ldo_process_config() and ->o_process_config(). As a + * subsume ->setup() methods of obd devices they replace. The same for + * lu_device_operations::ldo_process_config() and ->process_config(). As a * result, obd_setup() and obd_process_config() branch and call one XOR * another. * * Yet neither lu_device_type_operations::ldto_device_fini() nor * lu_device_type_operations::ldto_device_free() fully implement the - * functionality of ->o_precleanup() and ->o_cleanup() they override. Hence, + * functionality of ->precleanup() and ->o_cleanup() they override. Hence, * obd_precleanup() and obd_cleanup() call both lu_device and obd operations. */ @@ -527,7 +501,11 @@ static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) lu_context_fini(&session_ctx); } else { - OBD_CHECK_DT_OP(obd, setup, -EOPNOTSUPP); + if (!obd->obd_type->typ_dt_ops->setup) { + CERROR("%s: no %s operation\n", obd->obd_name, + __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, setup); rc = OBP(obd, setup)(obd, cfg); } @@ -549,7 +527,9 @@ static inline int obd_precleanup(struct obd_device *obd) lu_env_fini(&env); } } - OBD_CHECK_DT_OP(obd, precleanup, 0); + if (!obd->obd_type->typ_dt_ops->precleanup) + return 0; + OBD_COUNTER_INCREMENT(obd, precleanup); rc = OBP(obd, precleanup)(obd); @@ -572,7 +552,9 @@ static inline int obd_cleanup(struct obd_device *obd) obd->obd_lu_dev = NULL; } } - OBD_CHECK_DT_OP(obd, cleanup, 0); + if (!obd->obd_type->typ_dt_ops->cleanup) + return 0; + OBD_COUNTER_INCREMENT(obd, cleanup); rc = OBP(obd, cleanup)(obd); @@ -599,8 +581,8 @@ static inline void obd_cleanup_client_import(struct obd_device *obd) up_write(&obd->u.cli.cl_sem); } -static inline int -obd_process_config(struct obd_device *obd, int datalen, void *data) +static inline int obd_process_config(struct obd_device *obd, int datalen, + void *data) { struct lu_device_type *ldt = obd->obd_type->typ_lu; struct lu_device *d = obd->obd_lu_dev; @@ -616,7 +598,11 @@ static inline void obd_cleanup_client_import(struct obd_device *obd) lu_env_fini(&env); } } else { - OBD_CHECK_DT_OP(obd, process_config, -EOPNOTSUPP); + if (!obd->obd_type->typ_dt_ops->process_config) { + CERROR("%s: no %s operation\n", + obd->obd_name, __func__); + return -EOPNOTSUPP; + } rc = OBP(obd, process_config)(obd, datalen, data); } OBD_COUNTER_INCREMENT(obd, process_config); @@ -630,7 +616,15 @@ static inline int obd_create(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, create); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->create) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, create); rc = OBP(exp->exp_obd, create)(env, exp, obdo); @@ -642,7 +636,15 @@ static inline int obd_destroy(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, destroy); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->destroy) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, destroy); rc = OBP(exp->exp_obd, destroy)(env, exp, obdo); @@ -654,7 +656,15 @@ static inline int obd_getattr(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, getattr); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->getattr) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, getattr); rc = OBP(exp->exp_obd, getattr)(env, exp, oa); @@ -666,7 +676,15 @@ static inline int obd_setattr(const struct lu_env *env, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, setattr); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->setattr) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -EOPNOTSUPP; + } EXP_COUNTER_INCREMENT(exp, setattr); rc = OBP(exp->exp_obd, setattr)(env, exp, oa); @@ -682,7 +700,11 @@ static inline int obd_add_conn(struct obd_import *imp, struct obd_uuid *uuid, rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, add_conn, -EOPNOTSUPP); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->add_conn) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, add_conn); rc = OBP(obd, add_conn)(imp, uuid, priority); @@ -697,7 +719,11 @@ static inline int obd_del_conn(struct obd_import *imp, struct obd_uuid *uuid) rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, del_conn, -EOPNOTSUPP); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->del_conn) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, del_conn); rc = OBP(obd, del_conn)(imp, uuid); @@ -708,7 +734,10 @@ static inline struct obd_uuid *obd_get_uuid(struct obd_export *exp) { struct obd_uuid *uuid; - OBD_CHECK_DT_OP(exp->exp_obd, get_uuid, NULL); + if (!exp->exp_obd->obd_type || + !exp->exp_obd->obd_type->typ_dt_ops->get_uuid) + return NULL; + EXP_COUNTER_INCREMENT(exp, get_uuid); uuid = OBP(exp->exp_obd, get_uuid)(exp); @@ -727,16 +756,18 @@ static inline int obd_connect(const struct lu_env *env, struct obd_connect_data *data, void *localdata) { + /* for post-condition check */ + u64 ocf = data ? data->ocd_connect_flags : 0; int rc; - __u64 ocf = data ? data->ocd_connect_flags : 0; /* - * for post-condition - * check - */ rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, connect, -EOPNOTSUPP); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->connect) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, connect); rc = OBP(obd, connect)(env, exp, obd, cluuid, data, localdata); @@ -753,13 +784,16 @@ static inline int obd_reconnect(const struct lu_env *env, struct obd_connect_data *d, void *localdata) { + u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition check */ int rc; - __u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition check */ rc = obd_check_dev_active(obd); if (rc) return rc; - OBD_CHECK_DT_OP(obd, reconnect, 0); + + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->reconnect) + return 0; + OBD_COUNTER_INCREMENT(obd, reconnect); rc = OBP(obd, reconnect)(env, exp, obd, cluuid, d, localdata); @@ -772,7 +806,15 @@ static inline int obd_disconnect(struct obd_export *exp) { int rc; - EXP_CHECK_DT_OP(exp, disconnect); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->disconnect) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, disconnect); rc = OBP(exp->exp_obd, disconnect)(exp); @@ -784,7 +826,8 @@ static inline int obd_fid_init(struct obd_device *obd, struct obd_export *exp, { int rc; - OBD_CHECK_DT_OP(obd, fid_init, 0); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_init) + return 0; OBD_COUNTER_INCREMENT(obd, fid_init); rc = OBP(obd, fid_init)(obd, exp, type); @@ -795,7 +838,8 @@ static inline int obd_fid_fini(struct obd_device *obd) { int rc; - OBD_CHECK_DT_OP(obd, fid_fini, 0); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_fini) + return 0; OBD_COUNTER_INCREMENT(obd, fid_fini); rc = OBP(obd, fid_fini)(obd); @@ -809,7 +853,15 @@ static inline int obd_fid_alloc(const struct lu_env *env, { int rc; - EXP_CHECK_DT_OP(exp, fid_alloc); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->fid_alloc) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, fid_alloc); rc = OBP(exp->exp_obd, fid_alloc)(env, exp, fid, op_data); @@ -820,7 +872,10 @@ static inline int obd_pool_new(struct obd_device *obd, char *poolname) { int rc; - OBD_CHECK_DT_OP(obd, pool_new, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_new) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_new); rc = OBP(obd, pool_new)(obd, poolname); @@ -831,20 +886,25 @@ static inline int obd_pool_del(struct obd_device *obd, char *poolname) { int rc; - OBD_CHECK_DT_OP(obd, pool_del, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_del) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_del); rc = OBP(obd, pool_del)(obd, poolname); return rc; } -static inline int obd_pool_add(struct obd_device *obd, - char *poolname, +static inline int obd_pool_add(struct obd_device *obd, char *poolname, char *ostname) { int rc; - OBD_CHECK_DT_OP(obd, pool_add, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_add) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_add); rc = OBP(obd, pool_add)(obd, poolname, ostname); @@ -857,7 +917,10 @@ static inline int obd_pool_rem(struct obd_device *obd, { int rc; - OBD_CHECK_DT_OP(obd, pool_rem, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_rem) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, pool_rem); rc = OBP(obd, pool_rem)(obd, poolname, ostname); @@ -866,7 +929,7 @@ static inline int obd_pool_rem(struct obd_device *obd, static inline void obd_getref(struct obd_device *obd) { - if (OBT(obd) && OBP(obd, getref)) { + if (obd->obd_type && OBP(obd, getref)) { OBD_COUNTER_INCREMENT(obd, getref); OBP(obd, getref)(obd); } @@ -874,7 +937,7 @@ static inline void obd_getref(struct obd_device *obd) static inline void obd_putref(struct obd_device *obd) { - if (OBT(obd) && OBP(obd, putref)) { + if (obd->obd_type && OBP(obd, putref)) { OBD_COUNTER_INCREMENT(obd, putref); OBP(obd, putref)(obd); } @@ -884,7 +947,7 @@ static inline int obd_init_export(struct obd_export *exp) { int rc = 0; - if ((exp)->exp_obd && OBT((exp)->exp_obd) && + if (exp->exp_obd && exp->exp_obd->obd_type && OBP((exp)->exp_obd, init_export)) rc = OBP(exp->exp_obd, init_export)(exp); return rc; @@ -892,7 +955,7 @@ static inline int obd_init_export(struct obd_export *exp) static inline int obd_destroy_export(struct obd_export *exp) { - if ((exp)->exp_obd && OBT((exp)->exp_obd) && + if (exp->exp_obd && exp->exp_obd->obd_type && OBP((exp)->exp_obd, destroy_export)) OBP(exp->exp_obd, destroy_export)(exp); return 0; @@ -915,7 +978,10 @@ static inline int obd_statfs_async(struct obd_export *exp, return -EINVAL; obd = exp->exp_obd; - OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->statfs) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, statfs); CDEBUG(D_SUPER, "%s: osfs %p age %llu, max_age %llu\n", @@ -969,13 +1035,16 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp, struct obd_statfs *osfs, __u64 max_age, __u32 flags) { - int rc = 0; struct obd_device *obd = exp->exp_obd; + int rc = 0; if (!obd) return -EINVAL; - OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP); + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->statfs) { + CERROR("%s: no %s operation\n", obd->obd_name, __func__); + return -EOPNOTSUPP; + } OBD_COUNTER_INCREMENT(obd, statfs); CDEBUG(D_SUPER, "osfs %llu, max_age %llu\n", @@ -1009,7 +1078,15 @@ static inline int obd_preprw(const struct lu_env *env, int cmd, { int rc; - EXP_CHECK_DT_OP(exp, preprw); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->preprw) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, preprw); rc = OBP(exp->exp_obd, preprw)(env, cmd, exp, oa, objcount, obj, remote, @@ -1021,13 +1098,23 @@ static inline int obd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int pages, - struct niobuf_local *local, int rc) + struct niobuf_local *local, int orig_rc) { - EXP_CHECK_DT_OP(exp, commitrw); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->commitrw) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, commitrw); rc = OBP(exp->exp_obd, commitrw)(env, cmd, exp, oa, objcount, obj, - rnb, pages, local, rc); + rnb, pages, local, orig_rc); return rc; } @@ -1036,7 +1123,15 @@ static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, iocontrol); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->iocontrol) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, iocontrol); rc = OBP(exp->exp_obd, iocontrol)(cmd, exp, len, karg, uarg); @@ -1108,7 +1203,15 @@ static inline int obd_quotactl(struct obd_export *exp, { int rc; - EXP_CHECK_DT_OP(exp, quotactl); + rc = exp_check_ops(exp); + if (rc) + return rc; + + if (!exp->exp_obd->obd_type->typ_dt_ops->quotactl) { + CERROR("%s: no %s operation\n", + exp->exp_obd->obd_name, __func__); + return -ENOTSUPP; + } EXP_COUNTER_INCREMENT(exp, quotactl); rc = OBP(exp->exp_obd, quotactl)(exp->exp_obd, exp, oqctl); @@ -1129,7 +1232,7 @@ static inline int obd_health_check(const struct lu_env *env, int rc; /* don't use EXP_CHECK_DT_OP, because NULL method is normal here */ - if (!obd || !OBT(obd)) { + if (!obd || !obd->obd_type) { CERROR("cleaned up obd\n"); return -EOPNOTSUPP; } @@ -1166,7 +1269,9 @@ static inline int md_get_root(struct obd_export *exp, const char *fileset, { int rc; - EXP_CHECK_MD_OP(exp, get_root); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, get_root); rc = MDP(exp->exp_obd, get_root)(exp, fileset, fid); return rc; @@ -1177,7 +1282,9 @@ static inline int md_getattr(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, getattr); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, getattr); rc = MDP(exp->exp_obd, getattr)(exp, op_data, request); return rc; @@ -1188,7 +1295,9 @@ static inline int md_null_inode(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, null_inode); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, null_inode); rc = MDP(exp->exp_obd, null_inode)(exp, fid); return rc; @@ -1200,7 +1309,9 @@ static inline int md_close(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, close); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, close); rc = MDP(exp->exp_obd, close)(exp, op_data, mod, request); return rc; @@ -1213,7 +1324,9 @@ static inline int md_create(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, create); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, create); rc = MDP(exp->exp_obd, create)(exp, op_data, data, datalen, mode, uid, gid, cap_effective, rdev, request); @@ -1229,7 +1342,9 @@ static inline int md_enqueue(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, enqueue); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, enqueue); rc = MDP(exp->exp_obd, enqueue)(exp, einfo, policy, op_data, lockh, extra_lock_flags); @@ -1242,7 +1357,9 @@ static inline int md_getattr_name(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, getattr_name); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, getattr_name); rc = MDP(exp->exp_obd, getattr_name)(exp, op_data, request); return rc; @@ -1257,7 +1374,9 @@ static inline int md_intent_lock(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, intent_lock); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, intent_lock); rc = MDP(exp->exp_obd, intent_lock)(exp, op_data, it, reqp, cb_blocking, extra_lock_flags); @@ -1269,7 +1388,9 @@ static inline int md_link(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, link); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, link); rc = MDP(exp->exp_obd, link)(exp, op_data, request); return rc; @@ -1281,7 +1402,9 @@ static inline int md_rename(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, rename); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, rename); rc = MDP(exp->exp_obd, rename)(exp, op_data, old, oldlen, new, newlen, request); @@ -1294,7 +1417,9 @@ static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, setattr); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, setattr); rc = MDP(exp->exp_obd, setattr)(exp, op_data, ea, ealen, request); return rc; @@ -1305,7 +1430,9 @@ static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid, { int rc; - EXP_CHECK_MD_OP(exp, sync); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, sync); rc = MDP(exp->exp_obd, sync)(exp, fid, request); return rc; @@ -1319,7 +1446,9 @@ static inline int md_read_page(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, read_page); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, read_page); rc = MDP(exp->exp_obd, read_page)(exp, op_data, cb_op, hash_offset, ppage); @@ -1331,7 +1460,9 @@ static inline int md_unlink(struct obd_export *exp, struct md_op_data *op_data, { int rc; - EXP_CHECK_MD_OP(exp, unlink); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, unlink); rc = MDP(exp->exp_obd, unlink)(exp, op_data, request); return rc; @@ -1343,7 +1474,11 @@ static inline int md_get_lustre_md(struct obd_export *exp, struct obd_export *md_exp, struct lustre_md *md) { - EXP_CHECK_MD_OP(exp, get_lustre_md); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, get_lustre_md); return MDP(exp->exp_obd, get_lustre_md)(exp, req, dt_exp, md_exp, md); } @@ -1351,7 +1486,11 @@ static inline int md_get_lustre_md(struct obd_export *exp, static inline int md_free_lustre_md(struct obd_export *exp, struct lustre_md *md) { - EXP_CHECK_MD_OP(exp, free_lustre_md); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, free_lustre_md); return MDP(exp->exp_obd, free_lustre_md)(exp, md); } @@ -1361,7 +1500,11 @@ static inline int md_merge_attr(struct obd_export *exp, struct cl_attr *attr, ldlm_blocking_callback cb) { - EXP_CHECK_MD_OP(exp, merge_attr); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, merge_attr); return MDP(exp->exp_obd, merge_attr)(exp, lsm, attr, cb); } @@ -1372,7 +1515,11 @@ static inline int md_setxattr(struct obd_export *exp, const struct lu_fid *fid, unsigned int xattr_flags, u32 suppgid, struct ptlrpc_request **request) { - EXP_CHECK_MD_OP(exp, setxattr); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, setxattr); return MDP(exp->exp_obd, setxattr)(exp, fid, obd_md_valid, name, value, value_size, xattr_flags, @@ -1383,7 +1530,11 @@ static inline int md_getxattr(struct obd_export *exp, const struct lu_fid *fid, u64 obd_md_valid, const char *name, size_t buf_size, struct ptlrpc_request **req) { - EXP_CHECK_MD_OP(exp, getxattr); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, getxattr); return MDP(exp->exp_obd, getxattr)(exp, fid, obd_md_valid, name, buf_size, req); @@ -1393,7 +1544,11 @@ static inline int md_set_open_replay_data(struct obd_export *exp, struct obd_client_handle *och, struct lookup_intent *it) { - EXP_CHECK_MD_OP(exp, set_open_replay_data); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, set_open_replay_data); return MDP(exp->exp_obd, set_open_replay_data)(exp, och, it); } @@ -1401,7 +1556,11 @@ static inline int md_set_open_replay_data(struct obd_export *exp, static inline int md_clear_open_replay_data(struct obd_export *exp, struct obd_client_handle *och) { - EXP_CHECK_MD_OP(exp, clear_open_replay_data); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, clear_open_replay_data); return MDP(exp->exp_obd, clear_open_replay_data)(exp, och); } @@ -1410,7 +1569,11 @@ static inline int md_set_lock_data(struct obd_export *exp, const struct lustre_handle *lockh, void *data, __u64 *bits) { - EXP_CHECK_MD_OP(exp, set_lock_data); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, set_lock_data); return MDP(exp->exp_obd, set_lock_data)(exp, lockh, data, bits); } @@ -1424,7 +1587,9 @@ static inline int md_cancel_unused(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, cancel_unused); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, cancel_unused); rc = MDP(exp->exp_obd, cancel_unused)(exp, fid, policy, mode, @@ -1439,7 +1604,11 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, enum ldlm_mode mode, struct lustre_handle *lockh) { - EXP_CHECK_MD_OP(exp, lock_match); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, lock_match); return MDP(exp->exp_obd, lock_match)(exp, flags, fid, type, policy, mode, lockh); @@ -1448,7 +1617,11 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, static inline int md_init_ea_size(struct obd_export *exp, u32 easize, u32 def_asize) { - EXP_CHECK_MD_OP(exp, init_ea_size); + int rc; + + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, init_ea_size); return MDP(exp->exp_obd, init_ea_size)(exp, easize, def_asize); } @@ -1458,7 +1631,9 @@ static inline int md_intent_getattr_async(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, intent_getattr_async); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, intent_getattr_async); rc = MDP(exp->exp_obd, intent_getattr_async)(exp, minfo); return rc; @@ -1470,7 +1645,9 @@ static inline int md_revalidate_lock(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, revalidate_lock); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, revalidate_lock); rc = MDP(exp->exp_obd, revalidate_lock)(exp, it, fid, bits); return rc; @@ -1483,7 +1660,9 @@ static inline int md_get_fid_from_lsm(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, get_fid_from_lsm); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, get_fid_from_lsm); rc = MDP(exp->exp_obd, get_fid_from_lsm)(exp, lsm, name, namelen, fid); return rc; @@ -1502,7 +1681,9 @@ static inline int md_unpackmd(struct obd_export *exp, { int rc; - EXP_CHECK_MD_OP(exp, unpackmd); + rc = exp_check_ops(exp); + if (rc) + return rc; EXP_MD_COUNTER_INCREMENT(exp, unpackmd); rc = MDP(exp->exp_obd, unpackmd)(exp, plsm, lmm, lmm_size); return rc; diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c index 26aea11..e074b6e 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c @@ -93,8 +93,8 @@ int __llog_ctxt_put(const struct lu_env *env, struct llog_ctxt *ctxt) !!obd->obd_stopping, !!obd->obd_set_up); /* cleanup the llog ctxt here */ - if (CTXTP(ctxt, cleanup)) - rc = CTXTP(ctxt, cleanup)(env, ctxt); + if (ctxt->loc_logops->lop_cleanup) + rc = ctxt->loc_logops->lop_cleanup(env, ctxt); llog_ctxt_destroy(ctxt); wake_up(&olg->olg_waitq); -- 1.8.3.1 From adilger at whamcloud.com Thu Sep 20 05:42:09 2018 From: adilger at whamcloud.com (Andreas Dilger) Date: Thu, 20 Sep 2018 05:42:09 +0000 Subject: [lustre-devel] [PATCH 11/30] lustre: mdc: allow setting readdir RPC size parameter In-Reply-To: <8736u76j7g.fsf@notabene.neil.brown.name> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-12-git-send-email-jsimmons@infradead.org> <8736u76j7g.fsf@notabene.neil.brown.name> Message-ID: <7503F4FB-D93E-4CD1-9DF3-C00C51528E93@whamcloud.com> On Sep 18, 2018, at 09:14, NeilBrown wrote: > > On Mon, Sep 17 2018, James Simmons wrote: > >> From: Andreas Dilger >> >> diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h >> index 2dbd208..cf630db 100644 >> --- a/drivers/staging/lustre/lustre/include/lustre_net.h >> +++ b/drivers/staging/lustre/lustre/include/lustre_net.h >> @@ -104,15 +104,15 @@ >> * currently supported maximum between peers at connect via ocd_brw_size. >> */ >> #define PTLRPC_MAX_BRW_BITS (LNET_MTU_BITS + PTLRPC_BULK_OPS_BITS) >> -#define PTLRPC_MAX_BRW_SIZE (1 << PTLRPC_MAX_BRW_BITS) >> +#define PTLRPC_MAX_BRW_SIZE BIT(PTLRPC_MAX_BRW_BITS) >> #define PTLRPC_MAX_BRW_PAGES (PTLRPC_MAX_BRW_SIZE >> PAGE_SHIFT) >> >> -#define ONE_MB_BRW_SIZE (1 << LNET_MTU_BITS) >> -#define MD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) >> +#define ONE_MB_BRW_SIZE BIT(LNET_MTU_BITS) >> +#define MD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) >> #define MD_MAX_BRW_PAGES (MD_MAX_BRW_SIZE >> PAGE_SHIFT) >> #define DT_MAX_BRW_SIZE PTLRPC_MAX_BRW_SIZE >> #define DT_MAX_BRW_PAGES (DT_MAX_BRW_SIZE >> PAGE_SHIFT) >> -#define OFD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) >> +#define OFD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) > > Argg!! No!! Names are important. > "SIZE" means the value is a size, a number. The bit-representation is > largely irrelevant, it is the number that is important. > BIT(x) returns a single bit - lots of zeros and just one '1' bit. This > is not a number, it is a bit pattern. > > So settings FOO_SIZE to BIT(bar) is wrong. It is a type error. It uses > a bit pattern when a number is expected. The C compiler won't notice, but I will. > > When I apply this (which probably won't be until next week), I'll just > remove this section of the patch. Just to confirm, my original patch didn't have these BIT() macros in it, and I agree with your statements, so I'm fine with you removing them again. >> diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c >> index 6c9fe49..d3b0445 100644 >> --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c >> +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c >> @@ -267,27 +267,22 @@ void cl_inode_fini(struct inode *inode) >> /** >> * build inode number from passed @fid >> */ >> -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) >> +u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) >> { >> if (BITS_PER_LONG == 32 || api32) >> return fid_flatten32(fid); >> - else >> - return fid_flatten(fid); >> + >> + return fid_flatten(fid); > > I preferred that as it was - it makes the either/or nature more obvious. Kernel style generally recommends no "else" after a return, and checkpatch.pl will complain in this case. Cheers, Andreas --- Andreas Dilger Principal Lustre Architect Whamcloud -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 235 bytes Desc: Message signed with OpenPGP URL: From neilb at suse.com Mon Sep 24 03:20:50 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 13:20:50 +1000 Subject: [lustre-devel] [PATCH 01/30] lustre: lnd: resolve IP query code in LND drivers In-Reply-To: <1537205440-6656-2-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-2-git-send-email-jsimmons@infradead.org> Message-ID: <87bm8n60od.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > The recent IP querying code that landed to both ksocklnd and > ko2iblnd have some bugs that prevent proper setup. The first > bug in both drivers is that the IP address of ifa_local is in > big endian format so on little endian systems the IP address > is incorrect. Calling ntohl() on ifa_local gets the real IP > address. The second bug located in ko2iblnd is that in_dev is > always NULL. Add the call __in_dev_get_rtnl() to get in_dev > and use that information to query the IP address. Thanks! I've added: Fixes: 10e138e41a43 ("lustre: o2iblnd: get IP address more directly.") Fixes: f703f71afd98 ("lustre: socklnd: use for_each_netdev() instead of lnet_ipif_enumerate()") and applied this. NeilBrown > > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 12 +++++++++--- > drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 2 +- > 2 files changed, 10 insertions(+), 4 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index 15953e4..6874e53 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -2468,8 +2468,7 @@ static struct kib_dev *kiblnd_create_dev(char *ifname) > flags = dev_get_flags(netdev); > if (!(flags & IFF_UP)) { > CERROR("Can't query IPoIB interface %s: it's down\n", ifname); > - rtnl_unlock(); > - return NULL; > + goto unlock; > } > > dev = kzalloc(sizeof(*dev), GFP_NOFS); > @@ -2481,9 +2480,16 @@ static struct kib_dev *kiblnd_create_dev(char *ifname) > INIT_LIST_HEAD(&dev->ibd_nets); > INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */ > INIT_LIST_HEAD(&dev->ibd_fail_list); > + > + in_dev = __in_dev_get_rtnl(netdev); > + if (!in_dev) { > + kfree(dev); > + goto unlock; > + } > + > for_primary_ifa(in_dev) > if (strcmp(ifa->ifa_label, ifname) == 0) { > - dev->ibd_ifip = ifa->ifa_local; > + dev->ibd_ifip = ntohl(ifa->ifa_local); > break; > } > endfor_ifa(in_dev); > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 5b81040..750a7ce 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -2589,7 +2589,7 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) > } > for_primary_ifa(in_dev) > if (strcmp(ifa->ifa_label, name) == 0) { > - ksi->ksni_ipaddr = ifa->ifa_local; > + ksi->ksni_ipaddr = ntohl(ifa->ifa_local); > ksi->ksni_netmask = ifa->ifa_mask; > strlcpy(ksi->ksni_name, > name, sizeof(ksi->ksni_name)); > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 03:35:36 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 13:35:36 +1000 Subject: [lustre-devel] [PATCH 08/30] lustre: mgc: Remove unnecessary checks for config_log_put() In-Reply-To: <1537205440-6656-9-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-9-git-send-email-jsimmons@infradead.org> Message-ID: <878t3r5zzr.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > From: Steve Guminski > > Make config_log_put() check if its parameter is NULL, which makes > it is unnecessary to perform the check prior to calling it. > This patch removes the redundant checks. > > Signed-off-by: Steve Guminski > WC-bug-id: https://jira.whamcloud.com/browse/LU-9152 > Reviewed-on: https://review.whamcloud.com/25854 > Reviewed-by: Bob Glossman > Reviewed-by: Andreas Dilger > Reviewed-by: James Simmons > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lustre/mgc/mgc_request.c | 36 +++++++++++-------------- > 1 file changed, 16 insertions(+), 20 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c > index 4552cc5..e6f8d9e 100644 > --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c > +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c > @@ -131,6 +131,9 @@ static int config_log_get(struct config_llog_data *cld) > */ > static void config_log_put(struct config_llog_data *cld) > { > + if (unlikely(!cld)) > + return; > + I've removed the "unlikely()" call. Partly because use of likely/unlikely is discouraged where the difference cannot be measured (or clearly justified some other way), and partly because ..... > @@ -387,6 +387,9 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, > > static inline void config_mark_cld_stop(struct config_llog_data *cld) > { > + if (!cld) > + return; > + .... there is no "unlikely()" here, and I like consistency. Thanks, NeilBrown > mutex_lock(&cld->cld_lock); > spin_lock(&config_list_lock); > cld->cld_stopping = 1; > @@ -436,18 +439,13 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg) > cld->cld_sptlrpc = NULL; > mutex_unlock(&cld->cld_lock); > > - if (cld_recover) { > - config_mark_cld_stop(cld_recover); > - config_log_put(cld_recover); > - } > + config_mark_cld_stop(cld_recover); > + config_log_put(cld_recover); > > - if (cld_params) { > - config_mark_cld_stop(cld_params); > - config_log_put(cld_params); > - } > + config_mark_cld_stop(cld_params); > + config_log_put(cld_params); > > - if (cld_sptlrpc) > - config_log_put(cld_sptlrpc); > + config_log_put(cld_sptlrpc); > > /* drop the ref from the find */ > config_log_put(cld); > @@ -593,8 +591,7 @@ static int mgc_requeue_thread(void *data) > cld->cld_lostlock = 0; > spin_unlock(&config_list_lock); > > - if (cld_prev) > - config_log_put(cld_prev); > + config_log_put(cld_prev); > cld_prev = cld; > > if (likely(!(rq_state & RQ_STOP))) { > @@ -606,8 +603,7 @@ static int mgc_requeue_thread(void *data) > } > } > spin_unlock(&config_list_lock); > - if (cld_prev) > - config_log_put(cld_prev); > + config_log_put(cld_prev); > > /* Wait a bit to see if anyone else needs a requeue */ > wait_event_idle(rq_waitq, rq_state & (RQ_NOW | RQ_STOP)); > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 03:50:32 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 13:50:32 +1000 Subject: [lustre-devel] [PATCH 11/30] lustre: mdc: allow setting readdir RPC size parameter In-Reply-To: <7503F4FB-D93E-4CD1-9DF3-C00C51528E93@whamcloud.com> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-12-git-send-email-jsimmons@infradead.org> <8736u76j7g.fsf@notabene.neil.brown.name> <7503F4FB-D93E-4CD1-9DF3-C00C51528E93@whamcloud.com> Message-ID: <875zyv5zav.fsf@notabene.neil.brown.name> On Thu, Sep 20 2018, Andreas Dilger wrote: > On Sep 18, 2018, at 09:14, NeilBrown wrote: >> >> On Mon, Sep 17 2018, James Simmons wrote: >> >>> From: Andreas Dilger >>> >>> diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h >>> index 2dbd208..cf630db 100644 >>> --- a/drivers/staging/lustre/lustre/include/lustre_net.h >>> +++ b/drivers/staging/lustre/lustre/include/lustre_net.h >>> @@ -104,15 +104,15 @@ >>> * currently supported maximum between peers at connect via ocd_brw_size. >>> */ >>> #define PTLRPC_MAX_BRW_BITS (LNET_MTU_BITS + PTLRPC_BULK_OPS_BITS) >>> -#define PTLRPC_MAX_BRW_SIZE (1 << PTLRPC_MAX_BRW_BITS) >>> +#define PTLRPC_MAX_BRW_SIZE BIT(PTLRPC_MAX_BRW_BITS) >>> #define PTLRPC_MAX_BRW_PAGES (PTLRPC_MAX_BRW_SIZE >> PAGE_SHIFT) >>> >>> -#define ONE_MB_BRW_SIZE (1 << LNET_MTU_BITS) >>> -#define MD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) >>> +#define ONE_MB_BRW_SIZE BIT(LNET_MTU_BITS) >>> +#define MD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) >>> #define MD_MAX_BRW_PAGES (MD_MAX_BRW_SIZE >> PAGE_SHIFT) >>> #define DT_MAX_BRW_SIZE PTLRPC_MAX_BRW_SIZE >>> #define DT_MAX_BRW_PAGES (DT_MAX_BRW_SIZE >> PAGE_SHIFT) >>> -#define OFD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) >>> +#define OFD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) >> >> Argg!! No!! Names are important. >> "SIZE" means the value is a size, a number. The bit-representation is >> largely irrelevant, it is the number that is important. >> BIT(x) returns a single bit - lots of zeros and just one '1' bit. This >> is not a number, it is a bit pattern. >> >> So settings FOO_SIZE to BIT(bar) is wrong. It is a type error. It uses >> a bit pattern when a number is expected. The C compiler won't notice, but I will. >> >> When I apply this (which probably won't be until next week), I'll just >> remove this section of the patch. > > Just to confirm, my original patch didn't have these BIT() macros in it, > and I agree with your statements, so I'm fine with you removing them > again. Good. They are gone. > >>> diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c >>> index 6c9fe49..d3b0445 100644 >>> --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c >>> +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c >>> @@ -267,27 +267,22 @@ void cl_inode_fini(struct inode *inode) >>> /** >>> * build inode number from passed @fid >>> */ >>> -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) >>> +u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) >>> { >>> if (BITS_PER_LONG == 32 || api32) >>> return fid_flatten32(fid); >>> - else >>> - return fid_flatten(fid); >>> + >>> + return fid_flatten(fid); >> >> I preferred that as it was - it makes the either/or nature more obvious. > > Kernel style generally recommends no "else" after a return, and checkpatch.pl will complain in this case. I just ran checkpatch.pl --file drivers/staging/lustre/lustre/llite/lcommon_cl.c without this patch applied, and it didn't complain. I've removed this section of the patch because it seems to be unrelated to the rest of the patch, and because I don't like it. Thanks, NeilBrown > > Cheers, Andreas > --- > Andreas Dilger > Principal Lustre Architect > Whamcloud -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 03:58:00 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 13:58:00 +1000 Subject: [lustre-devel] [PATCH 12/30] lustre: kuc: initialize kkuc_groups at module init time In-Reply-To: <1537205440-6656-13-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-13-git-send-email-jsimmons@infradead.org> Message-ID: <8736tz5yyf.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > From: "John L. Hammond" > > Some kkuc functions use kkuc_groups[group].next == NULL to test for an > empty group list. This is incorrect if the group was previously added > to but not empty. Remove all next == NULL tests and use module load > time initialization of the kkuc_groups array. > > Signed-off-by: John L. Hammond > WC-bug-id: https://jira.whamcloud.com/browse/LU-9306 > Reviewed-on: https://review.whamcloud.com/26883 > Reviewed-by: Frank Zago > Reviewed-by: Faccini Bruno > Reviewed-by: Henri Doreau > Reviewed-by: Quentin Bouget > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > .../lustre/lustre/include/lustre_kernelcomm.h | 1 + > drivers/staging/lustre/lustre/obdclass/class_obd.c | 3 ++ > .../staging/lustre/lustre/obdclass/kernelcomm.c | 38 +++++++++++++++------- > 3 files changed, 30 insertions(+), 12 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h b/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h > index 2b3fa84..8e3a990 100644 > --- a/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h > +++ b/drivers/staging/lustre/lustre/include/lustre_kernelcomm.h > @@ -45,6 +45,7 @@ > typedef int (*libcfs_kkuc_cb_t)(void *data, void *cb_arg); > > /* Kernel methods */ > +void libcfs_kkuc_init(void); > int libcfs_kkuc_msg_put(struct file *fp, void *payload); > int libcfs_kkuc_group_put(unsigned int group, void *payload); > int libcfs_kkuc_group_add(struct file *fp, int uid, unsigned int group, > diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c > index eabaafe..2d23608 100644 > --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c > +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c > @@ -42,6 +42,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -664,6 +665,8 @@ static int __init obdclass_init(void) > if (err) > return err; > > + libcfs_kkuc_init(); > + > err = obd_zombie_impexp_init(); > if (err) > return err; > diff --git a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c > index 304288d..0fcfecf 100644 > --- a/drivers/staging/lustre/lustre/obdclass/kernelcomm.c > +++ b/drivers/staging/lustre/lustre/obdclass/kernelcomm.c > @@ -96,10 +96,23 @@ struct kkuc_reg { > char kr_data[0]; > }; > > -static struct list_head kkuc_groups[KUC_GRP_MAX + 1] = {}; > +static struct list_head kkuc_groups[KUC_GRP_MAX + 1]; > /* Protect message sending against remove and adds */ > static DECLARE_RWSEM(kg_sem); > > +static inline bool libcfs_kkuc_group_is_valid(int group) > +{ > + return 0 <= group && group < ARRAY_SIZE(kkuc_groups); > +} libcfs_kkuc_group_is_valid() is only ever passed an unsigned int. So I've changed it to expect one, and removed the comparison against 0 which is now pointless. Thanks, NeilBrown > + > +void libcfs_kkuc_init(void) > +{ > + int group; > + > + for (group = 0; group < ARRAY_SIZE(kkuc_groups); group++) > + INIT_LIST_HEAD(&kkuc_groups[group]); > +} > + > /** Add a receiver to a broadcast group > * @param filp pipe to write into > * @param uid identifier for this receiver > @@ -111,7 +124,7 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, unsigned int group, > { > struct kkuc_reg *reg; > > - if (group > KUC_GRP_MAX) { > + if (!libcfs_kkuc_group_is_valid(group)) { > CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); > return -EINVAL; > } > @@ -130,8 +143,6 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, unsigned int group, > memcpy(reg->kr_data, data, data_len); > > down_write(&kg_sem); > - if (!kkuc_groups[group].next) > - INIT_LIST_HEAD(&kkuc_groups[group]); > list_add(®->kr_chain, &kkuc_groups[group]); > up_write(&kg_sem); > > @@ -145,8 +156,10 @@ int libcfs_kkuc_group_rem(int uid, unsigned int group) > { > struct kkuc_reg *reg, *next; > > - if (!kkuc_groups[group].next) > - return 0; > + if (!libcfs_kkuc_group_is_valid(group)) { > + CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); > + return -EINVAL; > + } > > if (!uid) { > /* Broadcast a shutdown message */ > @@ -182,9 +195,14 @@ int libcfs_kkuc_group_put(unsigned int group, void *payload) > int rc = 0; > int one_success = 0; > > + if (!libcfs_kkuc_group_is_valid(group)) { > + CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); > + return -EINVAL; > + } > + > down_write(&kg_sem); > > - if (unlikely(!kkuc_groups[group].next) || > + if (unlikely(list_empty(&kkuc_groups[group])) || > unlikely(OBD_FAIL_CHECK(OBD_FAIL_MDS_HSM_CT_REGISTER_NET))) { > /* no agent have fully registered, CDT will retry */ > up_write(&kg_sem); > @@ -227,15 +245,11 @@ int libcfs_kkuc_group_foreach(unsigned int group, libcfs_kkuc_cb_t cb_func, > struct kkuc_reg *reg; > int rc = 0; > > - if (group > KUC_GRP_MAX) { > + if (!libcfs_kkuc_group_is_valid(group)) { > CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); > return -EINVAL; > } > > - /* no link for this group */ > - if (!kkuc_groups[group].next) > - return 0; > - > down_read(&kg_sem); > list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { > if (reg->kr_fp) > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 04:09:01 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 14:09:01 +1000 Subject: [lustre-devel] [PATCH 17/30] lustre: llite: protect ll_dentry_data modification In-Reply-To: <1537205440-6656-18-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-18-git-send-email-jsimmons@infradead.org> Message-ID: <87zhw74jvm.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > From: Andriy Skulysh > > The ll_dentry_data bitfields modification should be protected by > a spinlock. > > Signed-off-by: Andriy Skulysh > Signed-off-by: Lai Siyao > WC-bug-id: https://jira.whamcloud.com/browse/LU-9241 > Seagate-bug-id: MRP-4257 > Reviewed-on: https://review.whamcloud.com/26109 > Reviewed-by: Niu Yawei > Reviewed-by: Bobi Jam > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lustre/llite/llite_nfs.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c > index c66072a..5e91e83 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c > +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c > @@ -171,8 +171,9 @@ struct lustre_nfs_fid { > * we came from NFS and so opencache needs to be > * enabled for this one > */ > + spin_lock(&result->d_lock); > ll_d2d(result)->lld_nfs_dentry = 1; > - > + spin_unlock(&result->d_lock); > return result; > } This is a bit weird.... I agree that having a spinlock is needed as the compiler does an R/M/W to update the bitfield, and that could race with updats to lld_invalid (and I think that is a good arguement to avoid bitfields in shared structures). However lld_nfs_dentry is never used. The only use was removed by Commit: c1b66fccf986 ("staging: lustre: fid: do open-by-fid by default") The corresponding commit upstream is Commit: cb85c0364fd8 ("LU-3544 fid: do open-by-fid by default") and that commit doesn't remove the use of lld_nfs_dentry. Maybe because lld_nfs_dentry didn't exist then - it wasn't added until later by 65d0add6057b138. So do we need to bring lld_nfs_dentry back? Thanks, NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 04:11:52 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 14:11:52 +1000 Subject: [lustre-devel] [PATCH 18/30] lustre: llite: llite.stat_blocksize param for fixed st_blksize In-Reply-To: <1537205440-6656-19-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-19-git-send-email-jsimmons@infradead.org> Message-ID: <87worb4jqv.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > From: Andrew Perepechko > > llite.stat_blocksize is added to allow configurable st_blksize > for stat(2). The latter is treated incorrectly by some > applications. For example, glibc pre-2.25 uses this value for > stdio buffering which completely ruins performance with random > reads. > > The patch changes the behaviour of getattr rather than inode > initialization so that change of the setting causes immediate > effect without the need of reclaiming existing inodes. > > The patch is similar to the patch from bz # 12739 by Aurelien > Degremont. > > Signed-off-by: Andrew Perepechko > WC-bug-id: https://jira.whamcloud.com/browse/LU-9413 > Reviewed-on: https://review.whamcloud.com/26869 > Reviewed-by: Alexander Zarochentsev > Reviewed-by: Andreas Dilger > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lustre/llite/file.c | 2 +- > .../staging/lustre/lustre/llite/llite_internal.h | 6 +++- > drivers/staging/lustre/lustre/llite/lproc_llite.c | 33 ++++++++++++++++++++++ > 3 files changed, 39 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c > index b90c59c..94760eb 100644 > --- a/drivers/staging/lustre/lustre/llite/file.c > +++ b/drivers/staging/lustre/lustre/llite/file.c > @@ -3267,7 +3267,7 @@ int ll_getattr(const struct path *path, struct kstat *stat, > stat->atime = inode->i_atime; > stat->mtime = inode->i_mtime; > stat->ctime = inode->i_ctime; > - stat->blksize = 1 << inode->i_blkbits; > + stat->blksize = sbi->ll_stat_blksize ?: BIT(inode->i_blkbits); I replaced the BIT() with (1<< ). Thanks, NeilBrown > > stat->nlink = inode->i_nlink; > stat->size = i_size_read(inode); > diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h > index 9d9f623..dcb2fed 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_internal.h > +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h > @@ -523,7 +523,11 @@ struct ll_sb_info { > struct root_squash_info ll_squash; > struct path ll_mnt; > > - __kernel_fsid_t ll_fsid; > + /* st_blksize returned by stat(2), when non-zero */ > + unsigned int ll_stat_blksize; > + > + __kernel_fsid_t ll_fsid; > + > struct kset ll_kset; /* sysfs object */ > struct completion ll_kobj_unregister; > }; > diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c > index f775b4f..d8ef090 100644 > --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c > +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c > @@ -128,6 +128,38 @@ static ssize_t blocksize_show(struct kobject *kobj, struct attribute *attr, > } > LUSTRE_RO_ATTR(blocksize); > > +static ssize_t stat_blocksize_show(struct kobject *kobj, struct attribute *attr, > + char *buf) > +{ > + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, > + ll_kset.kobj); > + > + return sprintf(buf, "%u\n", sbi->ll_stat_blksize); > +} > + > +static ssize_t stat_blocksize_store(struct kobject *kobj, > + struct attribute *attr, > + const char *buffer, > + size_t count) > +{ > + struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info, > + ll_kset.kobj); > + unsigned int val; > + int rc; > + > + rc = kstrtouint(buffer, 10, &val); > + if (rc) > + return rc; > + > + if (val != 0 && (val < PAGE_SIZE || (val & (val - 1))) != 0) > + return -ERANGE; > + > + sbi->ll_stat_blksize = val; > + > + return count; > +} > +LUSTRE_RW_ATTR(stat_blocksize); > + > static ssize_t kbytestotal_show(struct kobject *kobj, struct attribute *attr, > char *buf) > { > @@ -1123,6 +1155,7 @@ static ssize_t ll_nosquash_nids_seq_write(struct file *file, > > static struct attribute *llite_attrs[] = { > &lustre_attr_blocksize.attr, > + &lustre_attr_stat_blocksize.attr, > &lustre_attr_kbytestotal.attr, > &lustre_attr_kbytesfree.attr, > &lustre_attr_kbytesavail.attr, > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 04:17:32 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 14:17:32 +1000 Subject: [lustre-devel] [PATCH 21/30] lustre: ldlm: use static initializer macros where possible In-Reply-To: <1537205440-6656-22-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-22-git-send-email-jsimmons@infradead.org> Message-ID: <87tvmf4jhf.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > From: "John L. Hammond" > > In lustre/ldlm/ replace module load time initialization of several > mutexes with static initialization using the kernel provided macros. > > Signed-off-by: John L. Hammond > WC-bug-id: https://jira.whamcloud.com/browse/LU-9010 > Reviewed-on: https://review.whamcloud.com/24824 > Reviewed-by: Dmitry Eremin > Reviewed-by: James Simmons > Reviewed-by: Andreas Dilger > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lustre/include/lustre_dlm.h | 3 +-- > drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c | 6 +----- > drivers/staging/lustre/lustre/ldlm/ldlm_resource.c | 4 ++-- > 3 files changed, 4 insertions(+), 9 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h > index a68c7a4..e2bbcaa 100644 > --- a/drivers/staging/lustre/lustre/include/lustre_dlm.h > +++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h > @@ -742,8 +742,7 @@ struct ldlm_lock { > * The lists this could be linked into are: > * waiting_locks_list (protected by waiting_locks_spinlock), > * then if the lock timed out, it is moved to > - * expired_lock_thread.elt_expired_locks for further processing. > - * Protected by elt_lock. > + * expired_lock_list for further processing. > */ > struct list_head l_pending_chain; > > diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c > index a8de3d9..986c378 100644 > --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c > +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c > @@ -53,7 +53,7 @@ > module_param(ldlm_cpts, charp, 0444); > MODULE_PARM_DESC(ldlm_cpts, "CPU partitions ldlm threads should run on"); > > -static struct mutex ldlm_ref_mutex; > +static DEFINE_MUTEX(ldlm_ref_mutex); > static int ldlm_refcount; > > static struct kobject *ldlm_kobj; > @@ -69,10 +69,6 @@ struct ldlm_cb_async_args { > > static struct ldlm_state *ldlm_state; > > -#define ELT_STOPPED 0 > -#define ELT_READY 1 > -#define ELT_TERMINATE 2 > - Arg... Why do people do this??? One patch - one change. This change is irrelevant to this patch, so it just makes it harder to review. Grumble. NeilBrown > struct ldlm_bl_pool { > spinlock_t blp_lock; > > diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c > index 1907a5a..bd5622d 100644 > --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c > +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c > @@ -49,10 +49,10 @@ > int ldlm_srv_namespace_nr; > int ldlm_cli_namespace_nr; > > -struct mutex ldlm_srv_namespace_lock; > +DEFINE_MUTEX(ldlm_srv_namespace_lock); > LIST_HEAD(ldlm_srv_namespace_list); > > -struct mutex ldlm_cli_namespace_lock; > +DEFINE_MUTEX(ldlm_cli_namespace_lock); > /* Client Namespaces that have active resources in them. > * Once all resources go away, ldlm_poold moves such namespaces to the > * inactive list > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 04:22:23 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 14:22:23 +1000 Subject: [lustre-devel] [PATCH 24/30] lustre: llite: rcu-walk check should not depend on statahead In-Reply-To: <1537205440-6656-25-git-send-email-jsimmons@infradead.org> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-25-git-send-email-jsimmons@infradead.org> Message-ID: <87r2hj4j9c.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > From: Steve Guminski > > Moves the check for the LOOKUP_RCU flag, so that it does not depend > on the statahead setting. The caller is now informed if rcu-walk > was requested but the filesystem does not support it, regardless > of whether statahead is enabled or disabled. Nope, this is wrong. The filesystem only returns -ECHILD if it couldn't complete the request because it would have to block. If statahead is disabled, then it can complete the request immediately, doesn't need to block, and so doesn't need to return -ECHILD. Patch deleted. Thanks, NeilBrown > > Signed-off-by: Steve Guminski > WC-bug-id: https://jira.whamcloud.com/browse/LU-8891 > Reviewed-on: https://review.whamcloud.com/24195 > Reviewed-by: John L. Hammond > Reviewed-by: Andreas Dilger > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lustre/llite/dcache.c | 7 +++---- > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c > index 11b82c63..ee1ba16 100644 > --- a/drivers/staging/lustre/lustre/llite/dcache.c > +++ b/drivers/staging/lustre/lustre/llite/dcache.c > @@ -270,13 +270,12 @@ static int ll_revalidate_dentry(struct dentry *dentry, > if (lookup_flags & LOOKUP_REVAL) > return 0; > > - if (!dentry_may_statahead(dir, dentry)) > - return 1; > - > if (lookup_flags & LOOKUP_RCU) > return -ECHILD; > > - ll_statahead(dir, &dentry, !d_inode(dentry)); > + if (dentry_may_statahead(dir, dentry)) > + ll_statahead(dir, &dentry, !d_inode(dentry)); > + > return 1; > } > > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 04:47:50 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 14:47:50 +1000 Subject: [lustre-devel] [PATCH 4/8] lustre: obdclass: cleanup obd_class.h defines In-Reply-To: <920C9E0E-A2EB-483E-ACB8-0AE680C02CD6@cray.com> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> <1537205481-6899-5-git-send-email-jsimmons@infradead.org> <920C9E0E-A2EB-483E-ACB8-0AE680C02CD6@cray.com> Message-ID: <87o9cn4i2x.fsf@notabene.neil.brown.name> On Tue, Sep 18 2018, Alexey Lyashkov wrote: > NAK. > Please use same as original patch > ' struct niobuf_local *local, int orig_rc' vs ' struct niobuf_local *local, const int orig_rc'. > I've added the "const" and appled the patch. Thanks. NeilBrown > > > On 17/09/2018, 20:31, "James Simmons" wrote: > > From: Ben Evans > > Get rid of OBT and CTXTP defines. > Remove OBD_CHECK_DT_OP > Convert EXP_CHECK_MD_OP into a function. > Remove CTXT_CHECK_OP. > > Signed-off-by: Ben Evans > Signed-off-by: Alexey Lyashkov > WC-bug-id: https://jira.whamcloud.com/browse/LU-9855 > Reviewed-on: https://review.whamcloud.com/29286 > WC-bug-id: https://jira.whamcloud.com/browse/LU-11169 > Reviewed-on: https://review.whamcloud.com/#/c/32906 > Reviewed-by: John L. Hammond > Reviewed-by: Steve Guminski > Reviewed-by: James Simmons > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lustre/include/obd_class.h | 437 +++++++++++++++------- > drivers/staging/lustre/lustre/obdclass/llog_obd.c | 4 +- > 2 files changed, 311 insertions(+), 130 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h > index c6fb2e1..aab1092 100644 > --- a/drivers/staging/lustre/lustre/include/obd_class.h > +++ b/drivers/staging/lustre/lustre/include/obd_class.h > @@ -303,10 +303,8 @@ static inline int lprocfs_climp_check(struct obd_device *obd) > > void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj); > > -#define OBT(dev) ((dev)->obd_type) > #define OBP(dev, op) ((dev)->obd_type->typ_dt_ops->op) > #define MDP(dev, op) ((dev)->obd_type->typ_md_ops->op) > -#define CTXTP(ctxt, op) ((ctxt)->loc_logops->lop_##op) > > /* > * Ensure obd_setup: used for cleanup which must be called > @@ -393,56 +391,16 @@ static inline int obd_check_dev_active(struct obd_device *obd) > } \ > } while (0) > > -#define EXP_CHECK_MD_OP(exp, op) \ > -do { \ > - if (!(exp)) { \ > - CERROR("obd_" #op ": NULL export\n"); \ > - return -ENODEV; \ > - } \ > - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ > - CERROR("obd_" #op ": cleaned up obd\n"); \ > - return -EOPNOTSUPP; \ > - } \ > - if (!OBT((exp)->exp_obd) || !MDP((exp)->exp_obd, op)) { \ > - CERROR("%s: obd_" #op ": dev %d no operation\n",\ > - (exp)->exp_obd->obd_name, \ > - (exp)->exp_obd->obd_minor); \ > - return -EOPNOTSUPP; \ > - } \ > -} while (0) > - > -#define OBD_CHECK_DT_OP(obd, op, err) \ > -do { \ > - if (!OBT(obd) || !OBP((obd), op)) { \ > - if (err) \ > - CERROR("%s: no obd_" #op " operation\n", \ > - obd->obd_name); \ > - return err; \ > - } \ > -} while (0) > +static inline int exp_check_ops(struct obd_export *exp) > +{ > + if (!exp) > + return -ENODEV; > > -#define EXP_CHECK_DT_OP(exp, op) \ > -do { \ > - if (!(exp)) { \ > - CERROR("obd_" #op ": NULL export\n"); \ > - return -ENODEV; \ > - } \ > - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ > - CERROR("obd_" #op ": cleaned up obd\n"); \ > - return -EOPNOTSUPP; \ > - } \ > - OBD_CHECK_DT_OP((exp)->exp_obd, op, -EOPNOTSUPP); \ > -} while (0) > + if (!exp->exp_obd || !exp->exp_obd->obd_type) > + return -EOPNOTSUPP; > > -#define CTXT_CHECK_OP(ctxt, op, err) \ > -do { \ > - if (!OBT(ctxt->loc_obd) || !CTXTP((ctxt), op)) { \ > - if (err) \ > - CERROR("%s: no lop_" #op " operation\n", \ > - ctxt->loc_obd->obd_name); \ > - return err; \ > - } \ > -} while (0) > + return 0; > +} > > static inline int class_devno_max(void) > { > @@ -455,7 +413,15 @@ static inline int obd_get_info(const struct lu_env *env, > { > int rc; > > - EXP_CHECK_DT_OP(exp, get_info); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->get_info) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, get_info); > > rc = OBP(exp->exp_obd, get_info)(env, exp, keylen, key, vallen, val); > @@ -469,7 +435,15 @@ static inline int obd_set_info_async(const struct lu_env *env, > { > int rc; > > - EXP_CHECK_DT_OP(exp, set_info_async); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->set_info_async) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, set_info_async); > > rc = OBP(exp->exp_obd, set_info_async)(env, exp, keylen, key, vallen, > @@ -484,14 +458,14 @@ static inline int obd_set_info_async(const struct lu_env *env, > * pieces of configuration process are still based on obd devices. > * > * Specifically, lu_device_type_operations::ldto_device_alloc() methods fully > - * subsume ->o_setup() methods of obd devices they replace. The same for > - * lu_device_operations::ldo_process_config() and ->o_process_config(). As a > + * subsume ->setup() methods of obd devices they replace. The same for > + * lu_device_operations::ldo_process_config() and ->process_config(). As a > * result, obd_setup() and obd_process_config() branch and call one XOR > * another. > * > * Yet neither lu_device_type_operations::ldto_device_fini() nor > * lu_device_type_operations::ldto_device_free() fully implement the > - * functionality of ->o_precleanup() and ->o_cleanup() they override. Hence, > + * functionality of ->precleanup() and ->o_cleanup() they override. Hence, > * obd_precleanup() and obd_cleanup() call both lu_device and obd operations. > */ > > @@ -527,7 +501,11 @@ static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) > lu_context_fini(&session_ctx); > > } else { > - OBD_CHECK_DT_OP(obd, setup, -EOPNOTSUPP); > + if (!obd->obd_type->typ_dt_ops->setup) { > + CERROR("%s: no %s operation\n", obd->obd_name, > + __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, setup); > rc = OBP(obd, setup)(obd, cfg); > } > @@ -549,7 +527,9 @@ static inline int obd_precleanup(struct obd_device *obd) > lu_env_fini(&env); > } > } > - OBD_CHECK_DT_OP(obd, precleanup, 0); > + if (!obd->obd_type->typ_dt_ops->precleanup) > + return 0; > + > OBD_COUNTER_INCREMENT(obd, precleanup); > > rc = OBP(obd, precleanup)(obd); > @@ -572,7 +552,9 @@ static inline int obd_cleanup(struct obd_device *obd) > obd->obd_lu_dev = NULL; > } > } > - OBD_CHECK_DT_OP(obd, cleanup, 0); > + if (!obd->obd_type->typ_dt_ops->cleanup) > + return 0; > + > OBD_COUNTER_INCREMENT(obd, cleanup); > > rc = OBP(obd, cleanup)(obd); > @@ -599,8 +581,8 @@ static inline void obd_cleanup_client_import(struct obd_device *obd) > up_write(&obd->u.cli.cl_sem); > } > > -static inline int > -obd_process_config(struct obd_device *obd, int datalen, void *data) > +static inline int obd_process_config(struct obd_device *obd, int datalen, > + void *data) > { > struct lu_device_type *ldt = obd->obd_type->typ_lu; > struct lu_device *d = obd->obd_lu_dev; > @@ -616,7 +598,11 @@ static inline void obd_cleanup_client_import(struct obd_device *obd) > lu_env_fini(&env); > } > } else { > - OBD_CHECK_DT_OP(obd, process_config, -EOPNOTSUPP); > + if (!obd->obd_type->typ_dt_ops->process_config) { > + CERROR("%s: no %s operation\n", > + obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > rc = OBP(obd, process_config)(obd, datalen, data); > } > OBD_COUNTER_INCREMENT(obd, process_config); > @@ -630,7 +616,15 @@ static inline int obd_create(const struct lu_env *env, struct obd_export *exp, > { > int rc; > > - EXP_CHECK_DT_OP(exp, create); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->create) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, create); > > rc = OBP(exp->exp_obd, create)(env, exp, obdo); > @@ -642,7 +636,15 @@ static inline int obd_destroy(const struct lu_env *env, struct obd_export *exp, > { > int rc; > > - EXP_CHECK_DT_OP(exp, destroy); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->destroy) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, destroy); > > rc = OBP(exp->exp_obd, destroy)(env, exp, obdo); > @@ -654,7 +656,15 @@ static inline int obd_getattr(const struct lu_env *env, struct obd_export *exp, > { > int rc; > > - EXP_CHECK_DT_OP(exp, getattr); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->getattr) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, getattr); > > rc = OBP(exp->exp_obd, getattr)(env, exp, oa); > @@ -666,7 +676,15 @@ static inline int obd_setattr(const struct lu_env *env, struct obd_export *exp, > { > int rc; > > - EXP_CHECK_DT_OP(exp, setattr); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->setattr) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, setattr); > > rc = OBP(exp->exp_obd, setattr)(env, exp, oa); > @@ -682,7 +700,11 @@ static inline int obd_add_conn(struct obd_import *imp, struct obd_uuid *uuid, > rc = obd_check_dev_active(obd); > if (rc) > return rc; > - OBD_CHECK_DT_OP(obd, add_conn, -EOPNOTSUPP); > + > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->add_conn) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, add_conn); > > rc = OBP(obd, add_conn)(imp, uuid, priority); > @@ -697,7 +719,11 @@ static inline int obd_del_conn(struct obd_import *imp, struct obd_uuid *uuid) > rc = obd_check_dev_active(obd); > if (rc) > return rc; > - OBD_CHECK_DT_OP(obd, del_conn, -EOPNOTSUPP); > + > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->del_conn) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, del_conn); > > rc = OBP(obd, del_conn)(imp, uuid); > @@ -708,7 +734,10 @@ static inline struct obd_uuid *obd_get_uuid(struct obd_export *exp) > { > struct obd_uuid *uuid; > > - OBD_CHECK_DT_OP(exp->exp_obd, get_uuid, NULL); > + if (!exp->exp_obd->obd_type || > + !exp->exp_obd->obd_type->typ_dt_ops->get_uuid) > + return NULL; > + > EXP_COUNTER_INCREMENT(exp, get_uuid); > > uuid = OBP(exp->exp_obd, get_uuid)(exp); > @@ -727,16 +756,18 @@ static inline int obd_connect(const struct lu_env *env, > struct obd_connect_data *data, > void *localdata) > { > + /* for post-condition check */ > + u64 ocf = data ? data->ocd_connect_flags : 0; > int rc; > - __u64 ocf = data ? data->ocd_connect_flags : 0; /* > - * for post-condition > - * check > - */ > > rc = obd_check_dev_active(obd); > if (rc) > return rc; > - OBD_CHECK_DT_OP(obd, connect, -EOPNOTSUPP); > + > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->connect) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, connect); > > rc = OBP(obd, connect)(env, exp, obd, cluuid, data, localdata); > @@ -753,13 +784,16 @@ static inline int obd_reconnect(const struct lu_env *env, > struct obd_connect_data *d, > void *localdata) > { > + u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition check */ > int rc; > - __u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition check */ > > rc = obd_check_dev_active(obd); > if (rc) > return rc; > - OBD_CHECK_DT_OP(obd, reconnect, 0); > + > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->reconnect) > + return 0; > + > OBD_COUNTER_INCREMENT(obd, reconnect); > > rc = OBP(obd, reconnect)(env, exp, obd, cluuid, d, localdata); > @@ -772,7 +806,15 @@ static inline int obd_disconnect(struct obd_export *exp) > { > int rc; > > - EXP_CHECK_DT_OP(exp, disconnect); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->disconnect) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, disconnect); > > rc = OBP(exp->exp_obd, disconnect)(exp); > @@ -784,7 +826,8 @@ static inline int obd_fid_init(struct obd_device *obd, struct obd_export *exp, > { > int rc; > > - OBD_CHECK_DT_OP(obd, fid_init, 0); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_init) > + return 0; > OBD_COUNTER_INCREMENT(obd, fid_init); > > rc = OBP(obd, fid_init)(obd, exp, type); > @@ -795,7 +838,8 @@ static inline int obd_fid_fini(struct obd_device *obd) > { > int rc; > > - OBD_CHECK_DT_OP(obd, fid_fini, 0); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->fid_fini) > + return 0; > OBD_COUNTER_INCREMENT(obd, fid_fini); > > rc = OBP(obd, fid_fini)(obd); > @@ -809,7 +853,15 @@ static inline int obd_fid_alloc(const struct lu_env *env, > { > int rc; > > - EXP_CHECK_DT_OP(exp, fid_alloc); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->fid_alloc) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, fid_alloc); > > rc = OBP(exp->exp_obd, fid_alloc)(env, exp, fid, op_data); > @@ -820,7 +872,10 @@ static inline int obd_pool_new(struct obd_device *obd, char *poolname) > { > int rc; > > - OBD_CHECK_DT_OP(obd, pool_new, -EOPNOTSUPP); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_new) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, pool_new); > > rc = OBP(obd, pool_new)(obd, poolname); > @@ -831,20 +886,25 @@ static inline int obd_pool_del(struct obd_device *obd, char *poolname) > { > int rc; > > - OBD_CHECK_DT_OP(obd, pool_del, -EOPNOTSUPP); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_del) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, pool_del); > > rc = OBP(obd, pool_del)(obd, poolname); > return rc; > } > > -static inline int obd_pool_add(struct obd_device *obd, > - char *poolname, > +static inline int obd_pool_add(struct obd_device *obd, char *poolname, > char *ostname) > { > int rc; > > - OBD_CHECK_DT_OP(obd, pool_add, -EOPNOTSUPP); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_add) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, pool_add); > > rc = OBP(obd, pool_add)(obd, poolname, ostname); > @@ -857,7 +917,10 @@ static inline int obd_pool_rem(struct obd_device *obd, > { > int rc; > > - OBD_CHECK_DT_OP(obd, pool_rem, -EOPNOTSUPP); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->pool_rem) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, pool_rem); > > rc = OBP(obd, pool_rem)(obd, poolname, ostname); > @@ -866,7 +929,7 @@ static inline int obd_pool_rem(struct obd_device *obd, > > static inline void obd_getref(struct obd_device *obd) > { > - if (OBT(obd) && OBP(obd, getref)) { > + if (obd->obd_type && OBP(obd, getref)) { > OBD_COUNTER_INCREMENT(obd, getref); > OBP(obd, getref)(obd); > } > @@ -874,7 +937,7 @@ static inline void obd_getref(struct obd_device *obd) > > static inline void obd_putref(struct obd_device *obd) > { > - if (OBT(obd) && OBP(obd, putref)) { > + if (obd->obd_type && OBP(obd, putref)) { > OBD_COUNTER_INCREMENT(obd, putref); > OBP(obd, putref)(obd); > } > @@ -884,7 +947,7 @@ static inline int obd_init_export(struct obd_export *exp) > { > int rc = 0; > > - if ((exp)->exp_obd && OBT((exp)->exp_obd) && > + if (exp->exp_obd && exp->exp_obd->obd_type && > OBP((exp)->exp_obd, init_export)) > rc = OBP(exp->exp_obd, init_export)(exp); > return rc; > @@ -892,7 +955,7 @@ static inline int obd_init_export(struct obd_export *exp) > > static inline int obd_destroy_export(struct obd_export *exp) > { > - if ((exp)->exp_obd && OBT((exp)->exp_obd) && > + if (exp->exp_obd && exp->exp_obd->obd_type && > OBP((exp)->exp_obd, destroy_export)) > OBP(exp->exp_obd, destroy_export)(exp); > return 0; > @@ -915,7 +978,10 @@ static inline int obd_statfs_async(struct obd_export *exp, > return -EINVAL; > > obd = exp->exp_obd; > - OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->statfs) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, statfs); > > CDEBUG(D_SUPER, "%s: osfs %p age %llu, max_age %llu\n", > @@ -969,13 +1035,16 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp, > struct obd_statfs *osfs, __u64 max_age, > __u32 flags) > { > - int rc = 0; > struct obd_device *obd = exp->exp_obd; > + int rc = 0; > > if (!obd) > return -EINVAL; > > - OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP); > + if (!obd->obd_type || !obd->obd_type->typ_dt_ops->statfs) { > + CERROR("%s: no %s operation\n", obd->obd_name, __func__); > + return -EOPNOTSUPP; > + } > OBD_COUNTER_INCREMENT(obd, statfs); > > CDEBUG(D_SUPER, "osfs %llu, max_age %llu\n", > @@ -1009,7 +1078,15 @@ static inline int obd_preprw(const struct lu_env *env, int cmd, > { > int rc; > > - EXP_CHECK_DT_OP(exp, preprw); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->preprw) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, preprw); > > rc = OBP(exp->exp_obd, preprw)(env, cmd, exp, oa, objcount, obj, remote, > @@ -1021,13 +1098,23 @@ static inline int obd_commitrw(const struct lu_env *env, int cmd, > struct obd_export *exp, struct obdo *oa, > int objcount, struct obd_ioobj *obj, > struct niobuf_remote *rnb, int pages, > - struct niobuf_local *local, int rc) > + struct niobuf_local *local, int orig_rc) > { > - EXP_CHECK_DT_OP(exp, commitrw); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->commitrw) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, commitrw); > > rc = OBP(exp->exp_obd, commitrw)(env, cmd, exp, oa, objcount, obj, > - rnb, pages, local, rc); > + rnb, pages, local, orig_rc); > return rc; > } > > @@ -1036,7 +1123,15 @@ static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp, > { > int rc; > > - EXP_CHECK_DT_OP(exp, iocontrol); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->iocontrol) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, iocontrol); > > rc = OBP(exp->exp_obd, iocontrol)(cmd, exp, len, karg, uarg); > @@ -1108,7 +1203,15 @@ static inline int obd_quotactl(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_DT_OP(exp, quotactl); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > + > + if (!exp->exp_obd->obd_type->typ_dt_ops->quotactl) { > + CERROR("%s: no %s operation\n", > + exp->exp_obd->obd_name, __func__); > + return -ENOTSUPP; > + } > EXP_COUNTER_INCREMENT(exp, quotactl); > > rc = OBP(exp->exp_obd, quotactl)(exp->exp_obd, exp, oqctl); > @@ -1129,7 +1232,7 @@ static inline int obd_health_check(const struct lu_env *env, > int rc; > > /* don't use EXP_CHECK_DT_OP, because NULL method is normal here */ > - if (!obd || !OBT(obd)) { > + if (!obd || !obd->obd_type) { > CERROR("cleaned up obd\n"); > return -EOPNOTSUPP; > } > @@ -1166,7 +1269,9 @@ static inline int md_get_root(struct obd_export *exp, const char *fileset, > { > int rc; > > - EXP_CHECK_MD_OP(exp, get_root); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, get_root); > rc = MDP(exp->exp_obd, get_root)(exp, fileset, fid); > return rc; > @@ -1177,7 +1282,9 @@ static inline int md_getattr(struct obd_export *exp, struct md_op_data *op_data, > { > int rc; > > - EXP_CHECK_MD_OP(exp, getattr); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, getattr); > rc = MDP(exp->exp_obd, getattr)(exp, op_data, request); > return rc; > @@ -1188,7 +1295,9 @@ static inline int md_null_inode(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, null_inode); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, null_inode); > rc = MDP(exp->exp_obd, null_inode)(exp, fid); > return rc; > @@ -1200,7 +1309,9 @@ static inline int md_close(struct obd_export *exp, struct md_op_data *op_data, > { > int rc; > > - EXP_CHECK_MD_OP(exp, close); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, close); > rc = MDP(exp->exp_obd, close)(exp, op_data, mod, request); > return rc; > @@ -1213,7 +1324,9 @@ static inline int md_create(struct obd_export *exp, struct md_op_data *op_data, > { > int rc; > > - EXP_CHECK_MD_OP(exp, create); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, create); > rc = MDP(exp->exp_obd, create)(exp, op_data, data, datalen, mode, > uid, gid, cap_effective, rdev, request); > @@ -1229,7 +1342,9 @@ static inline int md_enqueue(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, enqueue); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, enqueue); > rc = MDP(exp->exp_obd, enqueue)(exp, einfo, policy, op_data, lockh, > extra_lock_flags); > @@ -1242,7 +1357,9 @@ static inline int md_getattr_name(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, getattr_name); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, getattr_name); > rc = MDP(exp->exp_obd, getattr_name)(exp, op_data, request); > return rc; > @@ -1257,7 +1374,9 @@ static inline int md_intent_lock(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, intent_lock); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, intent_lock); > rc = MDP(exp->exp_obd, intent_lock)(exp, op_data, it, reqp, > cb_blocking, extra_lock_flags); > @@ -1269,7 +1388,9 @@ static inline int md_link(struct obd_export *exp, struct md_op_data *op_data, > { > int rc; > > - EXP_CHECK_MD_OP(exp, link); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, link); > rc = MDP(exp->exp_obd, link)(exp, op_data, request); > return rc; > @@ -1281,7 +1402,9 @@ static inline int md_rename(struct obd_export *exp, struct md_op_data *op_data, > { > int rc; > > - EXP_CHECK_MD_OP(exp, rename); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, rename); > rc = MDP(exp->exp_obd, rename)(exp, op_data, old, oldlen, new, > newlen, request); > @@ -1294,7 +1417,9 @@ static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data, > { > int rc; > > - EXP_CHECK_MD_OP(exp, setattr); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, setattr); > rc = MDP(exp->exp_obd, setattr)(exp, op_data, ea, ealen, request); > return rc; > @@ -1305,7 +1430,9 @@ static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid, > { > int rc; > > - EXP_CHECK_MD_OP(exp, sync); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, sync); > rc = MDP(exp->exp_obd, sync)(exp, fid, request); > return rc; > @@ -1319,7 +1446,9 @@ static inline int md_read_page(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, read_page); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, read_page); > rc = MDP(exp->exp_obd, read_page)(exp, op_data, cb_op, hash_offset, > ppage); > @@ -1331,7 +1460,9 @@ static inline int md_unlink(struct obd_export *exp, struct md_op_data *op_data, > { > int rc; > > - EXP_CHECK_MD_OP(exp, unlink); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, unlink); > rc = MDP(exp->exp_obd, unlink)(exp, op_data, request); > return rc; > @@ -1343,7 +1474,11 @@ static inline int md_get_lustre_md(struct obd_export *exp, > struct obd_export *md_exp, > struct lustre_md *md) > { > - EXP_CHECK_MD_OP(exp, get_lustre_md); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, get_lustre_md); > return MDP(exp->exp_obd, get_lustre_md)(exp, req, dt_exp, md_exp, md); > } > @@ -1351,7 +1486,11 @@ static inline int md_get_lustre_md(struct obd_export *exp, > static inline int md_free_lustre_md(struct obd_export *exp, > struct lustre_md *md) > { > - EXP_CHECK_MD_OP(exp, free_lustre_md); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, free_lustre_md); > return MDP(exp->exp_obd, free_lustre_md)(exp, md); > } > @@ -1361,7 +1500,11 @@ static inline int md_merge_attr(struct obd_export *exp, > struct cl_attr *attr, > ldlm_blocking_callback cb) > { > - EXP_CHECK_MD_OP(exp, merge_attr); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, merge_attr); > return MDP(exp->exp_obd, merge_attr)(exp, lsm, attr, cb); > } > @@ -1372,7 +1515,11 @@ static inline int md_setxattr(struct obd_export *exp, const struct lu_fid *fid, > unsigned int xattr_flags, u32 suppgid, > struct ptlrpc_request **request) > { > - EXP_CHECK_MD_OP(exp, setxattr); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, setxattr); > return MDP(exp->exp_obd, setxattr)(exp, fid, obd_md_valid, name, > value, value_size, xattr_flags, > @@ -1383,7 +1530,11 @@ static inline int md_getxattr(struct obd_export *exp, const struct lu_fid *fid, > u64 obd_md_valid, const char *name, > size_t buf_size, struct ptlrpc_request **req) > { > - EXP_CHECK_MD_OP(exp, getxattr); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, getxattr); > return MDP(exp->exp_obd, getxattr)(exp, fid, obd_md_valid, name, > buf_size, req); > @@ -1393,7 +1544,11 @@ static inline int md_set_open_replay_data(struct obd_export *exp, > struct obd_client_handle *och, > struct lookup_intent *it) > { > - EXP_CHECK_MD_OP(exp, set_open_replay_data); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, set_open_replay_data); > return MDP(exp->exp_obd, set_open_replay_data)(exp, och, it); > } > @@ -1401,7 +1556,11 @@ static inline int md_set_open_replay_data(struct obd_export *exp, > static inline int md_clear_open_replay_data(struct obd_export *exp, > struct obd_client_handle *och) > { > - EXP_CHECK_MD_OP(exp, clear_open_replay_data); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, clear_open_replay_data); > return MDP(exp->exp_obd, clear_open_replay_data)(exp, och); > } > @@ -1410,7 +1569,11 @@ static inline int md_set_lock_data(struct obd_export *exp, > const struct lustre_handle *lockh, > void *data, __u64 *bits) > { > - EXP_CHECK_MD_OP(exp, set_lock_data); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, set_lock_data); > return MDP(exp->exp_obd, set_lock_data)(exp, lockh, data, bits); > } > @@ -1424,7 +1587,9 @@ static inline int md_cancel_unused(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, cancel_unused); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, cancel_unused); > > rc = MDP(exp->exp_obd, cancel_unused)(exp, fid, policy, mode, > @@ -1439,7 +1604,11 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, > enum ldlm_mode mode, > struct lustre_handle *lockh) > { > - EXP_CHECK_MD_OP(exp, lock_match); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, lock_match); > return MDP(exp->exp_obd, lock_match)(exp, flags, fid, type, > policy, mode, lockh); > @@ -1448,7 +1617,11 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, > static inline int md_init_ea_size(struct obd_export *exp, u32 easize, > u32 def_asize) > { > - EXP_CHECK_MD_OP(exp, init_ea_size); > + int rc; > + > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, init_ea_size); > return MDP(exp->exp_obd, init_ea_size)(exp, easize, def_asize); > } > @@ -1458,7 +1631,9 @@ static inline int md_intent_getattr_async(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, intent_getattr_async); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, intent_getattr_async); > rc = MDP(exp->exp_obd, intent_getattr_async)(exp, minfo); > return rc; > @@ -1470,7 +1645,9 @@ static inline int md_revalidate_lock(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, revalidate_lock); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, revalidate_lock); > rc = MDP(exp->exp_obd, revalidate_lock)(exp, it, fid, bits); > return rc; > @@ -1483,7 +1660,9 @@ static inline int md_get_fid_from_lsm(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, get_fid_from_lsm); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, get_fid_from_lsm); > rc = MDP(exp->exp_obd, get_fid_from_lsm)(exp, lsm, name, namelen, fid); > return rc; > @@ -1502,7 +1681,9 @@ static inline int md_unpackmd(struct obd_export *exp, > { > int rc; > > - EXP_CHECK_MD_OP(exp, unpackmd); > + rc = exp_check_ops(exp); > + if (rc) > + return rc; > EXP_MD_COUNTER_INCREMENT(exp, unpackmd); > rc = MDP(exp->exp_obd, unpackmd)(exp, plsm, lmm, lmm_size); > return rc; > diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c > index 26aea11..e074b6e 100644 > --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c > +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c > @@ -93,8 +93,8 @@ int __llog_ctxt_put(const struct lu_env *env, struct llog_ctxt *ctxt) > !!obd->obd_stopping, !!obd->obd_set_up); > > /* cleanup the llog ctxt here */ > - if (CTXTP(ctxt, cleanup)) > - rc = CTXTP(ctxt, cleanup)(env, ctxt); > + if (ctxt->loc_logops->lop_cleanup) > + rc = ctxt->loc_logops->lop_cleanup(env, ctxt); > > llog_ctxt_destroy(ctxt); > wake_up(&olg->olg_waitq); > -- > 1.8.3.1 > > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 06:03:18 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 16:03:18 +1000 Subject: [lustre-devel] [PATCH 20/34] lnet: discard ni_cpt_list In-Reply-To: References: <153628058697.8267.6056114844033479774.stgit@noble> <153628137203.8267.14277020278461943610.stgit@noble> <874levqn9z.fsf@notabene.neil.brown.name> Message-ID: <87lg7r4el5.fsf@notabene.neil.brown.name> On Thu, Sep 13 2018, Amir Shehata wrote: > did you read my response to that question? Pasted below: > > --- > This area was re-implemented. There is no need for ni_cptlist any longer. I > looked at the current code and it's not being used. > Originally it was being used to place the the ni on a global list: > ln_nis_cpt. Which was traversed when attempting to calculate the cpt for a > NID using lnet_cpt_of_nid_locked(). However that latter function has been > re-implemented due to how MR works now. So there is not need for ni_cptlist. > ___ Thanks. I've queued this patch. NeilBrown From: NeilBrown Date: Mon, 24 Sep 2018 15:57:13 +1000 Subject: [PATCH] lustre: remove ni_cptlist field. This is never used in a meaningful way. Signed-off-by: NeilBrown --- drivers/staging/lustre/include/linux/lnet/lib-types.h | 2 -- drivers/staging/lustre/lnet/lnet/api-ni.c | 5 ----- drivers/staging/lustre/lnet/lnet/config.c | 1 - 3 files changed, 8 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 89158b52dc1b..1423aea83747 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -309,8 +309,6 @@ struct lnet_ni { spinlock_t ni_lock; /* chain on the lnet_net structure */ struct list_head ni_netlist; - /* chain on net_ni_cpt */ - struct list_head ni_cptlist; /* number of CPTs */ int ni_ncpts; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 69ea18ce2dcc..20fa3fea04b9 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1115,11 +1115,6 @@ lnet_ni_tq_credits(struct lnet_ni *ni) static void lnet_ni_unlink_locked(struct lnet_ni *ni) { - if (!list_empty(&ni->ni_cptlist)) { - list_del_init(&ni->ni_cptlist); - lnet_ni_decref_locked(ni, 0); - } - /* move it to zombie list and nobody can find it anymore */ LASSERT(!list_empty(&ni->ni_netlist)); list_move(&ni->ni_netlist, &ni->ni_net->net_ni_zombie); diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 92694b51f223..9539ce07ae05 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -438,7 +438,6 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) } spin_lock_init(&ni->ni_lock); - INIT_LIST_HEAD(&ni->ni_cptlist); INIT_LIST_HEAD(&ni->ni_netlist); ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*ni->ni_refs[0])); -- 2.14.0.rc0.dirty -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Sep 24 06:58:29 2018 From: neilb at suse.com (NeilBrown) Date: Mon, 24 Sep 2018 16:58:29 +1000 Subject: [lustre-devel] [PATCH 00/34] Beginning of multi-rail support for drivers/staging/lustre In-Reply-To: References: <153628058697.8267.6056114844033479774.stgit@noble> Message-ID: <87in2v4c16.fsf@notabene.neil.brown.name> On Tue, Sep 11 2018, James Simmons wrote: >> The following series implements the first patch in the >> multi-rail series: >> Commit: 8cbb8cd3e771 ("LU-7734 lnet: Multi-Rail local NI split") >> >> I split that commit up into 40 individual commits which can be found >> at >> https://github.com/neilbrown/lustre/commits/multirail >> though you need to scroll down a bit, as that contains all the >> multi-rail series. >> >> I then ported most of these patches to my mainline tree. >> Some that I haven't included are: >> - lnet: Move lnet_msg_alloc/free down a bit. >> lnet_msg_alloc/free don't exist any more >> - lnet: lib-types: change some tabs to spaces >> - lnet - assorted whitespace changes. >> - lnet: change ni_last_alive from time64_t to long >> - lnet: add lnet_net_state >> net_state is never used. >> - lnet: remove 'static' from lnet_get_net_config() >> >> I've also made a couple of minor changes to individual patches not >> strictly related to porting (the net_prio field is never used, so I >> never added it - I should have made that a separate patch). >> >> This series compiles, but doesn't work. I get a NULL pointer >> reference, then an assertion failure. If I fix those, it hangs. >> The NULL pointer ref and the failing assertion are gone with >> later patches, so I hope the other problems are too. >> > > I have tried it and did a compare to what landed in the OpenSFS branch. > I saw the failures in my testing and foudn the mistake in the 7th patch. > >> Some of these patches have very poor descriptions, such as "I have no >> idea what this does". If someone would like to explain - or maybe say >> "Oh, we really shouldn't have done that", I'd be very happy to >> receive that, and update the description or patch accordingly. > > When I ran checkpatch it really dislikes: > > This is part of > 8cbb8cd3e771e7f7e0f99cafc19fad32770dc015 > LU-7734 lnet: Multi-Rail local NI split > > I don't recommend landing the above in the commit messsage as for the > reason that a person outside of lustre will not know where to look for > that git commit. Instead I recommend replacing it with: > > ------------------------------------------------------------------ > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18274 > Reviewed-by: Doug Oucharek > Reviewed-by: Olaf Weber > Signed-off-by: NeilBrown Thanks for the suggestion. I don't like that approach exactly because it seems to be a lie. The specific patch was not reviewed by those people, and there is useful information which is not included there. I have changed to patches to include: This is part of Commit: 8cbb8cd3e771 ("LU-7734 lnet: Multi-Rail local NI split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18274 Reviewed-by: Doug Oucharek Reviewed-by: Olaf Weber checkpatch is not happy with the indented tags, but checkpatch is a servant, not the master. I've made that change, moved this series to my 'lustre' branch, merged in the latest -rc, and pushed it all out. Now the post the rest of the 'MR' series, and then start looking at Dynamic Discovery (756abb9cf00b9^..1c45d9051764) Thanks, NeilBrown > > This gives the reviewer a URL link for both the JIRA ticket that usually > contains details not in the commit message as well as the gerrit URL > for the original patch. This way if a future bug is found a comparison > can be done against the original patch. > > The policy for the Lustre project is to perserve authorship for patches > when porting to other branches, upstream or LTS. > >> These will all appear in my lustre-testing branch, but won't migrate >> to 'lustre' until I, at least, have enough other patches that I can >> get a successful test run. >> >> Review and comments always welcome. >> >> Thanks, >> NeilBrown >> >> >> --- >> >> Amir Shehata (1): >> Completely re-write lnet_parse_networks(). >> >> NeilBrown (33): >> struct lnet_ni - reformat comments. >> lnet: Create struct lnet_net >> lnet: struct lnet_ni: move ni_lnd to lnet_net >> lnet: embed lnd_tunables in lnet_ni >> lnet: begin separating "networks" from "network interfaces". >> lnet: store separate xmit/recv net-interface in each message. >> lnet: change lnet_peer to reference the net, rather than ni. >> lnet: add cpt to lnet_match_info. >> lnet: add list of cpts to lnet_net. >> lnet: add ni arg to lnet_cpt_of_nid() >> lnet: pass tun to lnet_startup_lndni, instead of full conf >> lnet: split lnet_startup_lndni >> lnet: reverse order of lnet_startup_lnd{net,ni} >> lnet: rename lnet_find_net_locked to lnet_find_rnet_locked >> lnet: extend zombie handling to nets and nis >> lnet: lnet_shutdown_lndnets - remove some cleanup code. >> lnet: move lnet_shutdown_lndnets down to after first use >> lnet: add ni_state >> lnet: simplify lnet_islocalnet() >> lnet: discard ni_cpt_list >> lnet: add net_ni_added >> lnet: don't take reference in lnet_XX2ni_locked() >> lnet: don't need lock to test ln_shutdown. >> lnet: don't take lock over lnet_net_unique() >> lnet: swap 'then' and 'else' branches in lnet_startup_lndnet >> lnet: only valid lnd_type when net_id is unique. >> lnet: make it possible to add a new interface to a network >> lnet: add checks to ensure network interface names are unique. >> lnet: track tunables in lnet_startup_lndnet() >> lnet: fix typo >> lnet: lnet_dyn_add_ni: fix ping_info count >> lnet: lnet_dyn_del_ni: fix ping_info count >> lnet: introduce use_tcp_bonding mod param >> >> >> .../staging/lustre/include/linux/lnet/lib-lnet.h | 31 - >> .../staging/lustre/include/linux/lnet/lib-types.h | 142 ++- >> .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 18 >> .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 10 >> .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 6 >> .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 12 >> .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 74 +- >> .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 25 - >> drivers/staging/lustre/lnet/lnet/acceptor.c | 8 >> drivers/staging/lustre/lnet/lnet/api-ni.c | 939 +++++++++++++------- >> drivers/staging/lustre/lnet/lnet/config.c | 688 +++++++++++---- >> drivers/staging/lustre/lnet/lnet/lib-move.c | 132 ++- >> drivers/staging/lustre/lnet/lnet/lib-ptl.c | 6 >> drivers/staging/lustre/lnet/lnet/lo.c | 2 >> drivers/staging/lustre/lnet/lnet/net_fault.c | 3 >> drivers/staging/lustre/lnet/lnet/peer.c | 31 - >> drivers/staging/lustre/lnet/lnet/router.c | 51 + >> drivers/staging/lustre/lnet/lnet/router_proc.c | 24 - >> drivers/staging/lustre/lnet/selftest/brw_test.c | 2 >> drivers/staging/lustre/lnet/selftest/framework.c | 3 >> drivers/staging/lustre/lnet/selftest/selftest.h | 2 >> 21 files changed, 1507 insertions(+), 702 deletions(-) >> >> -- >> Signature >> >> -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Tue Sep 25 01:07:14 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:14 +1000 Subject: [lustre-devel] [PATCH 00/34] lustre: remainder of multi-rail series. Message-ID: <153783752960.32103.8394391715843917125.stgit@noble> Hi, following is the remainder of the Multi-Rail series, ported to drivers/staging. The previous series was only the first patch from upstream. This series is mostly the individual patches from upstream, though I did split some up a bit, and merged at least one bugfix back to where the bug was introduced. Comments, review, and explanations of bits I didn't understand, are most welcome. I confess that I haven't looked at the code very closely, just a superficially scan for things that look odd (there weren't many). Thanks, NeilBrown --- Amir Shehata (22): LU-7734 lnet: Multi-Rail peer split LU-7734 lnet: Multi-Rail local_ni/peer_ni selection LU-7734 lnet: configure peers from DLC LU-7734 lnet: configure local NI from DLC LU-7734 lnet: NUMA support LU-7734 lnet: Primary NID and traffic distribution LU-7734 lnet: handle non-MR peers LU-7734 lnet: handle N NIs to 1 LND peer LU-7734 lnet: rename LND peer to peer_ni LU-7734 lnet: peer/peer_ni handling adjustments LU-7734 lnet: proper cpt locking LU-7734 lnet: protect peer_ni credits LU-7734 lnet: simplify and fix lnet_select_pathway() LU-7734 lnet: configuration fixes LU-7734 lnet: fix lnet_select_pathway() LU-7734 lnet: Routing fixes part 1 LU-7734 lnet: Routing fixes part 2 LU-7734 lnet: fix routing selection LU-7734 lnet: Fix crash in router_proc.c LU-7734 lnet: fix NULL access in lnet_peer_aliveness_enabled LU-7734 lnet: rename peer key_nid to prim_nid LU-7734 lnet: cpt locking Doug Oucharek (1): LU-7734 lnet: Add peer_ni and NI stats for DLC NeilBrown (8): lnet: replace all lp_ fields with lpni_ lnet: change struct lnet_peer to struct lnet_peer_ni lnet: Change lpni_refcount to atomic_t lnet: change some function names - add 'ni'. lnet: make lnet_nid_cpt_hash non-static. lnet: introduce lnet_find_peer_ni_locked() lnet: lnet_peer_tables_cleanup: use an exclusive lock. lnet: use BIT() macro for LNET_MD_* flags Olaf Weber (3): LU-7734 lnet: fix lnet_peer_table_cleanup_locked() LU-7734 lnet: double free in lnet_add_net_common() LU-7734 lnet: set primary NID in ptlrpc_connection_get() .../lustre/include/linux/libcfs/libcfs_string.h | 12 drivers/staging/lustre/include/linux/lnet/api.h | 1 .../staging/lustre/include/linux/lnet/lib-lnet.h | 151 ++- .../staging/lustre/include/linux/lnet/lib-types.h | 157 ++- .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 11 .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 104 ++ .../lustre/include/uapi/linux/lnet/lnet-types.h | 34 - .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 237 ++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 118 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 516 ++++----- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 678 ++++++------ .../staging/lustre/lnet/klnds/socklnd/socklnd.h | 66 + .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 207 ++-- .../lustre/lnet/klnds/socklnd/socklnd_lib.c | 4 .../lustre/lnet/klnds/socklnd/socklnd_proto.c | 14 drivers/staging/lustre/lnet/lnet/api-ni.c | 650 ++++++++++- drivers/staging/lustre/lnet/lnet/config.c | 107 +- drivers/staging/lustre/lnet/lnet/lib-md.c | 31 + drivers/staging/lustre/lnet/lnet/lib-move.c | 957 +++++++++++++--- drivers/staging/lustre/lnet/lnet/lib-msg.c | 18 drivers/staging/lustre/lnet/lnet/lib-ptl.c | 3 drivers/staging/lustre/lnet/lnet/module.c | 70 + drivers/staging/lustre/lnet/lnet/peer.c | 1169 +++++++++++++++++--- drivers/staging/lustre/lnet/lnet/router.c | 341 +++--- drivers/staging/lustre/lnet/lnet/router_proc.c | 66 + drivers/staging/lustre/lustre/include/lustre_net.h | 2 drivers/staging/lustre/lustre/ptlrpc/connection.c | 1 drivers/staging/lustre/lustre/ptlrpc/events.c | 5 drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 40 - drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 2 drivers/staging/lustre/lustre/ptlrpc/service.c | 4 31 files changed, 4056 insertions(+), 1720 deletions(-) -- Signature From neilb at suse.com Tue Sep 25 01:07:14 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:14 +1000 Subject: [lustre-devel] [PATCH 01/34] lnet: replace all lp_ fields with lpni_ In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763488.32103.14222362329822520874.stgit@noble> sed -i 's/\blp_/lpni_/g' `git grep -l '\blp_' drivers/staging/lustre/lnet | grep '\.[ch]$'` followed by some long-line cleanups. This is part of Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 24 +- .../staging/lustre/include/linux/lnet/lib-types.h | 63 +++--- drivers/staging/lustre/lnet/lnet/lib-move.c | 146 +++++++------ drivers/staging/lustre/lnet/lnet/peer.c | 125 ++++++----- drivers/staging/lustre/lnet/lnet/router.c | 218 ++++++++++---------- drivers/staging/lustre/lnet/lnet/router_proc.c | 52 ++--- 6 files changed, 316 insertions(+), 312 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 5ee770cd7a5f..9b54a3d72290 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -79,10 +79,10 @@ extern struct lnet the_lnet; /* THE network */ static inline int lnet_is_route_alive(struct lnet_route *route) { /* gateway is down */ - if (!route->lr_gateway->lp_alive) + if (!route->lr_gateway->lpni_alive) return 0; /* no NI status, assume it's alive */ - if ((route->lr_gateway->lp_ping_feats & + if ((route->lr_gateway->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS) == 0) return 1; /* has NI status, check # down NIs */ @@ -313,8 +313,8 @@ lnet_handle2me(struct lnet_handle_me *handle) static inline void lnet_peer_addref_locked(struct lnet_peer *lp) { - LASSERT(lp->lp_refcount > 0); - lp->lp_refcount++; + LASSERT(lp->lpni_refcount > 0); + lp->lpni_refcount++; } void lnet_destroy_peer_locked(struct lnet_peer *lp); @@ -322,16 +322,16 @@ void lnet_destroy_peer_locked(struct lnet_peer *lp); static inline void lnet_peer_decref_locked(struct lnet_peer *lp) { - LASSERT(lp->lp_refcount > 0); - lp->lp_refcount--; - if (!lp->lp_refcount) + LASSERT(lp->lpni_refcount > 0); + lp->lpni_refcount--; + if (!lp->lpni_refcount) lnet_destroy_peer_locked(lp); } static inline int lnet_isrouter(struct lnet_peer *lp) { - return lp->lp_rtr_refcount ? 1 : 0; + return lp->lpni_rtr_refcount ? 1 : 0; } static inline void @@ -652,10 +652,10 @@ int lnet_get_peer_info(__u32 peer_index, __u64 *nid, static inline void lnet_peer_set_alive(struct lnet_peer *lp) { - lp->lp_last_query = ktime_get_seconds(); - lp->lp_last_alive = lp->lp_last_query; - if (!lp->lp_alive) - lnet_notify_locked(lp, 0, 1, lp->lp_last_alive); + lp->lpni_last_query = ktime_get_seconds(); + lp->lpni_last_alive = lp->lpni_last_query; + if (!lp->lpni_alive) + lnet_notify_locked(lp, 0, 1, lp->lpni_last_alive); } #endif diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 8bc72f25a897..59a1a2620675 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -385,61 +385,61 @@ struct lnet_rc_data { struct lnet_peer { /* chain on peer hash */ - struct list_head lp_hashlist; + struct list_head lpni_hashlist; /* messages blocking for tx credits */ - struct list_head lp_txq; + struct list_head lpni_txq; /* messages blocking for router credits */ - struct list_head lp_rtrq; + struct list_head lpni_rtrq; /* chain on router list */ - struct list_head lp_rtr_list; + struct list_head lpni_rtr_list; /* # tx credits available */ - int lp_txcredits; + int lpni_txcredits; /* low water mark */ - int lp_mintxcredits; + int lpni_mintxcredits; /* # router credits */ - int lp_rtrcredits; + int lpni_rtrcredits; /* low water mark */ - int lp_minrtrcredits; + int lpni_minrtrcredits; /* alive/dead? */ - unsigned int lp_alive:1; + unsigned int lpni_alive:1; /* notification outstanding? */ - unsigned int lp_notify:1; + unsigned int lpni_notify:1; /* outstanding notification for LND? */ - unsigned int lp_notifylnd:1; + unsigned int lpni_notifylnd:1; /* some thread is handling notification */ - unsigned int lp_notifying:1; + unsigned int lpni_notifying:1; /* SEND event outstanding from ping */ - unsigned int lp_ping_notsent; + unsigned int lpni_ping_notsent; /* # times router went dead<->alive */ - int lp_alive_count; + int lpni_alive_count; /* ytes queued for sending */ - long lp_txqnob; + long lpni_txqnob; /* time of last aliveness news */ - time64_t lp_timestamp; + time64_t lpni_timestamp; /* time of last ping attempt */ - time64_t lp_ping_timestamp; + time64_t lpni_ping_timestamp; /* != 0 if ping reply expected */ - time64_t lp_ping_deadline; + time64_t lpni_ping_deadline; /* when I was last alive */ - time64_t lp_last_alive; - /* when lp_ni was queried last time */ - time64_t lp_last_query; + time64_t lpni_last_alive; + /* when lpni_ni was queried last time */ + time64_t lpni_last_query; /* network peer is on */ - struct lnet_net *lp_net; + struct lnet_net *lpni_net; /* peer's NID */ - lnet_nid_t lp_nid; + lnet_nid_t lpni_nid; /* # refs */ - int lp_refcount; + int lpni_refcount; /* CPT this peer attached on */ - int lp_cpt; + int lpni_cpt; /* # refs from lnet_route::lr_gateway */ - int lp_rtr_refcount; + int lpni_rtr_refcount; /* returned RC ping features */ - unsigned int lp_ping_feats; + unsigned int lpni_ping_feats; /* routers on this peer */ - struct list_head lp_routes; + struct list_head lpni_routes; /* router checker state */ - struct lnet_rc_data *lp_rcd; + struct lnet_rc_data *lpni_rcd; }; /* peer hash size */ @@ -464,8 +464,9 @@ struct lnet_peer_table { * peer aliveness is enabled only on routers for peers in a network where the * lnet_ni::ni_peertimeout has been set to a positive value */ -#define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing && \ - (lp)->lp_net->net_tunables.lct_peer_timeout > 0) +#define lnet_peer_aliveness_enabled(lp) \ + (the_lnet.ln_routing && \ + (lp)->lpni_net->net_tunables.lct_peer_timeout > 0) struct lnet_route { /* chain on net */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b75ebc236f3a..5879a109d46a 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -481,7 +481,7 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) &msg->msg_private); if (rc) { CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", - libcfs_nid2str(msg->msg_rxpeer->lp_nid), + libcfs_nid2str(msg->msg_rxpeer->lpni_nid), libcfs_id2str(msg->msg_target), rc); LASSERT(rc < 0); /* required by my callers */ } @@ -498,14 +498,14 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) LASSERT(lnet_peer_aliveness_enabled(lp)); LASSERT(ni->ni_net->net_lnd->lnd_query); - lnet_net_unlock(lp->lp_cpt); - ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); - lnet_net_lock(lp->lp_cpt); + lnet_net_unlock(lp->lpni_cpt); + ni->ni_net->net_lnd->lnd_query(ni, lp->lpni_nid, &last_alive); + lnet_net_lock(lp->lpni_cpt); - lp->lp_last_query = ktime_get_seconds(); + lp->lpni_last_query = ktime_get_seconds(); if (last_alive) /* NI has updated timestamp */ - lp->lp_last_alive = last_alive; + lp->lpni_last_alive = last_alive; } /* NB: always called with lnet_net_lock held */ @@ -520,21 +520,21 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) /* Trust lnet_notify() if it has more recent aliveness news, but * ignore the initial assumed death (see lnet_peers_start_down()). */ - if (!lp->lp_alive && lp->lp_alive_count > 0 && - lp->lp_timestamp >= lp->lp_last_alive) + if (!lp->lpni_alive && lp->lpni_alive_count > 0 && + lp->lpni_timestamp >= lp->lpni_last_alive) return 0; - deadline = lp->lp_last_alive + - lp->lp_net->net_tunables.lct_peer_timeout; + deadline = lp->lpni_last_alive + + lp->lpni_net->net_tunables.lct_peer_timeout; alive = deadline > now; - /* Update obsolete lp_alive except for routers assumed to be dead + /* Update obsolete lpni_alive except for routers assumed to be dead * initially, because router checker would update aliveness in this - * case, and moreover lp_last_alive at peer creation is assumed. + * case, and moreover lpni_last_alive at peer creation is assumed. */ - if (alive && !lp->lp_alive && - !(lnet_isrouter(lp) && !lp->lp_alive_count)) - lnet_notify_locked(lp, 0, 1, lp->lp_last_alive); + if (alive && !lp->lpni_alive && + !(lnet_isrouter(lp) && !lp->lpni_alive_count)) + lnet_notify_locked(lp, 0, 1, lp->lpni_last_alive); return alive; } @@ -558,19 +558,19 @@ lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) * Peer appears dead, but we should avoid frequent NI queries (at * most once per lnet_queryinterval seconds). */ - if (lp->lp_last_query) { + if (lp->lpni_last_query) { static const int lnet_queryinterval = 1; time64_t next_query; - next_query = lp->lp_last_query + lnet_queryinterval; + next_query = lp->lpni_last_query + lnet_queryinterval; if (now < next_query) { - if (lp->lp_alive) + if (lp->lpni_alive) CWARN("Unexpected aliveness of peer %s: %lld < %lld (%d/%d)\n", - libcfs_nid2str(lp->lp_nid), + libcfs_nid2str(lp->lpni_nid), now, next_query, lnet_queryinterval, - lp->lp_net->net_tunables.lct_peer_timeout); + lp->lpni_net->net_tunables.lct_peer_timeout); return 0; } } @@ -581,7 +581,7 @@ lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) if (lnet_peer_is_alive(lp, now)) return 1; - lnet_notify_locked(lp, 0, 0, lp->lp_last_alive); + lnet_notify_locked(lp, 0, 0, lp->lpni_last_alive); return 0; } @@ -639,19 +639,19 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) } if (!msg->msg_peertxcredit) { - LASSERT((lp->lp_txcredits < 0) == - !list_empty(&lp->lp_txq)); + LASSERT((lp->lpni_txcredits < 0) == + !list_empty(&lp->lpni_txq)); msg->msg_peertxcredit = 1; - lp->lp_txqnob += msg->msg_len + sizeof(struct lnet_hdr); - lp->lp_txcredits--; + lp->lpni_txqnob += msg->msg_len + sizeof(struct lnet_hdr); + lp->lpni_txcredits--; - if (lp->lp_txcredits < lp->lp_mintxcredits) - lp->lp_mintxcredits = lp->lp_txcredits; + if (lp->lpni_txcredits < lp->lpni_mintxcredits) + lp->lpni_mintxcredits = lp->lpni_txcredits; - if (lp->lp_txcredits < 0) { + if (lp->lpni_txcredits < 0) { msg->msg_tx_delayed = 1; - list_add_tail(&msg->msg_list, &lp->lp_txq); + list_add_tail(&msg->msg_list, &lp->lpni_txq); return LNET_CREDIT_WAIT; } } @@ -725,19 +725,19 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) LASSERT(!do_recv || msg->msg_rx_delayed); if (!msg->msg_peerrtrcredit) { - LASSERT((lp->lp_rtrcredits < 0) == - !list_empty(&lp->lp_rtrq)); + LASSERT((lp->lpni_rtrcredits < 0) == + !list_empty(&lp->lpni_rtrq)); msg->msg_peerrtrcredit = 1; - lp->lp_rtrcredits--; - if (lp->lp_rtrcredits < lp->lp_minrtrcredits) - lp->lp_minrtrcredits = lp->lp_rtrcredits; + lp->lpni_rtrcredits--; + if (lp->lpni_rtrcredits < lp->lpni_minrtrcredits) + lp->lpni_minrtrcredits = lp->lpni_rtrcredits; - if (lp->lp_rtrcredits < 0) { + if (lp->lpni_rtrcredits < 0) { /* must have checked eager_recv before here */ LASSERT(msg->msg_rx_ready_delay); msg->msg_rx_delayed = 1; - list_add_tail(&msg->msg_list, &lp->lp_rtrq); + list_add_tail(&msg->msg_list, &lp->lpni_rtrq); return LNET_CREDIT_WAIT; } } @@ -811,15 +811,15 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) /* give back peer txcredits */ msg->msg_peertxcredit = 0; - LASSERT((txpeer->lp_txcredits < 0) == - !list_empty(&txpeer->lp_txq)); + LASSERT((txpeer->lpni_txcredits < 0) == + !list_empty(&txpeer->lpni_txq)); - txpeer->lp_txqnob -= msg->msg_len + sizeof(struct lnet_hdr); - LASSERT(txpeer->lp_txqnob >= 0); + txpeer->lpni_txqnob -= msg->msg_len + sizeof(struct lnet_hdr); + LASSERT(txpeer->lpni_txqnob >= 0); - txpeer->lp_txcredits++; - if (txpeer->lp_txcredits <= 0) { - msg2 = list_entry(txpeer->lp_txq.next, + txpeer->lpni_txcredits++; + if (txpeer->lpni_txcredits <= 0) { + msg2 = list_entry(txpeer->lpni_txq.next, struct lnet_msg, msg_list); list_del(&msg2->msg_list); @@ -939,19 +939,19 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) /* give back peer router credits */ msg->msg_peerrtrcredit = 0; - LASSERT((rxpeer->lp_rtrcredits < 0) == - !list_empty(&rxpeer->lp_rtrq)); + LASSERT((rxpeer->lpni_rtrcredits < 0) == + !list_empty(&rxpeer->lpni_rtrq)); - rxpeer->lp_rtrcredits++; + rxpeer->lpni_rtrcredits++; /* * drop all messages which are queued to be routed on that * peer. */ if (!the_lnet.ln_routing) { - lnet_drop_routed_msgs_locked(&rxpeer->lp_rtrq, + lnet_drop_routed_msgs_locked(&rxpeer->lpni_rtrq, msg->msg_rx_cpt); - } else if (rxpeer->lp_rtrcredits <= 0) { - msg2 = list_entry(rxpeer->lp_rtrq.next, + } else if (rxpeer->lpni_rtrcredits <= 0) { + msg2 = list_entry(rxpeer->lpni_rtrq.next, struct lnet_msg, msg_list); list_del(&msg2->msg_list); @@ -988,16 +988,16 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) if (r1_hops > r2_hops) return -ERANGE; - if (p1->lp_txqnob < p2->lp_txqnob) + if (p1->lpni_txqnob < p2->lpni_txqnob) return 1; - if (p1->lp_txqnob > p2->lp_txqnob) + if (p1->lpni_txqnob > p2->lpni_txqnob) return -ERANGE; - if (p1->lp_txcredits > p2->lp_txcredits) + if (p1->lpni_txcredits > p2->lpni_txcredits) return 1; - if (p1->lp_txcredits < p2->lp_txcredits) + if (p1->lpni_txcredits < p2->lpni_txcredits) return -ERANGE; if (r1->lr_seq - r2->lr_seq <= 0) @@ -1014,7 +1014,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, struct lnet_route *route; struct lnet_route *best_route; struct lnet_route *last_route; - struct lnet_peer *lp_best; + struct lnet_peer *lpni_best; struct lnet_peer *lp; int rc; @@ -1026,7 +1026,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, if (!rnet) return NULL; - lp_best = NULL; + lpni_best = NULL; best_route = NULL; last_route = NULL; list_for_each_entry(route, &rnet->lrn_routes, lr_list) { @@ -1035,16 +1035,16 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, if (!lnet_is_route_alive(route)) continue; - if (net && lp->lp_net != net) + if (net && lp->lpni_net != net) continue; - if (lp->lp_nid == rtr_nid) /* it's pre-determined router */ + if (lp->lpni_nid == rtr_nid) /* it's pre-determined router */ return lp; - if (!lp_best) { + if (!lpni_best) { best_route = route; last_route = route; - lp_best = lp; + lpni_best = lp; continue; } @@ -1057,7 +1057,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, continue; best_route = route; - lp_best = lp; + lpni_best = lp; } /* @@ -1067,7 +1067,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, */ if (best_route) best_route->lr_seq = last_route->lr_seq + 1; - return lp_best; + return lpni_best; } int @@ -1156,7 +1156,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) /* ENOMEM or shutting down */ return rc; } - LASSERT(lp->lp_net == src_ni->ni_net); + LASSERT(lp->lpni_net == src_ni->ni_net); } else { /* sending to a remote network */ lp = lnet_find_route_locked(src_ni ? src_ni->ni_net : NULL, @@ -1176,27 +1176,27 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) * pre-determined router, this can happen if router table * was changed when we release the lock */ - if (rtr_nid != lp->lp_nid) { - cpt2 = lp->lp_cpt; + if (rtr_nid != lp->lpni_nid) { + cpt2 = lp->lpni_cpt; if (cpt2 != cpt) { lnet_net_unlock(cpt); - rtr_nid = lp->lp_nid; + rtr_nid = lp->lpni_nid; cpt = cpt2; goto again; } } CDEBUG(D_NET, "Best route to %s via %s for %s %d\n", - libcfs_nid2str(dst_nid), libcfs_nid2str(lp->lp_nid), + libcfs_nid2str(dst_nid), libcfs_nid2str(lp->lpni_nid), lnet_msgtyp2str(msg->msg_type), msg->msg_len); if (!src_ni) { - src_ni = lnet_get_next_ni_locked(lp->lp_net, NULL); + src_ni = lnet_get_next_ni_locked(lp->lpni_net, NULL); LASSERT(src_ni); src_nid = src_ni->ni_nid; } else { - LASSERT(src_ni->ni_net == lp->lp_net); + LASSERT(src_ni->ni_net == lp->lpni_net); } lnet_peer_addref_locked(lp); @@ -1210,7 +1210,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) } msg->msg_target_is_router = 1; - msg->msg_target.nid = lp->lp_nid; + msg->msg_target.nid = lp->lpni_nid; msg->msg_target.pid = LNET_PID_LUSTRE; } @@ -1289,7 +1289,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) info.mi_rlength = hdr->payload_length; info.mi_roffset = hdr->msg.put.offset; info.mi_mbits = hdr->msg.put.match_bits; - info.mi_cpt = msg->msg_rxpeer->lp_cpt; + info.mi_cpt = msg->msg_rxpeer->lpni_cpt; msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; ready_delay = msg->msg_rx_ready_delay; @@ -1520,7 +1520,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) if (!the_lnet.ln_routing) return -ECANCELED; - if (msg->msg_rxpeer->lp_rtrcredits <= 0 || + if (msg->msg_rxpeer->lpni_rtrcredits <= 0 || lnet_msg2bufpool(msg)->rbp_credits <= 0) { if (!ni->ni_net->net_lnd->lnd_eager_recv) { msg->msg_rx_ready_delay = 1; @@ -1909,7 +1909,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) * until that's done */ lnet_drop_message(msg->msg_rxni, - msg->msg_rxpeer->lp_cpt, + msg->msg_rxpeer->lpni_cpt, msg->msg_private, msg->msg_len); /* * NB: message will not generate event because w/o attached MD, @@ -2376,7 +2376,7 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) hops = shortest_hops; if (srcnidp) { ni = lnet_get_next_ni_locked( - shortest->lr_gateway->lp_net, + shortest->lr_gateway->lpni_net, NULL); *srcnidp = ni->ni_nid; } diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 42bc35010f64..619d016b1d89 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -111,10 +111,10 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], - lp_hashlist) { - if (ni && ni->ni_net != lp->lp_net) + lpni_hashlist) { + if (ni && ni->ni_net != lp->lpni_net) continue; - list_del_init(&lp->lp_hashlist); + list_del_init(&lp->lpni_hashlist); /* Lose hash table's ref */ ptable->pt_zombies++; lnet_peer_decref_locked(lp); @@ -148,22 +148,22 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, { struct lnet_peer *lp; struct lnet_peer *tmp; - lnet_nid_t lp_nid; + lnet_nid_t lpni_nid; int i; for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], - lp_hashlist) { - if (ni->ni_net != lp->lp_net) + lpni_hashlist) { + if (ni->ni_net != lp->lpni_net) continue; - if (!lp->lp_rtr_refcount) + if (!lp->lpni_rtr_refcount) continue; - lp_nid = lp->lp_nid; + lpni_nid = lp->lpni_nid; lnet_net_unlock(cpt_locked); - lnet_del_route(LNET_NIDNET(LNET_NID_ANY), lp_nid); + lnet_del_route(LNET_NIDNET(LNET_NID_ANY), lpni_nid); lnet_net_lock(cpt_locked); } } @@ -209,8 +209,8 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) } while (!list_empty(&deathrow)) { - lp = list_entry(deathrow.next, struct lnet_peer, lp_hashlist); - list_del(&lp->lp_hashlist); + lp = list_entry(deathrow.next, struct lnet_peer, lpni_hashlist); + list_del(&lp->lpni_hashlist); kfree(lp); } } @@ -220,19 +220,19 @@ lnet_destroy_peer_locked(struct lnet_peer *lp) { struct lnet_peer_table *ptable; - LASSERT(!lp->lp_refcount); - LASSERT(!lp->lp_rtr_refcount); - LASSERT(list_empty(&lp->lp_txq)); - LASSERT(list_empty(&lp->lp_hashlist)); - LASSERT(!lp->lp_txqnob); + LASSERT(!lp->lpni_refcount); + LASSERT(!lp->lpni_rtr_refcount); + LASSERT(list_empty(&lp->lpni_txq)); + LASSERT(list_empty(&lp->lpni_hashlist)); + LASSERT(!lp->lpni_txqnob); - ptable = the_lnet.ln_peer_tables[lp->lp_cpt]; + ptable = the_lnet.ln_peer_tables[lp->lpni_cpt]; LASSERT(ptable->pt_number > 0); ptable->pt_number--; - lp->lp_net = NULL; + lp->lpni_net = NULL; - list_add(&lp->lp_hashlist, &ptable->pt_deathrow); + list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); LASSERT(ptable->pt_zombies > 0); ptable->pt_zombies--; } @@ -246,8 +246,8 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) LASSERT(!the_lnet.ln_shutdown); peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; - list_for_each_entry(lp, peers, lp_hashlist) { - if (lp->lp_nid == nid) { + list_for_each_entry(lp, peers, lpni_hashlist) { + if (lp->lpni_nid == nid) { lnet_peer_addref_locked(lp); return lp; } @@ -281,8 +281,8 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) if (!list_empty(&ptable->pt_deathrow)) { lp = list_entry(ptable->pt_deathrow.next, - struct lnet_peer, lp_hashlist); - list_del(&lp->lp_hashlist); + struct lnet_peer, lpni_hashlist); + list_del(&lp->lpni_hashlist); } /* @@ -303,24 +303,24 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) goto out; } - INIT_LIST_HEAD(&lp->lp_txq); - INIT_LIST_HEAD(&lp->lp_rtrq); - INIT_LIST_HEAD(&lp->lp_routes); - - lp->lp_notify = 0; - lp->lp_notifylnd = 0; - lp->lp_notifying = 0; - lp->lp_alive_count = 0; - lp->lp_timestamp = 0; - lp->lp_alive = !lnet_peers_start_down(); /* 1 bit!! */ - lp->lp_last_alive = ktime_get_seconds(); /* assumes alive */ - lp->lp_last_query = 0; /* haven't asked NI yet */ - lp->lp_ping_timestamp = 0; - lp->lp_ping_feats = LNET_PING_FEAT_INVAL; - lp->lp_nid = nid; - lp->lp_cpt = cpt2; - lp->lp_refcount = 2; /* 1 for caller; 1 for hash */ - lp->lp_rtr_refcount = 0; + INIT_LIST_HEAD(&lp->lpni_txq); + INIT_LIST_HEAD(&lp->lpni_rtrq); + INIT_LIST_HEAD(&lp->lpni_routes); + + lp->lpni_notify = 0; + lp->lpni_notifylnd = 0; + lp->lpni_notifying = 0; + lp->lpni_alive_count = 0; + lp->lpni_timestamp = 0; + lp->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ + lp->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ + lp->lpni_last_query = 0; /* haven't asked NI yet */ + lp->lpni_ping_timestamp = 0; + lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; + lp->lpni_nid = nid; + lp->lpni_cpt = cpt2; + lp->lpni_refcount = 2; /* 1 for caller; 1 for hash */ + lp->lpni_rtr_refcount = 0; lnet_net_lock(cpt); @@ -335,13 +335,14 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) goto out; } - lp->lp_net = lnet_get_net_locked(LNET_NIDNET(lp->lp_nid)); - lp->lp_txcredits = - lp->lp_mintxcredits = lp->lp_net->net_tunables.lct_peer_tx_credits; - lp->lp_rtrcredits = - lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_net); + lp->lpni_net = lnet_get_net_locked(LNET_NIDNET(lp->lpni_nid)); + lp->lpni_txcredits = + lp->lpni_mintxcredits = + lp->lpni_net->net_tunables.lct_peer_tx_credits; + lp->lpni_rtrcredits = + lp->lpni_minrtrcredits = lnet_peer_buffer_credits(lp->lpni_net); - list_add_tail(&lp->lp_hashlist, + list_add_tail(&lp->lpni_hashlist, &ptable->pt_hash[lnet_nid2peerhash(nid)]); ptable->pt_version++; *lpp = lp; @@ -349,7 +350,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) return 0; out: if (lp) - list_add(&lp->lp_hashlist, &ptable->pt_deathrow); + list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); ptable->pt_number--; return rc; } @@ -373,13 +374,13 @@ lnet_debug_peer(lnet_nid_t nid) } if (lnet_isrouter(lp) || lnet_peer_aliveness_enabled(lp)) - aliveness = lp->lp_alive ? "up" : "down"; + aliveness = lp->lpni_alive ? "up" : "down"; CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", - libcfs_nid2str(lp->lp_nid), lp->lp_refcount, - aliveness, lp->lp_net->net_tunables.lct_peer_tx_credits, - lp->lp_rtrcredits, lp->lp_minrtrcredits, - lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob); + libcfs_nid2str(lp->lpni_nid), lp->lpni_refcount, + aliveness, lp->lpni_net->net_tunables.lct_peer_tx_credits, + lp->lpni_rtrcredits, lp->lpni_minrtrcredits, + lp->lpni_txcredits, lp->lpni_mintxcredits, lp->lpni_txqnob); lnet_peer_decref_locked(lp); @@ -420,7 +421,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, for (j = 0; j < LNET_PEER_HASH_SIZE && !found; j++) { struct list_head *peers = &peer_table->pt_hash[j]; - list_for_each_entry(lp, peers, lp_hashlist) { + list_for_each_entry(lp, peers, lpni_hashlist) { if (peer_index-- > 0) continue; @@ -428,16 +429,16 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, if (lnet_isrouter(lp) || lnet_peer_aliveness_enabled(lp)) snprintf(aliveness, LNET_MAX_STR_LEN, - lp->lp_alive ? "up" : "down"); + lp->lpni_alive ? "up" : "down"); - *nid = lp->lp_nid; - *refcount = lp->lp_refcount; + *nid = lp->lpni_nid; + *refcount = lp->lpni_refcount; *ni_peer_tx_credits = - lp->lp_net->net_tunables.lct_peer_tx_credits; - *peer_tx_credits = lp->lp_txcredits; - *peer_rtr_credits = lp->lp_rtrcredits; - *peer_min_rtr_credits = lp->lp_mintxcredits; - *peer_tx_qnob = lp->lp_txqnob; + lp->lpni_net->net_tunables.lct_peer_tx_credits; + *peer_tx_credits = lp->lpni_txcredits; + *peer_rtr_credits = lp->lpni_rtrcredits; + *peer_min_rtr_credits = lp->lpni_mintxcredits; + *peer_tx_qnob = lp->lpni_txqnob; found = true; } diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 2bbd1cf86a8c..2be1ffb6b720 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -103,30 +103,30 @@ void lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, time64_t when) { - if (lp->lp_timestamp > when) { /* out of date information */ + if (lp->lpni_timestamp > when) { /* out of date information */ CDEBUG(D_NET, "Out of date\n"); return; } - lp->lp_timestamp = when; /* update timestamp */ - lp->lp_ping_deadline = 0; /* disable ping timeout */ + lp->lpni_timestamp = when; /* update timestamp */ + lp->lpni_ping_deadline = 0; /* disable ping timeout */ - if (lp->lp_alive_count && /* got old news */ - (!lp->lp_alive) == (!alive)) { /* new date for old news */ + if (lp->lpni_alive_count && /* got old news */ + (!lp->lpni_alive) == (!alive)) { /* new date for old news */ CDEBUG(D_NET, "Old news\n"); return; } /* Flag that notification is outstanding */ - lp->lp_alive_count++; - lp->lp_alive = !(!alive); /* 1 bit! */ - lp->lp_notify = 1; - lp->lp_notifylnd |= notifylnd; - if (lp->lp_alive) - lp->lp_ping_feats = LNET_PING_FEAT_INVAL; /* reset */ + lp->lpni_alive_count++; + lp->lpni_alive = !(!alive); /* 1 bit! */ + lp->lpni_notify = 1; + lp->lpni_notifylnd |= notifylnd; + if (lp->lpni_alive) + lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; /* reset */ - CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lp_nid), alive); + CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lpni_nid), alive); } static void @@ -140,55 +140,56 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) * NB individual events can be missed; the only guarantee is that you * always get the most recent news */ - if (lp->lp_notifying || !ni) + if (lp->lpni_notifying || !ni) return; - lp->lp_notifying = 1; + lp->lpni_notifying = 1; - while (lp->lp_notify) { - alive = lp->lp_alive; - notifylnd = lp->lp_notifylnd; + while (lp->lpni_notify) { + alive = lp->lpni_alive; + notifylnd = lp->lpni_notifylnd; - lp->lp_notifylnd = 0; - lp->lp_notify = 0; + lp->lpni_notifylnd = 0; + lp->lpni_notify = 0; if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { - lnet_net_unlock(lp->lp_cpt); + lnet_net_unlock(lp->lpni_cpt); /* * A new notification could happen now; I'll handle it * when control returns to me */ - ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); + ni->ni_net->net_lnd->lnd_notify(ni, lp->lpni_nid, + alive); - lnet_net_lock(lp->lp_cpt); + lnet_net_lock(lp->lpni_cpt); } } - lp->lp_notifying = 0; + lp->lpni_notifying = 0; } static void lnet_rtr_addref_locked(struct lnet_peer *lp) { - LASSERT(lp->lp_refcount > 0); - LASSERT(lp->lp_rtr_refcount >= 0); + LASSERT(lp->lpni_refcount > 0); + LASSERT(lp->lpni_rtr_refcount >= 0); /* lnet_net_lock must be exclusively locked */ - lp->lp_rtr_refcount++; - if (lp->lp_rtr_refcount == 1) { + lp->lpni_rtr_refcount++; + if (lp->lpni_rtr_refcount == 1) { struct list_head *pos; /* a simple insertion sort */ list_for_each_prev(pos, &the_lnet.ln_routers) { struct lnet_peer *rtr; - rtr = list_entry(pos, struct lnet_peer, lp_rtr_list); - if (rtr->lp_nid < lp->lp_nid) + rtr = list_entry(pos, struct lnet_peer, lpni_rtr_list); + if (rtr->lpni_nid < lp->lpni_nid) break; } - list_add(&lp->lp_rtr_list, pos); + list_add(&lp->lpni_rtr_list, pos); /* addref for the_lnet.ln_routers */ lnet_peer_addref_locked(lp); the_lnet.ln_routers_version++; @@ -198,21 +199,21 @@ lnet_rtr_addref_locked(struct lnet_peer *lp) static void lnet_rtr_decref_locked(struct lnet_peer *lp) { - LASSERT(lp->lp_refcount > 0); - LASSERT(lp->lp_rtr_refcount > 0); + LASSERT(lp->lpni_refcount > 0); + LASSERT(lp->lpni_rtr_refcount > 0); /* lnet_net_lock must be exclusively locked */ - lp->lp_rtr_refcount--; - if (!lp->lp_rtr_refcount) { - LASSERT(list_empty(&lp->lp_routes)); + lp->lpni_rtr_refcount--; + if (!lp->lpni_rtr_refcount) { + LASSERT(list_empty(&lp->lpni_routes)); - if (lp->lp_rcd) { - list_add(&lp->lp_rcd->rcd_list, + if (lp->lpni_rcd) { + list_add(&lp->lpni_rcd->rcd_list, &the_lnet.ln_rcd_deathrow); - lp->lp_rcd = NULL; + lp->lpni_rcd = NULL; } - list_del(&lp->lp_rtr_list); + list_del(&lp->lpni_rtr_list); /* decref for the_lnet.ln_routers */ lnet_peer_decref_locked(lp); the_lnet.ln_routers_version++; @@ -279,7 +280,7 @@ lnet_add_route_to_rnet(struct lnet_remotenet *rnet, struct lnet_route *route) offset--; } list_add(&route->lr_list, e); - list_add(&route->lr_gwlist, &route->lr_gateway->lp_routes); + list_add(&route->lr_gwlist, &route->lr_gateway->lpni_routes); the_lnet.ln_remote_nets_version++; lnet_rtr_addref_locked(route->lr_gateway); @@ -364,14 +365,14 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, } /* our lookups must be true */ - LASSERT(route2->lr_gateway->lp_nid != gateway); + LASSERT(route2->lr_gateway->lpni_nid != gateway); } if (add_route) { lnet_peer_addref_locked(route->lr_gateway); /* +1 for notify */ lnet_add_route_to_rnet(rnet2, route); - ni = lnet_get_next_ni_locked(route->lr_gateway->lp_net, NULL); + ni = lnet_get_next_ni_locked(route->lr_gateway->lpni_net, NULL); lnet_net_unlock(LNET_LOCK_EX); /* XXX Assume alive */ @@ -426,12 +427,12 @@ lnet_check_routes(void) continue; } - if (route->lr_gateway->lp_net == - route2->lr_gateway->lp_net) + if (route->lr_gateway->lpni_net == + route2->lr_gateway->lpni_net) continue; - nid1 = route->lr_gateway->lp_nid; - nid2 = route2->lr_gateway->lp_nid; + nid1 = route->lr_gateway->lpni_nid; + nid2 = route2->lr_gateway->lpni_nid; net = rnet->lrn_net; lnet_net_unlock(cpt); @@ -481,7 +482,7 @@ lnet_del_route(__u32 net, lnet_nid_t gw_nid) list_for_each_entry(route, &rnet->lrn_routes, lr_list) { gateway = route->lr_gateway; if (!(gw_nid == LNET_NID_ANY || - gw_nid == gateway->lp_nid)) + gw_nid == gateway->lpni_nid)) continue; list_del(&route->lr_list); @@ -575,7 +576,7 @@ lnet_get_route(int idx, __u32 *net, __u32 *hops, *net = rnet->lrn_net; *hops = route->lr_hops; *priority = route->lr_priority; - *gateway = route->lr_gateway->lp_nid; + *gateway = route->lr_gateway->lpni_nid; *alive = lnet_is_route_alive(route); lnet_net_unlock(cpt); return 0; @@ -616,7 +617,7 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) struct lnet_peer *gw = rcd->rcd_gateway; struct lnet_route *rte; - if (!gw->lp_alive) + if (!gw->lpni_alive) return; if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) @@ -625,27 +626,27 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) /* NB always racing with network! */ if (info->pi_magic != LNET_PROTO_PING_MAGIC) { CDEBUG(D_NET, "%s: Unexpected magic %08x\n", - libcfs_nid2str(gw->lp_nid), info->pi_magic); - gw->lp_ping_feats = LNET_PING_FEAT_INVAL; + libcfs_nid2str(gw->lpni_nid), info->pi_magic); + gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; return; } - gw->lp_ping_feats = info->pi_features; - if (!(gw->lp_ping_feats & LNET_PING_FEAT_MASK)) { + gw->lpni_ping_feats = info->pi_features; + if (!(gw->lpni_ping_feats & LNET_PING_FEAT_MASK)) { CDEBUG(D_NET, "%s: Unexpected features 0x%x\n", - libcfs_nid2str(gw->lp_nid), gw->lp_ping_feats); + libcfs_nid2str(gw->lpni_nid), gw->lpni_ping_feats); return; /* nothing I can understand */ } - if (!(gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS)) + if (!(gw->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS)) return; /* can't carry NI status info */ - list_for_each_entry(rte, &gw->lp_routes, lr_gwlist) { + list_for_each_entry(rte, &gw->lpni_routes, lr_gwlist) { int down = 0; int up = 0; int i; - if (gw->lp_ping_feats & LNET_PING_FEAT_RTE_DISABLED) { + if (gw->lpni_ping_feats & LNET_PING_FEAT_RTE_DISABLED) { rte->lr_downis = 1; continue; } @@ -656,8 +657,8 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) if (nid == LNET_NID_ANY) { CDEBUG(D_NET, "%s: unexpected LNET_NID_ANY\n", - libcfs_nid2str(gw->lp_nid)); - gw->lp_ping_feats = LNET_PING_FEAT_INVAL; + libcfs_nid2str(gw->lpni_nid)); + gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; return; } @@ -678,8 +679,8 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) } CDEBUG(D_NET, "%s: Unexpected status 0x%x\n", - libcfs_nid2str(gw->lp_nid), stat->ns_status); - gw->lp_ping_feats = LNET_PING_FEAT_INVAL; + libcfs_nid2str(gw->lpni_nid), stat->ns_status); + gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; return; } @@ -722,14 +723,14 @@ lnet_router_checker_event(struct lnet_event *event) * places need to hold both locks at the same time, please take * care of lock ordering */ - lnet_net_lock(lp->lp_cpt); - if (!lnet_isrouter(lp) || lp->lp_rcd != rcd) { + lnet_net_lock(lp->lpni_cpt); + if (!lnet_isrouter(lp) || lp->lpni_rcd != rcd) { /* ignore if no longer a router or rcd is replaced */ goto out; } if (event->type == LNET_EVENT_SEND) { - lp->lp_ping_notsent = 0; + lp->lpni_ping_notsent = 0; if (!event->status) goto out; } @@ -753,7 +754,7 @@ lnet_router_checker_event(struct lnet_event *event) lnet_parse_rc_info(rcd); out: - lnet_net_unlock(lp->lp_cpt); + lnet_net_unlock(lp->lpni_cpt); } static void @@ -768,8 +769,8 @@ lnet_wait_known_routerstate(void) int cpt = lnet_net_lock_current(); all_known = 1; - list_for_each_entry(rtr, &the_lnet.ln_routers, lp_rtr_list) { - if (!rtr->lp_alive_count) { + list_for_each_entry(rtr, &the_lnet.ln_routers, lpni_rtr_list) { + if (!rtr->lpni_alive_count) { all_known = 0; break; } @@ -789,8 +790,8 @@ lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) { struct lnet_route *rte; - if ((gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS)) { - list_for_each_entry(rte, &gw->lp_routes, lr_gwlist) { + if ((gw->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS)) { + list_for_each_entry(rte, &gw->lpni_routes, lr_gwlist) { if (rte->lr_net == net) { rte->lr_downis = 0; break; @@ -849,7 +850,7 @@ lnet_destroy_rc_data(struct lnet_rc_data *rcd) LASSERT(LNetMDHandleIsInvalid(rcd->rcd_mdh)); if (rcd->rcd_gateway) { - int cpt = rcd->rcd_gateway->lp_cpt; + int cpt = rcd->rcd_gateway->lpni_cpt; lnet_net_lock(cpt); lnet_peer_decref_locked(rcd->rcd_gateway); @@ -870,7 +871,7 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) int rc; int i; - lnet_net_unlock(gateway->lp_cpt); + lnet_net_unlock(gateway->lpni_cpt); rcd = kzalloc(sizeof(*rcd), GFP_NOFS); if (!rcd) @@ -904,17 +905,17 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) } LASSERT(!rc); - lnet_net_lock(gateway->lp_cpt); + lnet_net_lock(gateway->lpni_cpt); /* router table changed or someone has created rcd for this gateway */ - if (!lnet_isrouter(gateway) || gateway->lp_rcd) { - lnet_net_unlock(gateway->lp_cpt); + if (!lnet_isrouter(gateway) || gateway->lpni_rcd) { + lnet_net_unlock(gateway->lpni_cpt); goto out; } lnet_peer_addref_locked(gateway); rcd->rcd_gateway = gateway; - gateway->lp_rcd = rcd; - gateway->lp_ping_notsent = 0; + gateway->lpni_rcd = rcd; + gateway->lpni_ping_notsent = 0; return rcd; @@ -927,8 +928,8 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) lnet_destroy_rc_data(rcd); } - lnet_net_lock(gateway->lp_cpt); - return gateway->lp_rcd; + lnet_net_lock(gateway->lpni_cpt); + return gateway->lpni_rcd; } static int @@ -936,7 +937,7 @@ lnet_router_check_interval(struct lnet_peer *rtr) { int secs; - secs = rtr->lp_alive ? live_router_check_interval : + secs = rtr->lpni_alive ? live_router_check_interval : dead_router_check_interval; if (secs < 0) secs = 0; @@ -954,12 +955,12 @@ lnet_ping_router_locked(struct lnet_peer *rtr) lnet_peer_addref_locked(rtr); - if (rtr->lp_ping_deadline && /* ping timed out? */ - now > rtr->lp_ping_deadline) + if (rtr->lpni_ping_deadline && /* ping timed out? */ + now > rtr->lpni_ping_deadline) lnet_notify_locked(rtr, 1, 0, now); /* Run any outstanding notifications */ - ni = lnet_get_next_ni_locked(rtr->lp_net, NULL); + ni = lnet_get_next_ni_locked(rtr->lpni_net, NULL); lnet_ni_notify_locked(ni, rtr); if (!lnet_isrouter(rtr) || @@ -969,8 +970,8 @@ lnet_ping_router_locked(struct lnet_peer *rtr) return; } - rcd = rtr->lp_rcd ? - rtr->lp_rcd : lnet_create_rc_data_locked(rtr); + rcd = rtr->lpni_rcd ? + rtr->lpni_rcd : lnet_create_rc_data_locked(rtr); if (!rcd) return; @@ -978,39 +979,40 @@ lnet_ping_router_locked(struct lnet_peer *rtr) secs = lnet_router_check_interval(rtr); CDEBUG(D_NET, - "rtr %s %lldd: deadline %lld ping_notsent %d alive %d alive_count %d lp_ping_timestamp %lld\n", - libcfs_nid2str(rtr->lp_nid), secs, - rtr->lp_ping_deadline, rtr->lp_ping_notsent, - rtr->lp_alive, rtr->lp_alive_count, rtr->lp_ping_timestamp); - - if (secs && !rtr->lp_ping_notsent && - now > rtr->lp_ping_timestamp + secs) { + "rtr %s %lldd: deadline %lld ping_notsent %d alive %d alive_count %d lpni_ping_timestamp %lld\n", + libcfs_nid2str(rtr->lpni_nid), secs, + rtr->lpni_ping_deadline, rtr->lpni_ping_notsent, + rtr->lpni_alive, rtr->lpni_alive_count, + rtr->lpni_ping_timestamp); + + if (secs && !rtr->lpni_ping_notsent && + now > rtr->lpni_ping_timestamp + secs) { int rc; struct lnet_process_id id; struct lnet_handle_md mdh; - id.nid = rtr->lp_nid; + id.nid = rtr->lpni_nid; id.pid = LNET_PID_LUSTRE; CDEBUG(D_NET, "Check: %s\n", libcfs_id2str(id)); - rtr->lp_ping_notsent = 1; - rtr->lp_ping_timestamp = now; + rtr->lpni_ping_notsent = 1; + rtr->lpni_ping_timestamp = now; mdh = rcd->rcd_mdh; - if (!rtr->lp_ping_deadline) { - rtr->lp_ping_deadline = ktime_get_seconds() + + if (!rtr->lpni_ping_deadline) { + rtr->lpni_ping_deadline = ktime_get_seconds() + router_ping_timeout; } - lnet_net_unlock(rtr->lp_cpt); + lnet_net_unlock(rtr->lpni_cpt); rc = LNetGet(LNET_NID_ANY, mdh, id, LNET_RESERVED_PORTAL, LNET_PROTO_PING_MATCHBITS, 0); - lnet_net_lock(rtr->lp_cpt); + lnet_net_lock(rtr->lpni_cpt); if (rc) - rtr->lp_ping_notsent = 0; /* no event pending */ + rtr->lpni_ping_notsent = 0; /* no event pending */ } lnet_peer_decref_locked(rtr); @@ -1106,14 +1108,14 @@ lnet_prune_rc_data(int wait_unlink) if (the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) { /* router checker is stopping, prune all */ list_for_each_entry(lp, &the_lnet.ln_routers, - lp_rtr_list) { - if (!lp->lp_rcd) + lpni_rtr_list) { + if (!lp->lpni_rcd) continue; - LASSERT(list_empty(&lp->lp_rcd->rcd_list)); - list_add(&lp->lp_rcd->rcd_list, + LASSERT(list_empty(&lp->lpni_rcd->rcd_list)); + list_add(&lp->lpni_rcd->rcd_list, &the_lnet.ln_rcd_deathrow); - lp->lp_rcd = NULL; + lp->lpni_rcd = NULL; } } @@ -1206,8 +1208,8 @@ lnet_router_checker(void *arg) rescan: version = the_lnet.ln_routers_version; - list_for_each_entry(rtr, &the_lnet.ln_routers, lp_rtr_list) { - cpt2 = rtr->lp_cpt; + list_for_each_entry(rtr, &the_lnet.ln_routers, lpni_rtr_list) { + cpt2 = rtr->lpni_cpt; if (cpt != cpt2) { lnet_net_unlock(cpt); cpt = cpt2; @@ -1745,8 +1747,8 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) * call us with when == _time_when_the_node_was_booted_ if * no connections were successfully established */ - if (ni && !alive && when < lp->lp_last_alive) - when = lp->lp_last_alive; + if (ni && !alive && when < lp->lpni_last_alive) + when = lp->lpni_last_alive; lnet_notify_locked(lp, !ni, alive, when); diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 52714b898aac..01c9ad44266f 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -214,7 +214,7 @@ static int proc_lnet_routes(struct ctl_table *table, int write, __u32 net = rnet->lrn_net; __u32 hops = route->lr_hops; unsigned int priority = route->lr_priority; - lnet_nid_t nid = route->lr_gateway->lp_nid; + lnet_nid_t nid = route->lr_gateway->lpni_nid; int alive = lnet_is_route_alive(route); s += snprintf(s, tmpstr + tmpsiz - s, @@ -306,7 +306,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, while (r != &the_lnet.ln_routers) { struct lnet_peer *lp; - lp = list_entry(r, struct lnet_peer, lp_rtr_list); + lp = list_entry(r, struct lnet_peer, lpni_rtr_list); if (!skip) { peer = lp; break; @@ -317,21 +317,21 @@ static int proc_lnet_routers(struct ctl_table *table, int write, } if (peer) { - lnet_nid_t nid = peer->lp_nid; + lnet_nid_t nid = peer->lpni_nid; time64_t now = ktime_get_seconds(); - time64_t deadline = peer->lp_ping_deadline; - int nrefs = peer->lp_refcount; - int nrtrrefs = peer->lp_rtr_refcount; - int alive_cnt = peer->lp_alive_count; - int alive = peer->lp_alive; - int pingsent = !peer->lp_ping_notsent; - time64_t last_ping = now - peer->lp_ping_timestamp; + time64_t deadline = peer->lpni_ping_deadline; + int nrefs = peer->lpni_refcount; + int nrtrrefs = peer->lpni_rtr_refcount; + int alive_cnt = peer->lpni_alive_count; + int alive = peer->lpni_alive; + int pingsent = !peer->lpni_ping_notsent; + time64_t last_ping = now - peer->lpni_ping_timestamp; int down_ni = 0; struct lnet_route *rtr; - if ((peer->lp_ping_feats & + if ((peer->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS)) { - list_for_each_entry(rtr, &peer->lp_routes, + list_for_each_entry(rtr, &peer->lpni_routes, lr_gwlist) { /* * downis on any route should be the @@ -452,16 +452,16 @@ static int proc_lnet_peers(struct ctl_table *table, int write, struct lnet_peer *lp; lp = list_entry(p, struct lnet_peer, - lp_hashlist); + lpni_hashlist); if (!skip) { peer = lp; /* * minor optimization: start from idx+1 * on next iteration if we've just - * drained lp_hashlist + * drained lpni_hashlist */ - if (lp->lp_hashlist.next == + if (lp->lpni_hashlist.next == &ptable->pt_hash[hash]) { hoff = 1; hash++; @@ -473,7 +473,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, } skip--; - p = lp->lp_hashlist.next; + p = lp->lpni_hashlist.next; } if (peer) @@ -485,25 +485,25 @@ static int proc_lnet_peers(struct ctl_table *table, int write, } if (peer) { - lnet_nid_t nid = peer->lp_nid; - int nrefs = peer->lp_refcount; + lnet_nid_t nid = peer->lpni_nid; + int nrefs = peer->lpni_refcount; time64_t lastalive = -1; char *aliveness = "NA"; - int maxcr = peer->lp_net->net_tunables.lct_peer_tx_credits; - int txcr = peer->lp_txcredits; - int mintxcr = peer->lp_mintxcredits; - int rtrcr = peer->lp_rtrcredits; - int minrtrcr = peer->lp_minrtrcredits; - int txqnob = peer->lp_txqnob; + int maxcr = peer->lpni_net->net_tunables.lct_peer_tx_credits; + int txcr = peer->lpni_txcredits; + int mintxcr = peer->lpni_mintxcredits; + int rtrcr = peer->lpni_rtrcredits; + int minrtrcr = peer->lpni_minrtrcredits; + int txqnob = peer->lpni_txqnob; if (lnet_isrouter(peer) || lnet_peer_aliveness_enabled(peer)) - aliveness = peer->lp_alive ? "up" : "down"; + aliveness = peer->lpni_alive ? "up" : "down"; if (lnet_peer_aliveness_enabled(peer)) { time64_t now = ktime_get_seconds(); - lastalive = now - peer->lp_last_alive; + lastalive = now - peer->lpni_last_alive; /* No need to mess up peers contents with * arbitrarily long integers - it suffices to From neilb at suse.com Tue Sep 25 01:07:14 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:14 +1000 Subject: [lustre-devel] [PATCH 02/34] lnet: change struct lnet_peer to struct lnet_peer_ni In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763493.32103.9862696546795848039.stgit@noble> Also remove the typedef sed -i -e 's/struct lnet_peer\b/struct lnet_peer_ni/g' -e 's/lnet_peer_t\b/struct lnet_peer_ni/g' `git ls-files lnet` Then edit lib-types.h to remove the typedef, and clean up some long lines. This is part of Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 20 ++++++----- .../staging/lustre/include/linux/lnet/lib-types.h | 10 +++--- drivers/staging/lustre/lnet/lnet/lib-move.c | 26 +++++++-------- drivers/staging/lustre/lnet/lnet/peer.c | 31 +++++++++--------- drivers/staging/lustre/lnet/lnet/router.c | 35 ++++++++++---------- drivers/staging/lustre/lnet/lnet/router_proc.c | 12 +++---- 6 files changed, 68 insertions(+), 66 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 9b54a3d72290..ef53638e20f6 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -311,16 +311,16 @@ lnet_handle2me(struct lnet_handle_me *handle) } static inline void -lnet_peer_addref_locked(struct lnet_peer *lp) +lnet_peer_addref_locked(struct lnet_peer_ni *lp) { LASSERT(lp->lpni_refcount > 0); lp->lpni_refcount++; } -void lnet_destroy_peer_locked(struct lnet_peer *lp); +void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); static inline void -lnet_peer_decref_locked(struct lnet_peer *lp) +lnet_peer_decref_locked(struct lnet_peer_ni *lp) { LASSERT(lp->lpni_refcount > 0); lp->lpni_refcount--; @@ -329,7 +329,7 @@ lnet_peer_decref_locked(struct lnet_peer *lp) } static inline int -lnet_isrouter(struct lnet_peer *lp) +lnet_isrouter(struct lnet_peer_ni *lp) { return lp->lpni_rtr_refcount ? 1 : 0; } @@ -410,7 +410,7 @@ void lnet_lib_exit(void); int lnet_notify(struct lnet_ni *ni, lnet_nid_t peer, int alive, time64_t when); -void lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, +void lnet_notify_locked(struct lnet_peer_ni *lp, int notifylnd, int alive, time64_t when); int lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway_nid, unsigned int priority); @@ -624,7 +624,7 @@ int lnet_peer_buffer_credits(struct lnet_net *net); int lnet_router_checker_start(void); void lnet_router_checker_stop(void); -void lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net); +void lnet_router_ni_update_locked(struct lnet_peer_ni *gw, __u32 net); void lnet_swap_pinginfo(struct lnet_ping_info *info); int lnet_parse_ip2nets(char **networksp, char *ip2nets); @@ -635,9 +635,9 @@ bool lnet_net_unique(__u32 net_id, struct list_head *nilist, struct lnet_net **net); bool lnet_ni_unique_net(struct list_head *nilist, char *iface); -int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); -struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, - lnet_nid_t nid); +int lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); +struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, + lnet_nid_t nid); void lnet_peer_tables_cleanup(struct lnet_ni *ni); void lnet_peer_tables_destroy(void); int lnet_peer_tables_create(void); @@ -650,7 +650,7 @@ int lnet_get_peer_info(__u32 peer_index, __u64 *nid, __u32 *peer_tx_qnob); static inline void -lnet_peer_set_alive(struct lnet_peer *lp) +lnet_peer_set_alive(struct lnet_peer_ni *lp) { lp->lpni_last_query = ktime_get_seconds(); lp->lpni_last_alive = lp->lpni_last_query; diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 59a1a2620675..4b26801d7d29 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -93,8 +93,8 @@ struct lnet_msg { unsigned int msg_onactivelist:1; /* on the activelist */ unsigned int msg_rdma_get:1; - struct lnet_peer *msg_txpeer; /* peer I'm sending to */ - struct lnet_peer *msg_rxpeer; /* peer I received from */ + struct lnet_peer_ni *msg_txpeer; /* peer I'm sending to */ + struct lnet_peer_ni *msg_rxpeer; /* peer I received from */ void *msg_private; struct lnet_libmd *msg_md; @@ -378,12 +378,12 @@ struct lnet_rc_data { /* ping buffer MD */ struct lnet_handle_md rcd_mdh; /* reference to gateway */ - struct lnet_peer *rcd_gateway; + struct lnet_peer_ni *rcd_gateway; /* ping buffer */ struct lnet_ping_info *rcd_pinginfo; }; -struct lnet_peer { +struct lnet_peer_ni { /* chain on peer hash */ struct list_head lpni_hashlist; /* messages blocking for tx credits */ @@ -474,7 +474,7 @@ struct lnet_route { /* chain on gateway */ struct list_head lr_gwlist; /* router node */ - struct lnet_peer *lr_gateway; + struct lnet_peer_ni *lr_gateway; /* remote network number */ __u32 lr_net; /* sequence for round-robin */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 5879a109d46a..4425406e441b 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -491,7 +491,7 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) /* NB: caller shall hold a ref on 'lp' as I'd drop lnet_net_lock */ static void -lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) +lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) { time64_t last_alive = 0; @@ -510,7 +510,7 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) /* NB: always called with lnet_net_lock held */ static inline int -lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) +lnet_peer_is_alive(struct lnet_peer_ni *lp, unsigned long now) { int alive; time64_t deadline; @@ -544,7 +544,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) * may drop the lnet_net_lock */ static int -lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) +lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) { time64_t now = ktime_get_seconds(); @@ -599,7 +599,7 @@ lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) static int lnet_post_send_locked(struct lnet_msg *msg, int do_send) { - struct lnet_peer *lp = msg->msg_txpeer; + struct lnet_peer_ni *lp = msg->msg_txpeer; struct lnet_ni *ni = msg->msg_txni; int cpt = msg->msg_tx_cpt; struct lnet_tx_queue *tq = ni->ni_tx_queues[cpt]; @@ -710,7 +710,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) * I return LNET_CREDIT_WAIT if msg blocked and LNET_CREDIT_OK if * received or OK to receive */ - struct lnet_peer *lp = msg->msg_rxpeer; + struct lnet_peer_ni *lp = msg->msg_rxpeer; struct lnet_rtrbufpool *rbp; struct lnet_rtrbuf *rb; @@ -780,7 +780,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) void lnet_return_tx_credits_locked(struct lnet_msg *msg) { - struct lnet_peer *txpeer = msg->msg_txpeer; + struct lnet_peer_ni *txpeer = msg->msg_txpeer; struct lnet_msg *msg2; struct lnet_ni *txni = msg->msg_txni; @@ -881,7 +881,7 @@ lnet_drop_routed_msgs_locked(struct list_head *list, int cpt) void lnet_return_rx_credits_locked(struct lnet_msg *msg) { - struct lnet_peer *rxpeer = msg->msg_rxpeer; + struct lnet_peer_ni *rxpeer = msg->msg_rxpeer; struct lnet_ni *rxni = msg->msg_rxni; struct lnet_msg *msg2; @@ -971,8 +971,8 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) static int lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) { - struct lnet_peer *p1 = r1->lr_gateway; - struct lnet_peer *p2 = r2->lr_gateway; + struct lnet_peer_ni *p1 = r1->lr_gateway; + struct lnet_peer_ni *p2 = r2->lr_gateway; int r1_hops = (r1->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r1->lr_hops; int r2_hops = (r2->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r2->lr_hops; @@ -1006,7 +1006,7 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) return -ERANGE; } -static struct lnet_peer * +static struct lnet_peer_ni * lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, lnet_nid_t rtr_nid) { @@ -1014,8 +1014,8 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, struct lnet_route *route; struct lnet_route *best_route; struct lnet_route *last_route; - struct lnet_peer *lpni_best; - struct lnet_peer *lp; + struct lnet_peer_ni *lpni_best; + struct lnet_peer_ni *lp; int rc; /* @@ -1076,7 +1076,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) lnet_nid_t dst_nid = msg->msg_target.nid; struct lnet_ni *src_ni; struct lnet_ni *local_ni; - struct lnet_peer *lp; + struct lnet_peer_ni *lp; int cpt; int cpt2; int rc; diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 619d016b1d89..67614309f242 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -106,8 +106,8 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, struct lnet_peer_table *ptable) { int i; - struct lnet_peer *lp; - struct lnet_peer *tmp; + struct lnet_peer_ni *lp; + struct lnet_peer_ni *tmp; for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], @@ -146,8 +146,8 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, struct lnet_peer_table *ptable, int cpt_locked) { - struct lnet_peer *lp; - struct lnet_peer *tmp; + struct lnet_peer_ni *lp; + struct lnet_peer_ni *tmp; lnet_nid_t lpni_nid; int i; @@ -174,7 +174,7 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) { struct lnet_peer_table *ptable; struct list_head deathrow; - struct lnet_peer *lp; + struct lnet_peer_ni *lp; int i; INIT_LIST_HEAD(&deathrow); @@ -209,14 +209,15 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) } while (!list_empty(&deathrow)) { - lp = list_entry(deathrow.next, struct lnet_peer, lpni_hashlist); + lp = list_entry(deathrow.next, struct lnet_peer_ni, + lpni_hashlist); list_del(&lp->lpni_hashlist); kfree(lp); } } void -lnet_destroy_peer_locked(struct lnet_peer *lp) +lnet_destroy_peer_locked(struct lnet_peer_ni *lp) { struct lnet_peer_table *ptable; @@ -237,11 +238,11 @@ lnet_destroy_peer_locked(struct lnet_peer *lp) ptable->pt_zombies--; } -struct lnet_peer * +struct lnet_peer_ni * lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) { struct list_head *peers; - struct lnet_peer *lp; + struct lnet_peer_ni *lp; LASSERT(!the_lnet.ln_shutdown); @@ -257,11 +258,11 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) } int -lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) +lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) { struct lnet_peer_table *ptable; - struct lnet_peer *lp = NULL; - struct lnet_peer *lp2; + struct lnet_peer_ni *lp = NULL; + struct lnet_peer_ni *lp2; int cpt2; int rc = 0; @@ -281,7 +282,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) if (!list_empty(&ptable->pt_deathrow)) { lp = list_entry(ptable->pt_deathrow.next, - struct lnet_peer, lpni_hashlist); + struct lnet_peer_ni, lpni_hashlist); list_del(&lp->lpni_hashlist); } @@ -359,7 +360,7 @@ void lnet_debug_peer(lnet_nid_t nid) { char *aliveness = "NA"; - struct lnet_peer *lp; + struct lnet_peer_ni *lp; int rc; int cpt; @@ -396,7 +397,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, __u32 *peer_tx_qnob) { struct lnet_peer_table *peer_table; - struct lnet_peer *lp; + struct lnet_peer_ni *lp; bool found = false; int lncpt, j; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 2be1ffb6b720..31685406dcc3 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -100,7 +100,7 @@ lnet_peers_start_down(void) } void -lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, +lnet_notify_locked(struct lnet_peer_ni *lp, int notifylnd, int alive, time64_t when) { if (lp->lpni_timestamp > when) { /* out of date information */ @@ -130,7 +130,7 @@ lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, } static void -lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) +lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) { int alive; int notifylnd; @@ -170,7 +170,7 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) } static void -lnet_rtr_addref_locked(struct lnet_peer *lp) +lnet_rtr_addref_locked(struct lnet_peer_ni *lp) { LASSERT(lp->lpni_refcount > 0); LASSERT(lp->lpni_rtr_refcount >= 0); @@ -182,9 +182,10 @@ lnet_rtr_addref_locked(struct lnet_peer *lp) /* a simple insertion sort */ list_for_each_prev(pos, &the_lnet.ln_routers) { - struct lnet_peer *rtr; + struct lnet_peer_ni *rtr; - rtr = list_entry(pos, struct lnet_peer, lpni_rtr_list); + rtr = list_entry(pos, struct lnet_peer_ni, + lpni_rtr_list); if (rtr->lpni_nid < lp->lpni_nid) break; } @@ -197,7 +198,7 @@ lnet_rtr_addref_locked(struct lnet_peer *lp) } static void -lnet_rtr_decref_locked(struct lnet_peer *lp) +lnet_rtr_decref_locked(struct lnet_peer_ni *lp) { LASSERT(lp->lpni_refcount > 0); LASSERT(lp->lpni_rtr_refcount > 0); @@ -453,7 +454,7 @@ lnet_check_routes(void) int lnet_del_route(__u32 net, lnet_nid_t gw_nid) { - struct lnet_peer *gateway; + struct lnet_peer_ni *gateway; struct lnet_remotenet *rnet; struct lnet_route *route; int rc = -ENOENT; @@ -614,7 +615,7 @@ static void lnet_parse_rc_info(struct lnet_rc_data *rcd) { struct lnet_ping_info *info = rcd->rcd_pinginfo; - struct lnet_peer *gw = rcd->rcd_gateway; + struct lnet_peer_ni *gw = rcd->rcd_gateway; struct lnet_route *rte; if (!gw->lpni_alive) @@ -703,7 +704,7 @@ static void lnet_router_checker_event(struct lnet_event *event) { struct lnet_rc_data *rcd = event->md.user_ptr; - struct lnet_peer *lp; + struct lnet_peer_ni *lp; LASSERT(rcd); @@ -760,7 +761,7 @@ lnet_router_checker_event(struct lnet_event *event) static void lnet_wait_known_routerstate(void) { - struct lnet_peer *rtr; + struct lnet_peer_ni *rtr; int all_known; LASSERT(the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING); @@ -786,7 +787,7 @@ lnet_wait_known_routerstate(void) } void -lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) +lnet_router_ni_update_locked(struct lnet_peer_ni *gw, __u32 net) { struct lnet_route *rte; @@ -863,7 +864,7 @@ lnet_destroy_rc_data(struct lnet_rc_data *rcd) } static struct lnet_rc_data * -lnet_create_rc_data_locked(struct lnet_peer *gateway) +lnet_create_rc_data_locked(struct lnet_peer_ni *gateway) { struct lnet_rc_data *rcd = NULL; struct lnet_ping_info *pi; @@ -933,7 +934,7 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) } static int -lnet_router_check_interval(struct lnet_peer *rtr) +lnet_router_check_interval(struct lnet_peer_ni *rtr) { int secs; @@ -946,7 +947,7 @@ lnet_router_check_interval(struct lnet_peer *rtr) } static void -lnet_ping_router_locked(struct lnet_peer *rtr) +lnet_ping_router_locked(struct lnet_peer_ni *rtr) { struct lnet_rc_data *rcd = NULL; time64_t now = ktime_get_seconds(); @@ -1092,7 +1093,7 @@ lnet_prune_rc_data(int wait_unlink) { struct lnet_rc_data *rcd; struct lnet_rc_data *tmp; - struct lnet_peer *lp; + struct lnet_peer_ni *lp; struct list_head head; int i = 2; @@ -1197,7 +1198,7 @@ lnet_router_checker_active(void) static int lnet_router_checker(void *arg) { - struct lnet_peer *rtr; + struct lnet_peer_ni *rtr; while (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING) { __u64 version; @@ -1693,7 +1694,7 @@ lnet_rtrpools_disable(void) int lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) { - struct lnet_peer *lp = NULL; + struct lnet_peer_ni *lp = NULL; time64_t now = ktime_get_seconds(); int cpt = lnet_cpt_of_nid(nid, ni); diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 01c9ad44266f..d0340707feaa 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -289,7 +289,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, *ppos = LNET_PROC_POS_MAKE(0, ver, 0, off); } else { struct list_head *r; - struct lnet_peer *peer = NULL; + struct lnet_peer_ni *peer = NULL; int skip = off - 1; lnet_net_lock(0); @@ -304,9 +304,9 @@ static int proc_lnet_routers(struct ctl_table *table, int write, r = the_lnet.ln_routers.next; while (r != &the_lnet.ln_routers) { - struct lnet_peer *lp; + struct lnet_peer_ni *lp; - lp = list_entry(r, struct lnet_peer, lpni_rtr_list); + lp = list_entry(r, struct lnet_peer_ni, lpni_rtr_list); if (!skip) { peer = lp; break; @@ -425,7 +425,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, hoff++; } else { - struct lnet_peer *peer; + struct lnet_peer_ni *peer; struct list_head *p; int skip; again: @@ -449,9 +449,9 @@ static int proc_lnet_peers(struct ctl_table *table, int write, p = ptable->pt_hash[hash].next; while (p != &ptable->pt_hash[hash]) { - struct lnet_peer *lp; + struct lnet_peer_ni *lp; - lp = list_entry(p, struct lnet_peer, + lp = list_entry(p, struct lnet_peer_ni, lpni_hashlist); if (!skip) { peer = lp; From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 03/34] lnet: Change lpni_refcount to atomic_t In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763497.32103.13856612081166369948.stgit@noble> This is part of Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 10 +++++----- .../staging/lustre/include/linux/lnet/lib-types.h | 2 +- drivers/staging/lustre/lnet/lnet/peer.c | 8 ++++---- drivers/staging/lustre/lnet/lnet/router.c | 4 ++-- drivers/staging/lustre/lnet/lnet/router_proc.c | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index ef53638e20f6..88e010aa3f68 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -313,8 +313,8 @@ lnet_handle2me(struct lnet_handle_me *handle) static inline void lnet_peer_addref_locked(struct lnet_peer_ni *lp) { - LASSERT(lp->lpni_refcount > 0); - lp->lpni_refcount++; + LASSERT(atomic_read(&lp->lpni_refcount) > 0); + atomic_inc(&lp->lpni_refcount); } void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); @@ -322,9 +322,9 @@ void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); static inline void lnet_peer_decref_locked(struct lnet_peer_ni *lp) { - LASSERT(lp->lpni_refcount > 0); - lp->lpni_refcount--; - if (!lp->lpni_refcount) + LASSERT(atomic_read(&lp->lpni_refcount) > 0); + atomic_dec(&lp->lpni_refcount); + if (atomic_read(&lp->lpni_refcount) == 0) lnet_destroy_peer_locked(lp); } diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 4b26801d7d29..9a2cf319dba9 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -429,7 +429,7 @@ struct lnet_peer_ni { /* peer's NID */ lnet_nid_t lpni_nid; /* # refs */ - int lpni_refcount; + atomic_t lpni_refcount; /* CPT this peer attached on */ int lpni_cpt; /* # refs from lnet_route::lr_gateway */ diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 67614309f242..7475678ea184 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -221,7 +221,7 @@ lnet_destroy_peer_locked(struct lnet_peer_ni *lp) { struct lnet_peer_table *ptable; - LASSERT(!lp->lpni_refcount); + LASSERT(atomic_read(&lp->lpni_refcount) == 0); LASSERT(!lp->lpni_rtr_refcount); LASSERT(list_empty(&lp->lpni_txq)); LASSERT(list_empty(&lp->lpni_hashlist)); @@ -320,7 +320,7 @@ lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; lp->lpni_nid = nid; lp->lpni_cpt = cpt2; - lp->lpni_refcount = 2; /* 1 for caller; 1 for hash */ + atomic_set(&lp->lpni_refcount, 2); /* 1 for caller; 1 for hash */ lp->lpni_rtr_refcount = 0; lnet_net_lock(cpt); @@ -378,7 +378,7 @@ lnet_debug_peer(lnet_nid_t nid) aliveness = lp->lpni_alive ? "up" : "down"; CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", - libcfs_nid2str(lp->lpni_nid), lp->lpni_refcount, + libcfs_nid2str(lp->lpni_nid), atomic_read(&lp->lpni_refcount), aliveness, lp->lpni_net->net_tunables.lct_peer_tx_credits, lp->lpni_rtrcredits, lp->lpni_minrtrcredits, lp->lpni_txcredits, lp->lpni_mintxcredits, lp->lpni_txqnob); @@ -433,7 +433,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, lp->lpni_alive ? "up" : "down"); *nid = lp->lpni_nid; - *refcount = lp->lpni_refcount; + *refcount = atomic_read(&lp->lpni_refcount); *ni_peer_tx_credits = lp->lpni_net->net_tunables.lct_peer_tx_credits; *peer_tx_credits = lp->lpni_txcredits; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 31685406dcc3..bfd4b22cc28a 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -172,7 +172,7 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) static void lnet_rtr_addref_locked(struct lnet_peer_ni *lp) { - LASSERT(lp->lpni_refcount > 0); + LASSERT(atomic_read(&lp->lpni_refcount) > 0); LASSERT(lp->lpni_rtr_refcount >= 0); /* lnet_net_lock must be exclusively locked */ @@ -200,7 +200,7 @@ lnet_rtr_addref_locked(struct lnet_peer_ni *lp) static void lnet_rtr_decref_locked(struct lnet_peer_ni *lp) { - LASSERT(lp->lpni_refcount > 0); + LASSERT(atomic_read(&lp->lpni_refcount) > 0); LASSERT(lp->lpni_rtr_refcount > 0); /* lnet_net_lock must be exclusively locked */ diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index d0340707feaa..12a4b1708d3c 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -320,7 +320,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, lnet_nid_t nid = peer->lpni_nid; time64_t now = ktime_get_seconds(); time64_t deadline = peer->lpni_ping_deadline; - int nrefs = peer->lpni_refcount; + int nrefs = atomic_read(&peer->lpni_refcount); int nrtrrefs = peer->lpni_rtr_refcount; int alive_cnt = peer->lpni_alive_count; int alive = peer->lpni_alive; @@ -486,7 +486,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, if (peer) { lnet_nid_t nid = peer->lpni_nid; - int nrefs = peer->lpni_refcount; + int nrefs = atomic_read(&peer->lpni_refcount); time64_t lastalive = -1; char *aliveness = "NA"; int maxcr = peer->lpni_net->net_tunables.lct_peer_tx_credits; From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 04/34] lnet: change some function names - add 'ni'. In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763501.32103.12514510583840060159.stgit@noble> sed -i 's/lnet_peer_addref_locked/lnet_peer_ni_addref_locked/g' `git grep -l lnet_peer_addref_locked lnet/` sed -i 's/lnet_destroy_peer_locked/lnet_destroy_peer_ni_locked/g' `git grep -l lnet_destroy_peer_locked lnet/` sed -i 's/lnet_peer_decref_locked/lnet_peer_ni_decref_locked/g' `git grep -l lnet_peer_decref_locked lnet/` sed -i 's/lnet_nid2peer_locked/lnet_nid2peerni_locked/g' `git grep -l lnet_nid2peer_locked lnet/` This is part of Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 10 ++++---- drivers/staging/lustre/lnet/lnet/lib-move.c | 10 ++++---- drivers/staging/lustre/lnet/lnet/peer.c | 12 +++++----- drivers/staging/lustre/lnet/lnet/router.c | 24 ++++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 88e010aa3f68..a1c581069eb1 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -311,21 +311,21 @@ lnet_handle2me(struct lnet_handle_me *handle) } static inline void -lnet_peer_addref_locked(struct lnet_peer_ni *lp) +lnet_peer_ni_addref_locked(struct lnet_peer_ni *lp) { LASSERT(atomic_read(&lp->lpni_refcount) > 0); atomic_inc(&lp->lpni_refcount); } -void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); +void lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp); static inline void -lnet_peer_decref_locked(struct lnet_peer_ni *lp) +lnet_peer_ni_decref_locked(struct lnet_peer_ni *lp) { LASSERT(atomic_read(&lp->lpni_refcount) > 0); atomic_dec(&lp->lpni_refcount); if (atomic_read(&lp->lpni_refcount) == 0) - lnet_destroy_peer_locked(lp); + lnet_destroy_peer_ni_locked(lp); } static inline int @@ -635,7 +635,7 @@ bool lnet_net_unique(__u32 net_id, struct list_head *nilist, struct lnet_net **net); bool lnet_ni_unique_net(struct list_head *nilist, char *iface); -int lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); +int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid); void lnet_peer_tables_cleanup(struct lnet_ni *ni); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 4425406e441b..edbec7e9ed7e 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -837,7 +837,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) if (txpeer) { msg->msg_txpeer = NULL; - lnet_peer_decref_locked(txpeer); + lnet_peer_ni_decref_locked(txpeer); } } @@ -964,7 +964,7 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) } if (rxpeer) { msg->msg_rxpeer = NULL; - lnet_peer_decref_locked(rxpeer); + lnet_peer_ni_decref_locked(rxpeer); } } @@ -1148,7 +1148,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) return 0; } - rc = lnet_nid2peer_locked(&lp, dst_nid, cpt); + rc = lnet_nid2peerni_locked(&lp, dst_nid, cpt); if (rc) { lnet_net_unlock(cpt); LCONSOLE_WARN("Error %d finding peer %s\n", rc, @@ -1199,7 +1199,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) LASSERT(src_ni->ni_net == lp->lpni_net); } - lnet_peer_addref_locked(lp); + lnet_peer_ni_addref_locked(lp); LASSERT(src_nid != LNET_NID_ANY); lnet_msg_commit(msg, cpt); @@ -1810,7 +1810,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, } lnet_net_lock(cpt); - rc = lnet_nid2peer_locked(&msg->msg_rxpeer, from_nid, cpt); + rc = lnet_nid2peerni_locked(&msg->msg_rxpeer, from_nid, cpt); if (rc) { lnet_net_unlock(cpt); CERROR("%s, src %s: Dropping %s (error %d looking up sender)\n", diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 7475678ea184..fcfad77b9f2c 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -117,7 +117,7 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, list_del_init(&lp->lpni_hashlist); /* Lose hash table's ref */ ptable->pt_zombies++; - lnet_peer_decref_locked(lp); + lnet_peer_ni_decref_locked(lp); } } } @@ -217,7 +217,7 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) } void -lnet_destroy_peer_locked(struct lnet_peer_ni *lp) +lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp) { struct lnet_peer_table *ptable; @@ -249,7 +249,7 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; list_for_each_entry(lp, peers, lpni_hashlist) { if (lp->lpni_nid == nid) { - lnet_peer_addref_locked(lp); + lnet_peer_ni_addref_locked(lp); return lp; } } @@ -258,7 +258,7 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) } int -lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) +lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) { struct lnet_peer_table *ptable; struct lnet_peer_ni *lp = NULL; @@ -367,7 +367,7 @@ lnet_debug_peer(lnet_nid_t nid) cpt = lnet_cpt_of_nid(nid, NULL); lnet_net_lock(cpt); - rc = lnet_nid2peer_locked(&lp, nid, cpt); + rc = lnet_nid2peerni_locked(&lp, nid, cpt); if (rc) { lnet_net_unlock(cpt); CDEBUG(D_WARNING, "No peer %s\n", libcfs_nid2str(nid)); @@ -383,7 +383,7 @@ lnet_debug_peer(lnet_nid_t nid) lp->lpni_rtrcredits, lp->lpni_minrtrcredits, lp->lpni_txcredits, lp->lpni_mintxcredits, lp->lpni_txqnob); - lnet_peer_decref_locked(lp); + lnet_peer_ni_decref_locked(lp); lnet_net_unlock(cpt); } diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index bfd4b22cc28a..ba2b2b930576 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -192,7 +192,7 @@ lnet_rtr_addref_locked(struct lnet_peer_ni *lp) list_add(&lp->lpni_rtr_list, pos); /* addref for the_lnet.ln_routers */ - lnet_peer_addref_locked(lp); + lnet_peer_ni_addref_locked(lp); the_lnet.ln_routers_version++; } } @@ -216,7 +216,7 @@ lnet_rtr_decref_locked(struct lnet_peer_ni *lp) list_del(&lp->lpni_rtr_list); /* decref for the_lnet.ln_routers */ - lnet_peer_decref_locked(lp); + lnet_peer_ni_decref_locked(lp); the_lnet.ln_routers_version++; } } @@ -332,7 +332,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, lnet_net_lock(LNET_LOCK_EX); - rc = lnet_nid2peer_locked(&route->lr_gateway, gateway, LNET_LOCK_EX); + rc = lnet_nid2peerni_locked(&route->lr_gateway, gateway, LNET_LOCK_EX); if (rc) { lnet_net_unlock(LNET_LOCK_EX); @@ -370,7 +370,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, } if (add_route) { - lnet_peer_addref_locked(route->lr_gateway); /* +1 for notify */ + lnet_peer_ni_addref_locked(route->lr_gateway); /* +1 for notify */ lnet_add_route_to_rnet(rnet2, route); ni = lnet_get_next_ni_locked(route->lr_gateway->lpni_net, NULL); @@ -384,7 +384,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, } /* -1 for notify or !add_route */ - lnet_peer_decref_locked(route->lr_gateway); + lnet_peer_ni_decref_locked(route->lr_gateway); lnet_net_unlock(LNET_LOCK_EX); rc = 0; @@ -496,7 +496,7 @@ lnet_del_route(__u32 net, lnet_nid_t gw_nid) rnet = NULL; lnet_rtr_decref_locked(gateway); - lnet_peer_decref_locked(gateway); + lnet_peer_ni_decref_locked(gateway); lnet_net_unlock(LNET_LOCK_EX); @@ -854,7 +854,7 @@ lnet_destroy_rc_data(struct lnet_rc_data *rcd) int cpt = rcd->rcd_gateway->lpni_cpt; lnet_net_lock(cpt); - lnet_peer_decref_locked(rcd->rcd_gateway); + lnet_peer_ni_decref_locked(rcd->rcd_gateway); lnet_net_unlock(cpt); } @@ -913,7 +913,7 @@ lnet_create_rc_data_locked(struct lnet_peer_ni *gateway) goto out; } - lnet_peer_addref_locked(gateway); + lnet_peer_ni_addref_locked(gateway); rcd->rcd_gateway = gateway; gateway->lpni_rcd = rcd; gateway->lpni_ping_notsent = 0; @@ -954,7 +954,7 @@ lnet_ping_router_locked(struct lnet_peer_ni *rtr) time64_t secs; struct lnet_ni *ni; - lnet_peer_addref_locked(rtr); + lnet_peer_ni_addref_locked(rtr); if (rtr->lpni_ping_deadline && /* ping timed out? */ now > rtr->lpni_ping_deadline) @@ -967,7 +967,7 @@ lnet_ping_router_locked(struct lnet_peer_ni *rtr) if (!lnet_isrouter(rtr) || the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) { /* router table changed or router checker is shutting down */ - lnet_peer_decref_locked(rtr); + lnet_peer_ni_decref_locked(rtr); return; } @@ -1016,7 +1016,7 @@ lnet_ping_router_locked(struct lnet_peer_ni *rtr) rtr->lpni_ping_notsent = 0; /* no event pending */ } - lnet_peer_decref_locked(rtr); + lnet_peer_ni_decref_locked(rtr); } int @@ -1756,7 +1756,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) if (ni) lnet_ni_notify_locked(ni, lp); - lnet_peer_decref_locked(lp); + lnet_peer_ni_decref_locked(lp); lnet_net_unlock(cpt); return 0; From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 05/34] lnet: make lnet_nid_cpt_hash non-static. In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763504.32103.13261120162709788445.stgit@noble> Future patch will need this. This is part of Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + drivers/staging/lustre/lnet/lnet/api-ni.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index a1c581069eb1..f925e3cd64ca 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -395,6 +395,7 @@ lnet_net2rnethash(__u32 net) extern struct lnet_lnd the_lolnd; extern int avoid_asym_router_failure; +unsigned int lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number); int lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni); int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 1b47cbd6fd68..20fa3fea04b9 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -693,7 +693,7 @@ lnet_get_net_locked(__u32 net_id) return NULL; } -static unsigned int +unsigned int lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) { __u64 key = nid; From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 06/34] lnet: introduce lnet_find_peer_ni_locked() In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763508.32103.13303107512736711408.stgit@noble> Use in place of lnet_find_peer_locked() This is part of Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + drivers/staging/lustre/lnet/lnet/peer.c | 31 ++++++++++++++++++++ drivers/staging/lustre/lnet/lnet/router.c | 2 + 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index f925e3cd64ca..656177b64336 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -639,6 +639,7 @@ bool lnet_ni_unique_net(struct list_head *nilist, char *iface); int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid); +struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt); void lnet_peer_tables_cleanup(struct lnet_ni *ni); void lnet_peer_tables_destroy(void); int lnet_peer_tables_create(void); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index fcfad77b9f2c..53b0ca0a2021 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -216,6 +216,37 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) } } +static struct lnet_peer_ni * +lnet_get_peer_ni_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) +{ + struct list_head *peers; + struct lnet_peer_ni *lp; + + LASSERT(!the_lnet.ln_shutdown); + + peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; + list_for_each_entry(lp, peers, lpni_hashlist) { + if (lp->lpni_nid == nid) { + lnet_peer_ni_addref_locked(lp); + return lp; + } + } + + return NULL; +} + +struct lnet_peer_ni * +lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt) +{ + struct lnet_peer_ni *lpni; + struct lnet_peer_table *ptable; + + ptable = the_lnet.ln_peer_tables[cpt]; + lpni = lnet_get_peer_ni_locked(ptable, nid); + + return lpni; +} + void lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp) { diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index ba2b2b930576..de037a77671d 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -1734,7 +1734,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) return -ESHUTDOWN; } - lp = lnet_find_peer_locked(the_lnet.ln_peer_tables[cpt], nid); + lp = lnet_find_peer_ni_locked(nid, cpt); if (!lp) { /* nid not found */ lnet_net_unlock(cpt); From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 07/34] lnet: lnet_peer_tables_cleanup: use an exclusive lock. In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763511.32103.5073326313518943569.stgit@noble> Why?? surely this will deadlock. This is part of Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") from upstream lustre, where it is marked: Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/peer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 53b0ca0a2021..376e3459fa92 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -185,9 +185,9 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) * peers are gateways for. */ cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { - lnet_net_lock(i); + lnet_net_lock(LNET_LOCK_EX); lnet_peer_table_del_rtrs_locked(ni, ptable, i); - lnet_net_unlock(i); + lnet_net_unlock(LNET_LOCK_EX); } /* @@ -195,17 +195,17 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) * deathrow. */ cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { - lnet_net_lock(i); + lnet_net_lock(LNET_LOCK_EX); lnet_peer_table_cleanup_locked(ni, ptable); - lnet_net_unlock(i); + lnet_net_unlock(LNET_LOCK_EX); } /* Cleanup all entries on deathrow. */ cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { - lnet_net_lock(i); + lnet_net_lock(LNET_LOCK_EX); lnet_peer_table_deathrow_wait_locked(ptable, i); list_splice_init(&ptable->pt_deathrow, &deathrow); - lnet_net_unlock(i); + lnet_net_unlock(LNET_LOCK_EX); } while (!list_empty(&deathrow)) { From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 08/34] LU-7734 lnet: Multi-Rail peer split In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763514.32103.5823547209878409504.stgit@noble> From: Amir Shehata [[Note, the preceding few patches are part of this in the upstream lustre code - they were split for easier merging into linux. ]] Split the peer structure into peer/peer_net/peer_ni, as described in the Multi-Rail HLD. Removed deathrow list in peers, instead peers are immediately deleted. deathrow complicates memory management for peers to little gain. Moved to LNET_LOCK_EX for any operations which will modify the peer tables. And CPT locks for any operatios which read the peer tables. Therefore there is no need to use lnet_cpt_of_nid() to calculate the CPT of the peer NID, instead we use lnet_nid_cpt_hash() to distribute peers across multiple CPTs. It is no longe true that peers and NIs would exist on the same CPT. In the new design peers and NIs don't have a 1-1 relationship. You can send to the same peer from several NIs, which can exist on separate CPTs Signed-off-by: Amir Shehata Change-Id: Ida41d830d38d0ab2bb551476e4a8866d52a25fe2 Reviewed-on: http://review.whamcloud.com/18293 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 2 .../staging/lustre/include/linux/lnet/lib-types.h | 29 ++ drivers/staging/lustre/lnet/lnet/api-ni.c | 1 drivers/staging/lustre/lnet/lnet/peer.c | 260 ++++++++++++-------- drivers/staging/lustre/lnet/lnet/router_proc.c | 3 5 files changed, 191 insertions(+), 104 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 656177b64336..bf076298de71 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -637,8 +637,6 @@ bool lnet_net_unique(__u32 net_id, struct list_head *nilist, bool lnet_ni_unique_net(struct list_head *nilist, char *iface); int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); -struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, - lnet_nid_t nid); struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt); void lnet_peer_tables_cleanup(struct lnet_ni *ni); void lnet_peer_tables_destroy(void); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 9a2cf319dba9..9f70c094cc4c 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -384,6 +384,7 @@ struct lnet_rc_data { }; struct lnet_peer_ni { + struct list_head lpni_on_peer_net_list; /* chain on peer hash */ struct list_head lpni_hashlist; /* messages blocking for tx credits */ @@ -394,6 +395,7 @@ struct lnet_peer_ni { struct list_head lpni_rtr_list; /* # tx credits available */ int lpni_txcredits; + struct lnet_peer_net *lpni_peer_net; /* low water mark */ int lpni_mintxcredits; /* # router credits */ @@ -442,6 +444,31 @@ struct lnet_peer_ni { struct lnet_rc_data *lpni_rcd; }; +struct lnet_peer { + /* chain on global peer list */ + struct list_head lp_on_lnet_peer_list; + + /* list of peer nets */ + struct list_head lp_peer_nets; + + /* primary NID of the peer */ + lnet_nid_t lp_primary_nid; +}; + +struct lnet_peer_net { + /* chain on peer block */ + struct list_head lpn_on_peer_list; + + /* list of peer_nis on this network */ + struct list_head lpn_peer_nis; + + /* pointer to the peer I'm part of */ + struct lnet_peer *lpn_peer; + + /* Net ID */ + __u32 lpn_net_id; +}; + /* peer hash size */ #define LNET_PEER_HASH_BITS 9 #define LNET_PEER_HASH_SIZE (1 << LNET_PEER_HASH_BITS) @@ -686,6 +713,8 @@ struct lnet { struct lnet_msg_container **ln_msg_containers; struct lnet_counters **ln_counters; struct lnet_peer_table **ln_peer_tables; + /* list of configured or discovered peers */ + struct list_head ln_peers; /* failure simulation */ struct list_head ln_test_peers; struct list_head ln_drop_rules; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 20fa3fea04b9..821b030f9621 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -542,6 +542,7 @@ lnet_prepare(lnet_pid_t requested_pid) the_lnet.ln_pid = requested_pid; INIT_LIST_HEAD(&the_lnet.ln_test_peers); + INIT_LIST_HEAD(&the_lnet.ln_peers); INIT_LIST_HEAD(&the_lnet.ln_nets); INIT_LIST_HEAD(&the_lnet.ln_routers); INIT_LIST_HEAD(&the_lnet.ln_drop_rules); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 376e3459fa92..97ee1f5cfd2f 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -54,8 +54,6 @@ lnet_peer_tables_create(void) } cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { - INIT_LIST_HEAD(&ptable->pt_deathrow); - hash = kvmalloc_cpt(LNET_PEER_HASH_SIZE * sizeof(*hash), GFP_KERNEL, i); if (!hash) { @@ -88,8 +86,6 @@ lnet_peer_tables_destroy(void) if (!hash) /* not initialized */ break; - LASSERT(list_empty(&ptable->pt_deathrow)); - ptable->pt_hash = NULL; for (j = 0; j < LNET_PEER_HASH_SIZE; j++) LASSERT(list_empty(&hash[j])); @@ -123,7 +119,7 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, } static void -lnet_peer_table_deathrow_wait_locked(struct lnet_peer_table *ptable, +lnet_peer_table_finalize_wait_locked(struct lnet_peer_table *ptable, int cpt_locked) { int i; @@ -173,12 +169,8 @@ void lnet_peer_tables_cleanup(struct lnet_ni *ni) { struct lnet_peer_table *ptable; - struct list_head deathrow; - struct lnet_peer_ni *lp; int i; - INIT_LIST_HEAD(&deathrow); - LASSERT(the_lnet.ln_shutdown || ni); /* * If just deleting the peers for a NI, get rid of any routes these @@ -191,8 +183,7 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) } /* - * Start the process of moving the applicable peers to - * deathrow. + * Start the cleanup process */ cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { lnet_net_lock(LNET_LOCK_EX); @@ -200,20 +191,12 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) lnet_net_unlock(LNET_LOCK_EX); } - /* Cleanup all entries on deathrow. */ + /* Wait until all peers have been destroyed. */ cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { lnet_net_lock(LNET_LOCK_EX); - lnet_peer_table_deathrow_wait_locked(ptable, i); - list_splice_init(&ptable->pt_deathrow, &deathrow); + lnet_peer_table_finalize_wait_locked(ptable, i); lnet_net_unlock(LNET_LOCK_EX); } - - while (!list_empty(&deathrow)) { - lp = list_entry(deathrow.next, struct lnet_peer_ni, - lpni_hashlist); - list_del(&lp->lpni_hashlist); - kfree(lp); - } } static struct lnet_peer_ni * @@ -247,74 +230,143 @@ lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt) return lpni; } -void -lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp) +static void +lnet_try_destroy_peer_hierarchy_locked(struct lnet_peer_ni *lpni) { - struct lnet_peer_table *ptable; + struct lnet_peer_net *peer_net; + struct lnet_peer *peer; - LASSERT(atomic_read(&lp->lpni_refcount) == 0); - LASSERT(!lp->lpni_rtr_refcount); - LASSERT(list_empty(&lp->lpni_txq)); - LASSERT(list_empty(&lp->lpni_hashlist)); - LASSERT(!lp->lpni_txqnob); + /* TODO: could the below situation happen? accessing an already + * destroyed peer? + */ + if (!lpni->lpni_peer_net || + !lpni->lpni_peer_net->lpn_peer) + return; - ptable = the_lnet.ln_peer_tables[lp->lpni_cpt]; - LASSERT(ptable->pt_number > 0); - ptable->pt_number--; + peer_net = lpni->lpni_peer_net; + peer = lpni->lpni_peer_net->lpn_peer; - lp->lpni_net = NULL; + list_del_init(&lpni->lpni_on_peer_net_list); + lpni->lpni_peer_net = NULL; - list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); - LASSERT(ptable->pt_zombies > 0); - ptable->pt_zombies--; + /* if peer_net is empty, then remove it from the peer */ + if (list_empty(&peer_net->lpn_peer_nis)) { + list_del_init(&peer_net->lpn_on_peer_list); + peer_net->lpn_peer = NULL; + kfree(peer_net); + + /* If the peer is empty then remove it from the + * the_lnet.ln_peers + */ + if (list_empty(&peer->lp_peer_nets)) { + list_del_init(&peer->lp_on_lnet_peer_list); + kfree(peer); + } + } } -struct lnet_peer_ni * -lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) +static int +lnet_build_peer_hierarchy(struct lnet_peer_ni *lpni) { - struct list_head *peers; - struct lnet_peer_ni *lp; + struct lnet_peer *peer; + struct lnet_peer_net *peer_net; + __u32 lpni_net = LNET_NIDNET(lpni->lpni_nid); - LASSERT(!the_lnet.ln_shutdown); + peer = NULL; + peer_net = NULL; - peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; - list_for_each_entry(lp, peers, lpni_hashlist) { - if (lp->lpni_nid == nid) { - lnet_peer_ni_addref_locked(lp); - return lp; - } + peer = kzalloc(sizeof(*peer), GFP_KERNEL); + if (!peer) + return -ENOMEM; + + peer_net = kzalloc(sizeof(*peer_net), GFP_KERNEL); + if (!peer_net) { + kfree(peer); + return -ENOMEM; } - return NULL; + INIT_LIST_HEAD(&peer->lp_on_lnet_peer_list); + INIT_LIST_HEAD(&peer->lp_peer_nets); + INIT_LIST_HEAD(&peer_net->lpn_on_peer_list); + INIT_LIST_HEAD(&peer_net->lpn_peer_nis); + + /* build the hierarchy */ + peer_net->lpn_net_id = lpni_net; + peer_net->lpn_peer = peer; + lpni->lpni_peer_net = peer_net; + peer->lp_primary_nid = lpni->lpni_nid; + list_add_tail(&peer_net->lpn_on_peer_list, &peer->lp_peer_nets); + list_add_tail(&lpni->lpni_on_peer_net_list, &peer_net->lpn_peer_nis); + list_add_tail(&peer->lp_on_lnet_peer_list, &the_lnet.ln_peers); + + return 0; +} + +void +lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lpni) +{ + struct lnet_peer_table *ptable; + + LASSERT(atomic_read(&lpni->lpni_refcount) == 0); + LASSERT(lpni->lpni_rtr_refcount == 0); + LASSERT(list_empty(&lpni->lpni_txq)); + LASSERT(list_empty(&lpni->lpni_hashlist)); + LASSERT(lpni->lpni_txqnob == 0); + LASSERT(lpni->lpni_peer_net); + LASSERT(lpni->lpni_peer_net->lpn_peer); + + ptable = the_lnet.ln_peer_tables[lpni->lpni_cpt]; + LASSERT(ptable->pt_number > 0); + ptable->pt_number--; + + lpni->lpni_net = NULL; + + lnet_try_destroy_peer_hierarchy_locked(lpni); + + kfree(lpni); + + LASSERT(ptable->pt_zombies > 0); + ptable->pt_zombies--; } int -lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) +lnet_nid2peerni_locked(struct lnet_peer_ni **lpnip, lnet_nid_t nid, int cpt) { struct lnet_peer_table *ptable; - struct lnet_peer_ni *lp = NULL; - struct lnet_peer_ni *lp2; + struct lnet_peer_ni *lpni = NULL; + struct lnet_peer_ni *lpni2; int cpt2; int rc = 0; - *lpp = NULL; + *lpnip = NULL; if (the_lnet.ln_shutdown) /* it's shutting down */ return -ESHUTDOWN; - /* cpt can be LNET_LOCK_EX if it's called from router functions */ - cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid, NULL); + /* + * calculate cpt2 with the standard hash function + * This cpt2 becomes the slot where we'll find or create the peer. + */ + cpt2 = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); - ptable = the_lnet.ln_peer_tables[cpt2]; - lp = lnet_find_peer_locked(ptable, nid); - if (lp) { - *lpp = lp; - return 0; + /* + * Any changes to the peer tables happen under exclusive write + * lock. Any reads to the peer tables can be done via a standard + * CPT read lock. + */ + if (cpt != LNET_LOCK_EX) { + lnet_net_unlock(cpt); + lnet_net_lock(LNET_LOCK_EX); } - if (!list_empty(&ptable->pt_deathrow)) { - lp = list_entry(ptable->pt_deathrow.next, - struct lnet_peer_ni, lpni_hashlist); - list_del(&lp->lpni_hashlist); + ptable = the_lnet.ln_peer_tables[cpt2]; + lpni = lnet_get_peer_ni_locked(ptable, nid); + if (lpni) { + *lpnip = lpni; + if (cpt != LNET_LOCK_EX) { + lnet_net_unlock(LNET_LOCK_EX); + lnet_net_lock(cpt); + } + return 0; } /* @@ -322,68 +374,72 @@ lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) * and destroyed locks and peer-table before I finish the allocation */ ptable->pt_number++; - lnet_net_unlock(cpt); + lnet_net_unlock(LNET_LOCK_EX); - if (lp) - memset(lp, 0, sizeof(*lp)); - else - lp = kzalloc_cpt(sizeof(*lp), GFP_NOFS, cpt2); - - if (!lp) { + lpni = kzalloc_cpt(sizeof(*lpni), GFP_KERNEL, cpt2); + if (!lpni) { rc = -ENOMEM; lnet_net_lock(cpt); goto out; } - INIT_LIST_HEAD(&lp->lpni_txq); - INIT_LIST_HEAD(&lp->lpni_rtrq); - INIT_LIST_HEAD(&lp->lpni_routes); - - lp->lpni_notify = 0; - lp->lpni_notifylnd = 0; - lp->lpni_notifying = 0; - lp->lpni_alive_count = 0; - lp->lpni_timestamp = 0; - lp->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ - lp->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ - lp->lpni_last_query = 0; /* haven't asked NI yet */ - lp->lpni_ping_timestamp = 0; - lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; - lp->lpni_nid = nid; - lp->lpni_cpt = cpt2; - atomic_set(&lp->lpni_refcount, 2); /* 1 for caller; 1 for hash */ - lp->lpni_rtr_refcount = 0; + INIT_LIST_HEAD(&lpni->lpni_txq); + INIT_LIST_HEAD(&lpni->lpni_rtrq); + INIT_LIST_HEAD(&lpni->lpni_routes); - lnet_net_lock(cpt); + lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ + lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ + lpni->lpni_ping_feats = LNET_PING_FEAT_INVAL; + lpni->lpni_nid = nid; + lpni->lpni_cpt = cpt2; + atomic_set(&lpni->lpni_refcount, 2); /* 1 for caller; 1 for hash */ + + rc = lnet_build_peer_hierarchy(lpni); + if (rc != 0) + goto out; + + lnet_net_lock(LNET_LOCK_EX); if (the_lnet.ln_shutdown) { rc = -ESHUTDOWN; goto out; } - lp2 = lnet_find_peer_locked(ptable, nid); - if (lp2) { - *lpp = lp2; + lpni2 = lnet_get_peer_ni_locked(ptable, nid); + if (lpni2) { + *lpnip = lpni2; goto out; } - lp->lpni_net = lnet_get_net_locked(LNET_NIDNET(lp->lpni_nid)); - lp->lpni_txcredits = - lp->lpni_mintxcredits = - lp->lpni_net->net_tunables.lct_peer_tx_credits; - lp->lpni_rtrcredits = - lp->lpni_minrtrcredits = lnet_peer_buffer_credits(lp->lpni_net); + lpni->lpni_net = lnet_get_net_locked(LNET_NIDNET(lpni->lpni_nid)); + lpni->lpni_txcredits = + lpni->lpni_mintxcredits = + lpni->lpni_net->net_tunables.lct_peer_tx_credits; + lpni->lpni_rtrcredits = + lpni->lpni_minrtrcredits = + lnet_peer_buffer_credits(lpni->lpni_net); - list_add_tail(&lp->lpni_hashlist, + list_add_tail(&lpni->lpni_hashlist, &ptable->pt_hash[lnet_nid2peerhash(nid)]); ptable->pt_version++; - *lpp = lp; + *lpnip = lpni; + + if (cpt != LNET_LOCK_EX) { + lnet_net_unlock(LNET_LOCK_EX); + lnet_net_lock(cpt); + } return 0; out: - if (lp) - list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); + if (lpni) { + lnet_try_destroy_peer_hierarchy_locked(lpni); + kfree(lpni); + } ptable->pt_number--; + if (cpt != LNET_LOCK_EX) { + lnet_net_unlock(LNET_LOCK_EX); + lnet_net_lock(cpt); + } return rc; } diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 12a4b1708d3c..977a937f261c 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -385,6 +385,9 @@ static int proc_lnet_routers(struct ctl_table *table, int write, return rc; } +/* TODO: there should be no direct access to ptable. We should add a set + * of APIs that give access to the ptable and its members + */ static int proc_lnet_peers(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 09/34] LU-7734 lnet: Multi-Rail local_ni/peer_ni selection In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763518.32103.4120463532750655807.stgit@noble> From: Amir Shehata This patch implements the local_ni/peer_ni selection algorithm. It adds APIs to the peer module to encapsulate iterating through the peer_nis in a peer and creating a peer. Signed-off-by: Amir Shehata Change-Id: Ifc0e5ebf84ab25753adfcfcb433b024100f35ace Reviewed-on: http://review.whamcloud.com/18383 Reviewed-by: Doug Oucharek Reviewed-by: Olaf Weber Tested-by: Jenkins Tested-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 53 ++ .../staging/lustre/include/linux/lnet/lib-types.h | 17 + drivers/staging/lustre/lnet/lnet/api-ni.c | 20 + drivers/staging/lustre/lnet/lnet/lib-move.c | 522 +++++++++++++++----- drivers/staging/lustre/lnet/lnet/peer.c | 120 ++++- 5 files changed, 603 insertions(+), 129 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index bf076298de71..6ffe5c1c9925 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -403,6 +403,7 @@ struct lnet_ni *lnet_nid2ni_addref(lnet_nid_t nid); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); struct lnet_ni *lnet_net2ni(__u32 net); bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); +struct lnet_net *lnet_get_net_locked(u32 net_id); extern int portal_rotor; @@ -635,13 +636,24 @@ int lnet_parse_networks(struct list_head *nilist, char *networks, bool lnet_net_unique(__u32 net_id, struct list_head *nilist, struct lnet_net **net); bool lnet_ni_unique_net(struct list_head *nilist, char *iface); - +void lnet_incr_dlc_seq(void); +u32 lnet_get_dlc_seq_locked(void); + +struct lnet_peer_ni *lnet_get_next_peer_ni_locked(struct lnet_peer *peer, + struct lnet_peer_net *peer_net, + struct lnet_peer_ni *prev); +int lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, + struct lnet_peer **peer); int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt); void lnet_peer_tables_cleanup(struct lnet_ni *ni); void lnet_peer_tables_destroy(void); int lnet_peer_tables_create(void); void lnet_debug_peer(lnet_nid_t nid); +struct lnet_peer_net *lnet_peer_get_net_locked(struct lnet_peer *peer, + u32 net_id); +bool lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, + struct lnet_ni *ni); int lnet_get_peer_info(__u32 peer_index, __u64 *nid, char alivness[LNET_MAX_STR_LEN], __u32 *cpt_iter, __u32 *refcount, @@ -649,6 +661,45 @@ int lnet_get_peer_info(__u32 peer_index, __u64 *nid, __u32 *peer_rtr_credits, __u32 *peer_min_rtr_credtis, __u32 *peer_tx_qnob); +static inline bool +lnet_is_peer_ni_healthy_locked(struct lnet_peer_ni *lpni) +{ + return lpni->lpni_healthy; +} + +static inline void +lnet_set_peer_ni_health_locked(struct lnet_peer_ni *lpni, bool health) +{ + lpni->lpni_healthy = health; +} + +static inline bool +lnet_is_peer_net_healthy_locked(struct lnet_peer_net *peer_net) +{ + struct lnet_peer_ni *lpni; + + list_for_each_entry(lpni, &peer_net->lpn_peer_nis, + lpni_on_peer_net_list) { + if (lnet_is_peer_ni_healthy_locked(lpni)) + return true; + } + + return false; +} + +static inline bool +lnet_is_peer_healthy_locked(struct lnet_peer *peer) +{ + struct lnet_peer_net *peer_net; + + list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_on_peer_list) { + if (lnet_is_peer_net_healthy_locked(peer_net)) + return true; + } + + return false; +} + static inline void lnet_peer_set_alive(struct lnet_peer_ni *lp) { diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 9f70c094cc4c..d935d273716d 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -346,6 +346,9 @@ struct lnet_ni { /* lnd tunables set explicitly */ bool ni_lnd_tunables_set; + /* sequence number used to round robin over nis within a net */ + u32 ni_seq; + /* * equivalent interfaces to use * This is an array because socklnd bonding can still be configured @@ -436,10 +439,18 @@ struct lnet_peer_ni { int lpni_cpt; /* # refs from lnet_route::lr_gateway */ int lpni_rtr_refcount; + /* sequence number used to round robin over peer nis within a net */ + u32 lpni_seq; + /* health flag */ + bool lpni_healthy; /* returned RC ping features */ unsigned int lpni_ping_feats; /* routers on this peer */ struct list_head lpni_routes; + /* array of preferred local nids */ + lnet_nid_t *lpni_pref_nids; + /* number of preferred NIDs in lnpi_pref_nids */ + u32 lpni_pref_nnids; /* router checker state */ struct lnet_rc_data *lpni_rcd; }; @@ -453,6 +464,9 @@ struct lnet_peer { /* primary NID of the peer */ lnet_nid_t lp_primary_nid; + + /* peer is Multi-Rail enabled peer */ + bool lp_multi_rail; }; struct lnet_peer_net { @@ -467,6 +481,9 @@ struct lnet_peer_net { /* Net ID */ __u32 lpn_net_id; + + /* health flag */ + bool lpn_healthy; }; /* peer hash size */ diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 821b030f9621..e8e0bc45d8aa 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -64,6 +64,15 @@ module_param(use_tcp_bonding, int, 0444); MODULE_PARM_DESC(use_tcp_bonding, "Set to 1 to use socklnd bonding. 0 to use Multi-Rail"); +/* + * This sequence number keeps track of how many times DLC was used to + * update the configuration. It is incremented on any DLC update and + * checked when sending a message to determine if there is a need to + * re-run the selection algorithm to handle configuration change. + * Look at lnet_select_pathway() for more details on its usage. + */ +static atomic_t lnet_dlc_seq_no = ATOMIC_INIT(0); + static int lnet_ping(struct lnet_process_id id, signed long timeout, struct lnet_process_id __user *ids, int n_ids); @@ -1490,6 +1499,7 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun) lnet_net_lock(LNET_LOCK_EX); list_splice_tail(&local_ni_list, &net_l->net_ni_list); + lnet_incr_dlc_seq(); lnet_net_unlock(LNET_LOCK_EX); /* if the network is not unique then we don't want to keep @@ -2165,6 +2175,16 @@ lnet_dyn_del_ni(__u32 net_id) return rc; } +void lnet_incr_dlc_seq(void) +{ + atomic_inc(&lnet_dlc_seq_no); +} + +u32 lnet_get_dlc_seq_locked(void) +{ + return atomic_read(&lnet_dlc_seq_no); +} + /** * LNet ioctl handler. * diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index edbec7e9ed7e..54e3093355c2 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -444,7 +444,6 @@ lnet_prep_send(struct lnet_msg *msg, int type, struct lnet_process_id target, memset(&msg->msg_hdr, 0, sizeof(msg->msg_hdr)); msg->msg_hdr.type = cpu_to_le32(type); - msg->msg_hdr.dest_nid = cpu_to_le64(target.nid); msg->msg_hdr.dest_pid = cpu_to_le32(target.pid); /* src_nid will be set later */ msg->msg_hdr.src_pid = cpu_to_le32(the_lnet.ln_pid); @@ -836,6 +835,15 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) } if (txpeer) { + /* + * TODO: + * Once the patch for the health comes in we need to set + * the health of the peer ni to bad when we fail to send + * a message. + * int status = msg->msg_ev.status; + * if (status != 0) + * lnet_set_peer_ni_health_locked(txpeer, false) + */ msg->msg_txpeer = NULL; lnet_peer_ni_decref_locked(txpeer); } @@ -968,6 +976,24 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) } } +static int +lnet_compare_peers(struct lnet_peer_ni *p1, struct lnet_peer_ni *p2) +{ + if (p1->lpni_txqnob < p2->lpni_txqnob) + return 1; + + if (p1->lpni_txqnob > p2->lpni_txqnob) + return -1; + + if (p1->lpni_txcredits > p2->lpni_txcredits) + return 1; + + if (p1->lpni_txcredits < p2->lpni_txcredits) + return -1; + + return 0; +} + static int lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) { @@ -975,35 +1001,28 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) struct lnet_peer_ni *p2 = r2->lr_gateway; int r1_hops = (r1->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r1->lr_hops; int r2_hops = (r2->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r2->lr_hops; + int rc; if (r1->lr_priority < r2->lr_priority) return 1; if (r1->lr_priority > r2->lr_priority) - return -ERANGE; + return -1; if (r1_hops < r2_hops) return 1; if (r1_hops > r2_hops) - return -ERANGE; - - if (p1->lpni_txqnob < p2->lpni_txqnob) - return 1; - - if (p1->lpni_txqnob > p2->lpni_txqnob) - return -ERANGE; - - if (p1->lpni_txcredits > p2->lpni_txcredits) - return 1; + return -1; - if (p1->lpni_txcredits < p2->lpni_txcredits) - return -ERANGE; + rc = lnet_compare_peers(p1, p2); + if (rc) + return rc; if (r1->lr_seq - r2->lr_seq <= 0) return 1; - return -ERANGE; + return -1; } static struct lnet_peer_ni * @@ -1070,171 +1089,430 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, return lpni_best; } -int -lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) +static int +lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, + struct lnet_msg *msg, lnet_nid_t rtr_nid, bool *lo_sent) { - lnet_nid_t dst_nid = msg->msg_target.nid; - struct lnet_ni *src_ni; - struct lnet_ni *local_ni; - struct lnet_peer_ni *lp; - int cpt; - int cpt2; - int rc; - + struct lnet_ni *best_ni = NULL; + struct lnet_peer_ni *best_lpni = NULL; + struct lnet_peer_ni *net_gw = NULL; + struct lnet_peer_ni *best_gw = NULL; + struct lnet_peer_ni *lpni; + struct lnet_peer *peer = NULL; + struct lnet_peer_net *peer_net; + struct lnet_net *local_net; + struct lnet_ni *ni = NULL; + int cpt, cpt2, rc; + bool routing = false; + bool ni_is_pref = false; + bool preferred = false; + int best_credits = 0; + u32 seq, seq2; + int best_lpni_credits = INT_MIN; + +again: /* - * NB: rtr_nid is set to LNET_NID_ANY for all current use-cases, - * but we might want to use pre-determined router for ACK/REPLY - * in the future + * get an initial CPT to use for locking. The idea here is not to + * serialize the calls to select_pathway, so that as many + * operations can run concurrently as possible. To do that we use + * the CPT where this call is being executed. Later on when we + * determine the CPT to use in lnet_message_commit, we switch the + * lock and check if there was any configuration changes, if none, + * then we proceed, if there is, then we'll need to update the cpt + * and redo the operation. */ - /* NB: ni == interface pre-determined (ACK/REPLY) */ - LASSERT(!msg->msg_txpeer); - LASSERT(!msg->msg_sending); - LASSERT(!msg->msg_target_is_router); - LASSERT(!msg->msg_receiving); + cpt = lnet_net_lock_current(); - msg->msg_sending = 1; - - LASSERT(!msg->msg_tx_committed); - local_ni = lnet_net2ni(LNET_NIDNET(dst_nid)); - cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid, - local_ni); - again: - lnet_net_lock(cpt); + best_gw = NULL; + routing = false; + local_net = NULL; + best_ni = NULL; if (the_lnet.ln_shutdown) { lnet_net_unlock(cpt); return -ESHUTDOWN; } - if (src_nid == LNET_NID_ANY) { - src_ni = NULL; - } else { - src_ni = lnet_nid2ni_locked(src_nid, cpt); - if (!src_ni) { + /* + * initialize the variables which could be reused if we go to + * again + */ + lpni = NULL; + seq = lnet_get_dlc_seq_locked(); + + rc = lnet_find_or_create_peer_locked(dst_nid, cpt, &peer); + if (rc != 0) { + lnet_net_unlock(cpt); + return rc; + } + + /* If peer is not healthy then can not send anything to it */ + if (!lnet_is_peer_healthy_locked(peer)) { + lnet_net_unlock(cpt); + return -EHOSTUNREACH; + } + + /* + * STEP 1: first jab at determineing best_ni + * if src_nid is explicitly specified, then best_ni is already + * pre-determiend for us. Otherwise we need to select the best + * one to use later on + */ + if (src_nid != LNET_NID_ANY) { + best_ni = lnet_nid2ni_locked(src_nid, cpt); + if (!best_ni) { lnet_net_unlock(cpt); LCONSOLE_WARN("Can't send to %s: src %s is not a local nid\n", libcfs_nid2str(dst_nid), libcfs_nid2str(src_nid)); return -EINVAL; } - LASSERT(!msg->msg_routing); - } - - /* Is this for someone on a local network? */ - local_ni = lnet_net2ni_locked(LNET_NIDNET(dst_nid), cpt); - if (local_ni) { - if (!src_ni) { - src_ni = local_ni; - src_nid = src_ni->ni_nid; - } else if (src_ni != local_ni) { + if (best_ni->ni_net->net_id != LNET_NIDNET(dst_nid)) { lnet_net_unlock(cpt); LCONSOLE_WARN("No route to %s via from %s\n", libcfs_nid2str(dst_nid), libcfs_nid2str(src_nid)); return -EINVAL; } + } - LASSERT(src_nid != LNET_NID_ANY); + if (best_ni == the_lnet.ln_loni) { + /* No send credit hassles with LOLND */ + msg->msg_hdr.dest_nid = cpu_to_le64(best_ni->ni_nid); + if (!msg->msg_routing) + msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); + msg->msg_target.nid = best_ni->ni_nid; lnet_msg_commit(msg, cpt); - if (!msg->msg_routing) - msg->msg_hdr.src_nid = cpu_to_le64(src_nid); + lnet_ni_addref_locked(best_ni, cpt); + lnet_net_unlock(cpt); + msg->msg_txni = best_ni; + lnet_ni_send(best_ni, msg); - if (src_ni == the_lnet.ln_loni) { - /* No send credit hassles with LOLND */ - lnet_net_unlock(cpt); - lnet_ni_send(src_ni, msg); - return 0; + *lo_sent = true; + return 0; + } + + if (best_ni) + goto pick_peer; + + /* + * Decide whether we need to route to peer_ni. + * Get the local net that I need to be on to be able to directly + * send to that peer. + * + * a. Find the peer which the dst_nid belongs to. + * b. Iterate through each of the peer_nets/nis to decide + * the best peer/local_ni pair to use + */ + list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_on_peer_list) { + if (!lnet_is_peer_net_healthy_locked(peer_net)) + continue; + + local_net = lnet_get_net_locked(peer_net->lpn_net_id); + if (!local_net) { + /* + * go through each peer_ni on that peer_net and + * determine the best possible gw to go through + */ + list_for_each_entry(lpni, &peer_net->lpn_peer_nis, + lpni_on_peer_net_list) { + net_gw = lnet_find_route_locked(NULL, + lpni->lpni_nid, + rtr_nid); + + /* + * if no route is found for that network then + * move onto the next peer_ni in the peer + */ + if (!net_gw) + continue; + + if (!best_gw) { + best_gw = net_gw; + best_lpni = lpni; + } else { + rc = lnet_compare_peers(net_gw, + best_gw); + if (rc > 0) { + best_gw = net_gw; + best_lpni = lpni; + } + } + } + + if (!best_gw) + continue; + + local_net = lnet_get_net_locked + (LNET_NIDNET(best_gw->lpni_nid)); + routing = true; + } else { + routing = false; + best_gw = NULL; } - rc = lnet_nid2peerni_locked(&lp, dst_nid, cpt); - if (rc) { - lnet_net_unlock(cpt); - LCONSOLE_WARN("Error %d finding peer %s\n", rc, - libcfs_nid2str(dst_nid)); - /* ENOMEM or shutting down */ - return rc; + /* no routable net found go on to a different net */ + if (!local_net) + continue; + + /* + * Second jab at determining best_ni + * if we get here then the peer we're trying to send + * to is on a directly connected network, and we'll + * need to pick the local_ni on that network to send + * from + */ + while ((ni = lnet_get_next_ni_locked(local_net, ni))) { + if (!lnet_is_ni_healthy_locked(ni)) + continue; + /* TODO: compare NUMA distance */ + if (ni->ni_tx_queues[cpt]->tq_credits <= + best_credits) { + /* + * all we want is to read tq_credits + * value as an approximation of how + * busy the NI is. No need to grab a lock + */ + continue; + } else if (best_ni) { + if ((best_ni)->ni_seq - ni->ni_seq <= 0) + continue; + (best_ni)->ni_seq = ni->ni_seq + 1; + } + + best_ni = ni; + best_credits = ni->ni_tx_queues[cpt]->tq_credits; } - LASSERT(lp->lpni_net == src_ni->ni_net); - } else { - /* sending to a remote network */ - lp = lnet_find_route_locked(src_ni ? src_ni->ni_net : NULL, - dst_nid, rtr_nid); - if (!lp) { - lnet_net_unlock(cpt); + } - LCONSOLE_WARN("No route to %s via %s (all routers down)\n", - libcfs_id2str(msg->msg_target), - libcfs_nid2str(src_nid)); - return -EHOSTUNREACH; + if (!best_ni) { + lnet_net_unlock(cpt); + LCONSOLE_WARN("No local ni found to send from to %s\n", + libcfs_nid2str(dst_nid)); + return -EINVAL; + } + + if (routing) + goto send; + +pick_peer: + lpni = NULL; + + if (msg->msg_type == LNET_MSG_REPLY || + msg->msg_type == LNET_MSG_ACK) { + /* + * for replies we want to respond on the same peer_ni we + * received the message on if possible. If not, then pick + * a peer_ni to send to + */ + best_lpni = lnet_find_peer_ni_locked(dst_nid, cpt); + if (best_lpni) { + lnet_peer_ni_decref_locked(best_lpni); + goto send; + } else { + CDEBUG(D_NET, + "unable to send msg_type %d to originating %s\n", + msg->msg_type, + libcfs_nid2str(dst_nid)); } + } + peer_net = lnet_peer_get_net_locked(peer, + best_ni->ni_net->net_id); + /* + * peer_net is not available or the src_nid is explicitly defined + * and the peer_net for that src_nid is unhealthy. find a route to + * the destination nid. + */ + if (!peer_net || + (src_nid != LNET_NID_ANY && + !lnet_is_peer_net_healthy_locked(peer_net))) { + best_gw = lnet_find_route_locked(best_ni->ni_net, + dst_nid, + rtr_nid); /* - * rtr_nid is LNET_NID_ANY or NID of pre-determined router, - * it's possible that rtr_nid isn't LNET_NID_ANY and lp isn't - * pre-determined router, this can happen if router table - * was changed when we release the lock + * if no route is found for that network then + * move onto the next peer_ni in the peer */ - if (rtr_nid != lp->lpni_nid) { - cpt2 = lp->lpni_cpt; - if (cpt2 != cpt) { - lnet_net_unlock(cpt); - - rtr_nid = lp->lpni_nid; - cpt = cpt2; - goto again; - } + if (!best_gw) { + lnet_net_unlock(cpt); + LCONSOLE_WARN("No route to peer from %s\n", + libcfs_nid2str(best_ni->ni_nid)); + return -EHOSTUNREACH; } CDEBUG(D_NET, "Best route to %s via %s for %s %d\n", - libcfs_nid2str(dst_nid), libcfs_nid2str(lp->lpni_nid), - lnet_msgtyp2str(msg->msg_type), msg->msg_len); + libcfs_nid2str(lpni->lpni_nid), + libcfs_nid2str(best_gw->lpni_nid), + lnet_msgtyp2str(msg->msg_type), msg->msg_len); - if (!src_ni) { - src_ni = lnet_get_next_ni_locked(lp->lpni_net, NULL); - LASSERT(src_ni); - src_nid = src_ni->ni_nid; - } else { - LASSERT(src_ni->ni_net == lp->lpni_net); + best_lpni = lnet_find_peer_ni_locked(dst_nid, cpt); + LASSERT(best_lpni); + lnet_peer_ni_decref_locked(best_lpni); + + routing = true; + + goto send; + } else if (!lnet_is_peer_net_healthy_locked(peer_net)) { + /* + * this peer_net is unhealthy but we still have an opportunity + * to find another peer_net that we can use + */ + u32 net_id = peer_net->lpn_net_id; + + lnet_net_unlock(cpt); + if (!best_lpni) + LCONSOLE_WARN("peer net %s unhealthy\n", + libcfs_net2str(net_id)); + goto again; + } + + best_lpni = NULL; + while ((lpni = lnet_get_next_peer_ni_locked(peer, peer_net, lpni))) { + /* + * if this peer ni is not healty just skip it, no point in + * examining it further + */ + if (!lnet_is_peer_ni_healthy_locked(lpni)) + continue; + ni_is_pref = lnet_peer_is_ni_pref_locked(lpni, best_ni); + + if (!preferred && ni_is_pref) { + preferred = true; + } else if (preferred && !ni_is_pref) { + continue; + } else if (lpni->lpni_txcredits <= best_lpni_credits) { + continue; + } else if (best_lpni) { + if (best_lpni->lpni_seq - lpni->lpni_seq <= 0) + continue; + best_lpni->lpni_seq = lpni->lpni_seq + 1; } - lnet_peer_ni_addref_locked(lp); + best_lpni = lpni; + best_lpni_credits = lpni->lpni_txcredits; + } - LASSERT(src_nid != LNET_NID_ANY); - lnet_msg_commit(msg, cpt); + /* if we still can't find a peer ni then we can't reach it */ + if (!best_lpni) { + u32 net_id = peer_net ? peer_net->lpn_net_id : + LNET_NIDNET(dst_nid); + + lnet_net_unlock(cpt); + LCONSOLE_WARN("no peer_ni found on peer net %s\n", + libcfs_net2str(net_id)); + goto again; + } - if (!msg->msg_routing) { - /* I'm the source and now I know which NI to send on */ - msg->msg_hdr.src_nid = cpu_to_le64(src_nid); +send: + /* + * determine the cpt to use and if it has changed then + * lock the new cpt and check if the config has changed. + * If it has changed then repeat the algorithm since the + * ni or peer list could have changed and the algorithm + * would endup picking a different ni/peer_ni pair. + */ + cpt2 = best_lpni->lpni_cpt; + if (cpt != cpt2) { + lnet_net_unlock(cpt); + cpt = cpt2; + lnet_net_lock(cpt); + seq2 = lnet_get_dlc_seq_locked(); + if (seq2 != seq) { + lnet_net_unlock(cpt); + goto again; } + } + + /* + * store the best_lpni in the message right away to avoid having + * to do the same operation under different conditions + */ + msg->msg_txpeer = (routing) ? best_gw : best_lpni; + msg->msg_txni = best_ni; + /* + * grab a reference for the best_ni since now it's in use in this + * send. the reference will need to be dropped when the message is + * finished in lnet_finalize() + */ + lnet_ni_addref_locked(msg->msg_txni, cpt); + lnet_peer_ni_addref_locked(msg->msg_txpeer); + + /* + * set the destination nid in the message here because it's + * possible that we'd be sending to a different nid than the one + * originaly given. + */ + msg->msg_hdr.dest_nid = cpu_to_le64(msg->msg_txpeer->lpni_nid); + /* + * Always set the target.nid to the best peer picked. Either the + * nid will be one of the preconfigured NIDs, or the same NID as + * what was originaly set in the target or it will be the NID of + * a router if this message should be routed + */ + msg->msg_target.nid = msg->msg_txpeer->lpni_nid; + + /* + * lnet_msg_commit assigns the correct cpt to the message, which + * is used to decrement the correct refcount on the ni when it's + * time to return the credits + */ + lnet_msg_commit(msg, cpt); + + /* + * If we are routing the message then we don't need to overwrite + * the src_nid since it would've been set at the origin. Otherwise + * we are the originator so we need to set it. + */ + if (!msg->msg_routing) + msg->msg_hdr.src_nid = cpu_to_le64(msg->msg_txni->ni_nid); + + if (routing) { msg->msg_target_is_router = 1; - msg->msg_target.nid = lp->lpni_nid; msg->msg_target.pid = LNET_PID_LUSTRE; } - /* 'lp' is our best choice of peer */ + rc = lnet_post_send_locked(msg, 0); - LASSERT(!msg->msg_peertxcredit); - LASSERT(!msg->msg_txcredit); + lnet_net_unlock(cpt); + + return rc; +} + +int +lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) +{ + lnet_nid_t dst_nid = msg->msg_target.nid; + int rc; + bool lo_sent = false; + + /* + * NB: rtr_nid is set to LNET_NID_ANY for all current use-cases, + * but we might want to use pre-determined router for ACK/REPLY + * in the future + */ + /* NB: !ni == interface pre-determined (ACK/REPLY) */ LASSERT(!msg->msg_txpeer); + LASSERT(!msg->msg_sending); + LASSERT(!msg->msg_target_is_router); + LASSERT(!msg->msg_receiving); - msg->msg_txpeer = lp; /* msg takes my ref on lp */ - /* set the NI for this message */ - msg->msg_txni = src_ni; - lnet_ni_addref_locked(msg->msg_txni, cpt); + msg->msg_sending = 1; - rc = lnet_post_send_locked(msg, 0); - lnet_net_unlock(cpt); + LASSERT(!msg->msg_tx_committed); - if (rc < 0) + rc = lnet_select_pathway(src_nid, dst_nid, msg, rtr_nid, &lo_sent); + if (rc < 0 || lo_sent) return rc; if (rc == LNET_CREDIT_OK) - lnet_ni_send(src_ni, msg); + lnet_ni_send(msg->msg_txni, msg); - return 0; /* rc == LNET_CREDIT_OK or LNET_CREDIT_WAIT */ + /* rc == LNET_CREDIT_OK or LNET_CREDIT_WAIT */ + return 0; } void diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 97ee1f5cfd2f..edba1b1d87cc 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -230,6 +230,95 @@ lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt) return lpni; } +int +lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, + struct lnet_peer **peer) +{ + struct lnet_peer_ni *lpni; + + lpni = lnet_find_peer_ni_locked(dst_nid, cpt); + if (!lpni) { + int rc; + + rc = lnet_nid2peerni_locked(&lpni, dst_nid, cpt); + if (rc != 0) + return rc; + } + + *peer = lpni->lpni_peer_net->lpn_peer; + lnet_peer_ni_decref_locked(lpni); + + return 0; +} + +struct lnet_peer_ni * +lnet_get_next_peer_ni_locked(struct lnet_peer *peer, + struct lnet_peer_net *peer_net, + struct lnet_peer_ni *prev) +{ + struct lnet_peer_ni *lpni; + struct lnet_peer_net *net = peer_net; + + if (!prev) { + if (!net) + net = list_entry(peer->lp_peer_nets.next, + struct lnet_peer_net, + lpn_on_peer_list); + lpni = list_entry(net->lpn_peer_nis.next, struct lnet_peer_ni, + lpni_on_peer_net_list); + + return lpni; + } + + if (prev->lpni_on_peer_net_list.next == + &prev->lpni_peer_net->lpn_peer_nis) { + /* + * if you reached the end of the peer ni list and the peer + * net is specified then there are no more peer nis in that + * net. + */ + if (net) + return NULL; + + /* + * we reached the end of this net ni list. move to the + * next net + */ + if (prev->lpni_peer_net->lpn_on_peer_list.next == + &peer->lp_peer_nets) + /* no more nets and no more NIs. */ + return NULL; + + /* get the next net */ + net = list_entry(prev->lpni_peer_net->lpn_on_peer_list.next, + struct lnet_peer_net, + lpn_on_peer_list); + /* get the ni on it */ + lpni = list_entry(net->lpn_peer_nis.next, struct lnet_peer_ni, + lpni_on_peer_net_list); + + return lpni; + } + + /* there are more nis left */ + lpni = list_entry(prev->lpni_on_peer_net_list.next, + struct lnet_peer_ni, lpni_on_peer_net_list); + + return lpni; +} + +bool +lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, struct lnet_ni *ni) +{ + int i; + + for (i = 0; i < lpni->lpni_pref_nnids; i++) { + if (lpni->lpni_pref_nids[i] == ni->ni_nid) + return true; + } + return false; +} + static void lnet_try_destroy_peer_hierarchy_locked(struct lnet_peer_ni *lpni) { @@ -302,6 +391,18 @@ lnet_build_peer_hierarchy(struct lnet_peer_ni *lpni) return 0; } +struct lnet_peer_net * +lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id) +{ + struct lnet_peer_net *peer_net; + + list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_on_peer_list) { + if (peer_net->lpn_net_id == net_id) + return peer_net; + } + return NULL; +} + void lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lpni) { @@ -412,12 +513,19 @@ lnet_nid2peerni_locked(struct lnet_peer_ni **lpnip, lnet_nid_t nid, int cpt) } lpni->lpni_net = lnet_get_net_locked(LNET_NIDNET(lpni->lpni_nid)); - lpni->lpni_txcredits = - lpni->lpni_mintxcredits = - lpni->lpni_net->net_tunables.lct_peer_tx_credits; - lpni->lpni_rtrcredits = - lpni->lpni_minrtrcredits = - lnet_peer_buffer_credits(lpni->lpni_net); + if (lpni->lpni_net) { + lpni->lpni_txcredits = + lpni->lpni_mintxcredits = + lpni->lpni_net->net_tunables.lct_peer_tx_credits; + lpni->lpni_rtrcredits = + lpni->lpni_minrtrcredits = + lnet_peer_buffer_credits(lpni->lpni_net); + } else { + CDEBUG(D_NET, "peer_ni %s is not directly connected\n", + libcfs_nid2str(nid)); + } + + lnet_set_peer_ni_health_locked(lpni, true); list_add_tail(&lpni->lpni_hashlist, &ptable->pt_hash[lnet_nid2peerhash(nid)]); From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 10/34] LU-7734 lnet: configure peers from DLC In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763522.32103.731439682287514589.stgit@noble> From: Amir Shehata This patch adds the ability to configure peers from the DLC interface. When a peer is added a primary NID should be provided. If none is provided then the first NID in the list of NIDs will be used as the primary NID. Basic error checking is done at the DLC level to ensure properly formatted NIDs. However, if a NID is a duplicate, this will be detected when adding it in the kernel. Operation is halted, which means some peer NIDs might have already been added, but not the entire set. It's the role of the caller to backtrack and remove that peer that failed to add. When deleting a peer a primary NID or a normal NID can be provided. If a standard NID is provided, then the peer is found, and the primary NID is compared to the peer ni. If they are the same the entire peer is deleted. Otherwise, only the identified peer ni is deleted. If a set of NIDs are provided each one will be removed from the peer identified by the peer NID in turn. The existing show peer credits API can be used to show peer information. Signed-off-by: Amir Shehata Change-Id: Iaf588a062b44d74305aa9aa7d31c7341c6c384b9 Reviewed-on: http://review.whamcloud.com/18476 Reviewed-by: Doug Oucharek Tested-by: Maloo Reviewed-by: Olaf Weber Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 20 + .../staging/lustre/include/linux/lnet/lib-types.h | 4 .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 5 .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 32 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 39 ++ drivers/staging/lustre/lnet/lnet/lib-move.c | 4 drivers/staging/lustre/lnet/lnet/peer.c | 387 ++++++++++++++++++-- drivers/staging/lustre/lnet/lnet/router.c | 2 8 files changed, 433 insertions(+), 60 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 6ffe5c1c9925..11642f8aee90 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -645,21 +645,25 @@ struct lnet_peer_ni *lnet_get_next_peer_ni_locked(struct lnet_peer *peer, int lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, struct lnet_peer **peer); int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); -struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt); +struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid); void lnet_peer_tables_cleanup(struct lnet_ni *ni); -void lnet_peer_tables_destroy(void); +void lnet_peer_uninit(void); int lnet_peer_tables_create(void); void lnet_debug_peer(lnet_nid_t nid); struct lnet_peer_net *lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id); bool lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, struct lnet_ni *ni); -int lnet_get_peer_info(__u32 peer_index, __u64 *nid, - char alivness[LNET_MAX_STR_LEN], - __u32 *cpt_iter, __u32 *refcount, - __u32 *ni_peer_tx_credits, __u32 *peer_tx_credits, - __u32 *peer_rtr_credits, __u32 *peer_min_rtr_credtis, - __u32 *peer_tx_qnob); +int lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid); +int lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid); +int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, + struct lnet_peer_ni_credit_info *peer_ni_info); +int lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, + char alivness[LNET_MAX_STR_LEN], + __u32 *cpt_iter, __u32 *refcount, + __u32 *ni_peer_tx_credits, __u32 *peer_tx_credits, + __u32 *peer_rtr_credits, __u32 *peer_min_rtr_credtis, + __u32 *peer_tx_qnob); static inline bool lnet_is_peer_ni_healthy_locked(struct lnet_peer_ni *lpni) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index d935d273716d..22b141cb6cff 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -388,6 +388,8 @@ struct lnet_rc_data { struct lnet_peer_ni { struct list_head lpni_on_peer_net_list; + /* chain on remote peer list */ + struct list_head lpni_on_remote_peer_ni_list; /* chain on peer hash */ struct list_head lpni_hashlist; /* messages blocking for tx credits */ @@ -732,6 +734,8 @@ struct lnet { struct lnet_peer_table **ln_peer_tables; /* list of configured or discovered peers */ struct list_head ln_peers; + /* list of peer nis not on a local network */ + struct list_head ln_remote_peer_ni_list; /* failure simulation */ struct list_head ln_test_peers; struct list_head ln_drop_rules; diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h index cce6b58e3682..d5a3e7c85aa4 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h @@ -136,6 +136,9 @@ struct libcfs_debug_ioctl_data { #define IOC_LIBCFS_GET_BUF _IOWR(IOC_LIBCFS_TYPE, 89, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_GET_PEER_INFO _IOWR(IOC_LIBCFS_TYPE, 90, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_GET_LNET_STATS _IOWR(IOC_LIBCFS_TYPE, 91, IOCTL_CONFIG_SIZE) -#define IOC_LIBCFS_MAX_NR 91 +#define IOC_LIBCFS_ADD_PEER_NI _IOWR(IOC_LIBCFS_TYPE, 92, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_DEL_PEER_NI _IOWR(IOC_LIBCFS_TYPE, 93, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_GET_PEER_NI _IOWR(IOC_LIBCFS_TYPE, 94, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_MAX_NR 94 #endif /* __LIBCFS_IOCTL_H__ */ diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index ac29f9d24d5d..9c4e05e1b683 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -126,26 +126,36 @@ struct lnet_ioctl_config_data { char cfg_bulk[0]; }; +struct lnet_peer_ni_credit_info { + char cr_aliveness[LNET_MAX_STR_LEN]; + __u32 cr_refcount; + __s32 cr_ni_peer_tx_credits; + __s32 cr_peer_tx_credits; + __s32 cr_peer_rtr_credits; + __s32 cr_peer_min_rtr_credits; + __u32 cr_peer_tx_qnob; + __u32 cr_ncpt; +}; + struct lnet_ioctl_peer { struct libcfs_ioctl_hdr pr_hdr; __u32 pr_count; __u32 pr_pad; - __u64 pr_nid; + lnet_nid_t pr_nid; union { - struct { - char cr_aliveness[LNET_MAX_STR_LEN]; - __u32 cr_refcount; - __u32 cr_ni_peer_tx_credits; - __u32 cr_peer_tx_credits; - __u32 cr_peer_rtr_credits; - __u32 cr_peer_min_rtr_credits; - __u32 cr_peer_tx_qnob; - __u32 cr_ncpt; - } pr_peer_credits; + struct lnet_peer_ni_credit_info pr_peer_credits; } pr_lnd_u; }; +struct lnet_ioctl_peer_cfg { + struct libcfs_ioctl_hdr prcfg_hdr; + lnet_nid_t prcfg_key_nid; + lnet_nid_t prcfg_cfg_nid; + __u32 prcfg_idx; + char prcfg_bulk[0]; +}; + struct lnet_ioctl_lnet_stats { struct libcfs_ioctl_hdr st_hdr; struct lnet_counters st_cntrs; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index e8e0bc45d8aa..710f8a0be934 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -552,6 +552,7 @@ lnet_prepare(lnet_pid_t requested_pid) INIT_LIST_HEAD(&the_lnet.ln_test_peers); INIT_LIST_HEAD(&the_lnet.ln_peers); + INIT_LIST_HEAD(&the_lnet.ln_remote_peer_ni_list); INIT_LIST_HEAD(&the_lnet.ln_nets); INIT_LIST_HEAD(&the_lnet.ln_routers); INIT_LIST_HEAD(&the_lnet.ln_drop_rules); @@ -646,7 +647,7 @@ lnet_unprepare(void) lnet_res_container_cleanup(&the_lnet.ln_eq_container); lnet_msg_containers_destroy(); - lnet_peer_tables_destroy(); + lnet_peer_uninit(); lnet_rtrpools_free(0); if (the_lnet.ln_counters) { @@ -2318,13 +2319,33 @@ LNetCtl(unsigned int cmd, void *arg) return lnet_get_rtr_pool_cfg(config->cfg_count, pool_cfg); } + case IOC_LIBCFS_ADD_PEER_NI: { + struct lnet_ioctl_peer_cfg *cfg = arg; + + if (cfg->prcfg_hdr.ioc_len < sizeof(*cfg)) + return -EINVAL; + + return lnet_add_peer_ni_to_peer(cfg->prcfg_key_nid, + cfg->prcfg_cfg_nid); + } + + case IOC_LIBCFS_DEL_PEER_NI: { + struct lnet_ioctl_peer_cfg *cfg = arg; + + if (cfg->prcfg_hdr.ioc_len < sizeof(*cfg)) + return -EINVAL; + + return lnet_del_peer_ni_from_peer(cfg->prcfg_key_nid, + cfg->prcfg_cfg_nid); + } + case IOC_LIBCFS_GET_PEER_INFO: { struct lnet_ioctl_peer *peer_info = arg; if (peer_info->pr_hdr.ioc_len < sizeof(*peer_info)) return -EINVAL; - return lnet_get_peer_info(peer_info->pr_count, + return lnet_get_peer_ni_info(peer_info->pr_count, &peer_info->pr_nid, peer_info->pr_lnd_u.pr_peer_credits.cr_aliveness, &peer_info->pr_lnd_u.pr_peer_credits.cr_ncpt, @@ -2336,6 +2357,20 @@ LNetCtl(unsigned int cmd, void *arg) &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_qnob); } + case IOC_LIBCFS_GET_PEER_NI: { + struct lnet_ioctl_peer_cfg *cfg = arg; + struct lnet_peer_ni_credit_info *lpni_cri; + size_t total = sizeof(*cfg) + sizeof(*lpni_cri); + + if (cfg->prcfg_hdr.ioc_len < total) + return -EINVAL; + + lpni_cri = (struct lnet_peer_ni_credit_info *)cfg->prcfg_bulk; + + return lnet_get_peer_info(cfg->prcfg_idx, &cfg->prcfg_key_nid, + &cfg->prcfg_cfg_nid, lpni_cri); + } + case IOC_LIBCFS_NOTIFY_ROUTER: { time64_t deadline = ktime_get_real_seconds() - data->ioc_u64[0]; diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 54e3093355c2..fbf209610ff9 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1307,7 +1307,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * received the message on if possible. If not, then pick * a peer_ni to send to */ - best_lpni = lnet_find_peer_ni_locked(dst_nid, cpt); + best_lpni = lnet_find_peer_ni_locked(dst_nid); if (best_lpni) { lnet_peer_ni_decref_locked(best_lpni); goto send; @@ -1348,7 +1348,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, libcfs_nid2str(best_gw->lpni_nid), lnet_msgtyp2str(msg->msg_type), msg->msg_len); - best_lpni = lnet_find_peer_ni_locked(dst_nid, cpt); + best_lpni = lnet_find_peer_ni_locked(dst_nid); LASSERT(best_lpni); lnet_peer_ni_decref_locked(best_lpni); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index edba1b1d87cc..d081440579e0 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -38,6 +38,65 @@ #include #include +static void +lnet_peer_remove_from_remote_list(struct lnet_peer_ni *lpni) +{ + if (!list_empty(&lpni->lpni_on_remote_peer_ni_list)) { + list_del_init(&lpni->lpni_on_remote_peer_ni_list); + lnet_peer_ni_decref_locked(lpni); + } +} + +void +lnet_peer_tables_destroy(void) +{ + struct lnet_peer_table *ptable; + struct list_head *hash; + int i; + int j; + + if (!the_lnet.ln_peer_tables) + return; + + cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { + hash = ptable->pt_hash; + if (!hash) /* not initialized */ + break; + + ptable->pt_hash = NULL; + for (j = 0; j < LNET_PEER_HASH_SIZE; j++) + LASSERT(list_empty(&hash[j])); + + kvfree(hash); + } + + cfs_percpt_free(the_lnet.ln_peer_tables); + the_lnet.ln_peer_tables = NULL; +} + +void lnet_peer_uninit(void) +{ + int cpt; + struct lnet_peer_ni *lpni, *tmp; + struct lnet_peer_table *ptable = NULL; + + /* remove all peer_nis from the remote peer and he hash list */ + list_for_each_entry_safe(lpni, tmp, &the_lnet.ln_remote_peer_ni_list, + lpni_on_remote_peer_ni_list) { + list_del_init(&lpni->lpni_on_remote_peer_ni_list); + lnet_peer_ni_decref_locked(lpni); + + cpt = lnet_cpt_of_nid_locked(lpni->lpni_nid, NULL); + ptable = the_lnet.ln_peer_tables[cpt]; + ptable->pt_zombies++; + + list_del_init(&lpni->lpni_hashlist); + lnet_peer_ni_decref_locked(lpni); + } + + lnet_peer_tables_destroy(); +} + int lnet_peer_tables_create(void) { @@ -70,33 +129,6 @@ lnet_peer_tables_create(void) return 0; } -void -lnet_peer_tables_destroy(void) -{ - struct lnet_peer_table *ptable; - struct list_head *hash; - int i; - int j; - - if (!the_lnet.ln_peer_tables) - return; - - cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { - hash = ptable->pt_hash; - if (!hash) /* not initialized */ - break; - - ptable->pt_hash = NULL; - for (j = 0; j < LNET_PEER_HASH_SIZE; j++) - LASSERT(list_empty(&hash[j])); - - kvfree(hash); - } - - cfs_percpt_free(the_lnet.ln_peer_tables); - the_lnet.ln_peer_tables = NULL; -} - static void lnet_peer_table_cleanup_locked(struct lnet_ni *ni, struct lnet_peer_table *ptable) @@ -219,10 +251,13 @@ lnet_get_peer_ni_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) } struct lnet_peer_ni * -lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt) +lnet_find_peer_ni_locked(lnet_nid_t nid) { struct lnet_peer_ni *lpni; struct lnet_peer_table *ptable; + int cpt; + + cpt = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); ptable = the_lnet.ln_peer_tables[cpt]; lpni = lnet_get_peer_ni_locked(ptable, nid); @@ -236,7 +271,7 @@ lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, { struct lnet_peer_ni *lpni; - lpni = lnet_find_peer_ni_locked(dst_nid, cpt); + lpni = lnet_find_peer_ni_locked(dst_nid); if (!lpni) { int rc; @@ -251,6 +286,25 @@ lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, return 0; } +struct lnet_peer_ni * +lnet_get_peer_ni_idx_locked(int idx, struct lnet_peer_net **lpn, + struct lnet_peer **lp) +{ + struct lnet_peer_ni *lpni; + + list_for_each_entry((*lp), &the_lnet.ln_peers, lp_on_lnet_peer_list) { + list_for_each_entry((*lpn), &((*lp)->lp_peer_nets), + lpn_on_peer_list) { + list_for_each_entry(lpni, &((*lpn)->lpn_peer_nis), + lpni_on_peer_net_list) + if (idx-- == 0) + return lpni; + } + } + + return NULL; +} + struct lnet_peer_ni * lnet_get_next_peer_ni_locked(struct lnet_peer *peer, struct lnet_peer_net *peer_net, @@ -403,6 +457,223 @@ lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id) return NULL; } +/* + * given the key nid find the peer to add the new peer NID to. If the key + * nid is NULL, then create a new peer, but first make sure that the NID + * is unique + */ +int +lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid) +{ + struct lnet_peer_ni *lpni, *lpni2; + struct lnet_peer *peer; + struct lnet_peer_net *peer_net, *pn; + int cpt, cpt2, rc; + struct lnet_peer_table *ptable = NULL; + __u32 net_id = LNET_NIDNET(nid); + + if (nid == LNET_NID_ANY) + return -EINVAL; + + /* check that nid is unique */ + cpt = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); + lnet_net_lock(cpt); + lpni = lnet_find_peer_ni_locked(nid); + if (lpni) { + lnet_peer_ni_decref_locked(lpni); + lnet_net_unlock(cpt); + return -EEXIST; + } + lnet_net_unlock(cpt); + + if (key_nid != LNET_NID_ANY) { + cpt2 = lnet_nid_cpt_hash(key_nid, LNET_CPT_NUMBER); + lnet_net_lock(cpt2); + lpni = lnet_find_peer_ni_locked(key_nid); + if (!lpni) { + lnet_net_unlock(cpt2); + /* key_nid refers to a non-existent peer_ni.*/ + return -EINVAL; + } + peer = lpni->lpni_peer_net->lpn_peer; + peer->lp_multi_rail = true; + lnet_peer_ni_decref_locked(lpni); + lnet_net_unlock(cpt2); + } else { + lnet_net_lock(LNET_LOCK_EX); + rc = lnet_nid2peerni_locked(&lpni, nid, LNET_LOCK_EX); + if (rc == 0) { + lpni->lpni_peer_net->lpn_peer->lp_multi_rail = true; + lnet_peer_ni_decref_locked(lpni); + } + lnet_net_unlock(LNET_LOCK_EX); + return rc; + } + + lpni = kzalloc_cpt(sizeof(*lpni), GFP_KERNEL, cpt); + if (!lpni) + return -ENOMEM; + + INIT_LIST_HEAD(&lpni->lpni_txq); + INIT_LIST_HEAD(&lpni->lpni_rtrq); + INIT_LIST_HEAD(&lpni->lpni_routes); + INIT_LIST_HEAD(&lpni->lpni_hashlist); + INIT_LIST_HEAD(&lpni->lpni_on_peer_net_list); + INIT_LIST_HEAD(&lpni->lpni_on_remote_peer_ni_list); + + lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ + lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ + lpni->lpni_ping_feats = LNET_PING_FEAT_INVAL; + lpni->lpni_nid = nid; + lpni->lpni_cpt = cpt; + lnet_set_peer_ni_health_locked(lpni, true); + + /* allocate here in case we need to add a new peer_net */ + peer_net = NULL; + peer_net = kzalloc(sizeof(*peer_net), GFP_KERNEL); + if (!peer_net) { + rc = -ENOMEM; + kfree(lpni); + return rc; + } + + lnet_net_lock(LNET_LOCK_EX); + + ptable = the_lnet.ln_peer_tables[cpt]; + ptable->pt_number++; + + lpni2 = lnet_find_peer_ni_locked(nid); + if (lpni2) { + lnet_peer_ni_decref_locked(lpni2); + /* sanity check that lpni2's peer is what we expect */ + if (lpni2->lpni_peer_net->lpn_peer != peer) + rc = -EEXIST; + else + rc = -EINVAL; + + ptable->pt_number--; + /* another thread has already added it */ + lnet_net_unlock(LNET_LOCK_EX); + kfree(peer_net); + return rc; + } + + lpni->lpni_net = lnet_get_net_locked(LNET_NIDNET(lpni->lpni_nid)); + if (lpni->lpni_net) { + lpni->lpni_txcredits = + lpni->lpni_mintxcredits = + lpni->lpni_net->net_tunables.lct_peer_tx_credits; + lpni->lpni_rtrcredits = + lpni->lpni_minrtrcredits = + lnet_peer_buffer_credits(lpni->lpni_net); + } else { + /* + * if you're adding a peer which is not on a local network + * then we can't assign any of the credits. It won't be + * picked for sending anyway. Eventually a network can be + * added, in this case we need to revisit this peer and + * update its credits. + */ + + /* increment refcount for remote peer list */ + atomic_inc(&lpni->lpni_refcount); + list_add_tail(&lpni->lpni_on_remote_peer_ni_list, + &the_lnet.ln_remote_peer_ni_list); + } + + /* increment refcount for peer on hash list */ + atomic_inc(&lpni->lpni_refcount); + + list_add_tail(&lpni->lpni_hashlist, + &ptable->pt_hash[lnet_nid2peerhash(nid)]); + ptable->pt_version++; + + /* add the lpni to a net */ + list_for_each_entry(pn, &peer->lp_peer_nets, lpn_on_peer_list) { + if (pn->lpn_net_id == net_id) { + list_add_tail(&lpni->lpni_on_peer_net_list, + &pn->lpn_peer_nis); + lpni->lpni_peer_net = pn; + lnet_net_unlock(LNET_LOCK_EX); + kfree(peer_net); + return 0; + } + } + + INIT_LIST_HEAD(&peer_net->lpn_on_peer_list); + INIT_LIST_HEAD(&peer_net->lpn_peer_nis); + + /* build the hierarchy */ + peer_net->lpn_net_id = net_id; + peer_net->lpn_peer = peer; + lpni->lpni_peer_net = peer_net; + list_add_tail(&lpni->lpni_on_peer_net_list, &peer_net->lpn_peer_nis); + list_add_tail(&peer_net->lpn_on_peer_list, &peer->lp_peer_nets); + + lnet_net_unlock(LNET_LOCK_EX); + return 0; +} + +int +lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid) +{ + int cpt; + lnet_nid_t local_nid; + struct lnet_peer *peer; + struct lnet_peer_ni *lpni, *lpni2; + struct lnet_peer_table *ptable = NULL; + + if (key_nid == LNET_NID_ANY) + return -EINVAL; + + local_nid = (nid != LNET_NID_ANY) ? nid : key_nid; + cpt = lnet_nid_cpt_hash(local_nid, LNET_CPT_NUMBER); + lnet_net_lock(LNET_LOCK_EX); + + lpni = lnet_find_peer_ni_locked(local_nid); + if (!lpni) { + lnet_net_unlock(cpt); + return -EINVAL; + } + lnet_peer_ni_decref_locked(lpni); + + peer = lpni->lpni_peer_net->lpn_peer; + LASSERT(peer); + + if (peer->lp_primary_nid == lpni->lpni_nid) { + /* + * deleting the primary ni is equivalent to deleting the + * entire peer + */ + lpni = NULL; + lpni = lnet_get_next_peer_ni_locked(peer, NULL, lpni); + while (lpni) { + lpni2 = lnet_get_next_peer_ni_locked(peer, NULL, lpni); + cpt = lnet_nid_cpt_hash(lpni->lpni_nid, + LNET_CPT_NUMBER); + lnet_peer_remove_from_remote_list(lpni); + ptable = the_lnet.ln_peer_tables[cpt]; + ptable->pt_zombies++; + list_del_init(&lpni->lpni_hashlist); + lnet_peer_ni_decref_locked(lpni); + lpni = lpni2; + } + lnet_net_unlock(LNET_LOCK_EX); + + return 0; + } + + lnet_peer_remove_from_remote_list(lpni); + cpt = lnet_nid_cpt_hash(lpni->lpni_nid, LNET_CPT_NUMBER); + ptable = the_lnet.ln_peer_tables[cpt]; + ptable->pt_zombies++; + list_del_init(&lpni->lpni_hashlist); + lnet_peer_ni_decref_locked(lpni); + lnet_net_unlock(LNET_LOCK_EX); + + return 0; +} + void lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lpni) { @@ -487,6 +758,9 @@ lnet_nid2peerni_locked(struct lnet_peer_ni **lpnip, lnet_nid_t nid, int cpt) INIT_LIST_HEAD(&lpni->lpni_txq); INIT_LIST_HEAD(&lpni->lpni_rtrq); INIT_LIST_HEAD(&lpni->lpni_routes); + INIT_LIST_HEAD(&lpni->lpni_hashlist); + INIT_LIST_HEAD(&lpni->lpni_on_peer_net_list); + INIT_LIST_HEAD(&lpni->lpni_on_remote_peer_ni_list); lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ @@ -521,8 +795,20 @@ lnet_nid2peerni_locked(struct lnet_peer_ni **lpnip, lnet_nid_t nid, int cpt) lpni->lpni_minrtrcredits = lnet_peer_buffer_credits(lpni->lpni_net); } else { + /* + * if you're adding a peer which is not on a local network + * then we can't assign any of the credits. It won't be + * picked for sending anyway. Eventually a network can be + * added, in this case we need to revisit this peer and + * update its credits. + */ + CDEBUG(D_NET, "peer_ni %s is not directly connected\n", libcfs_nid2str(nid)); + /* increment refcount for remote peer list */ + atomic_inc(&lpni->lpni_refcount); + list_add_tail(&lpni->lpni_on_remote_peer_ni_list, + &the_lnet.ln_remote_peer_ni_list); } lnet_set_peer_ni_health_locked(lpni, true); @@ -584,12 +870,12 @@ lnet_debug_peer(lnet_nid_t nid) } int -lnet_get_peer_info(__u32 peer_index, __u64 *nid, - char aliveness[LNET_MAX_STR_LEN], - __u32 *cpt_iter, __u32 *refcount, - __u32 *ni_peer_tx_credits, __u32 *peer_tx_credits, - __u32 *peer_rtr_credits, __u32 *peer_min_rtr_credits, - __u32 *peer_tx_qnob) +lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, + char aliveness[LNET_MAX_STR_LEN], + __u32 *cpt_iter, __u32 *refcount, + __u32 *ni_peer_tx_credits, __u32 *peer_tx_credits, + __u32 *peer_rtr_credits, __u32 *peer_min_rtr_credits, + __u32 *peer_tx_qnob) { struct lnet_peer_table *peer_table; struct lnet_peer_ni *lp; @@ -645,3 +931,34 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, return found ? 0 : -ENOENT; } + +int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, + struct lnet_peer_ni_credit_info *peer_ni_info) +{ + struct lnet_peer_ni *lpni = NULL; + struct lnet_peer_net *lpn = NULL; + struct lnet_peer *lp = NULL; + + lpni = lnet_get_peer_ni_idx_locked(idx, &lpn, &lp); + + if (!lpni) + return -ENOENT; + + *primary_nid = lp->lp_primary_nid; + *nid = lpni->lpni_nid; + snprintf(peer_ni_info->cr_aliveness, LNET_MAX_STR_LEN, "NA"); + if (lnet_isrouter(lpni) || + lnet_peer_aliveness_enabled(lpni)) + snprintf(peer_ni_info->cr_aliveness, LNET_MAX_STR_LEN, + lpni->lpni_alive ? "up" : "down"); + + peer_ni_info->cr_refcount = atomic_read(&lpni->lpni_refcount); + peer_ni_info->cr_ni_peer_tx_credits = lpni->lpni_net ? + lpni->lpni_net->net_tunables.lct_peer_tx_credits : 0; + peer_ni_info->cr_peer_tx_credits = lpni->lpni_txcredits; + peer_ni_info->cr_peer_rtr_credits = lpni->lpni_rtrcredits; + peer_ni_info->cr_peer_min_rtr_credits = lpni->lpni_mintxcredits; + peer_ni_info->cr_peer_tx_qnob = lpni->lpni_txqnob; + + return 0; +} diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index de037a77671d..7913914620f3 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -1734,7 +1734,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) return -ESHUTDOWN; } - lp = lnet_find_peer_ni_locked(nid, cpt); + lp = lnet_find_peer_ni_locked(nid); if (!lp) { /* nid not found */ lnet_net_unlock(cpt); From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 11/34] LU-7734 lnet: configure local NI from DLC In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763527.32103.6166409833321456335.stgit@noble> From: Amir Shehata This patch adds the ability to configure multiple network interfaces on the same network. This can be done via the lnetctl CLI interface or through a YAML configuration. Refer to the multi-rail HLD for more details on the syntax. It also deprecates ip2nets kernel parsing. All string parsing and network maching now happens in the DLC userspace library. New IOCTLs are added for adding/deleting local NIs, to keep backwards compatibility with older version of the DLC and lnetctl. The changes also include parsing and matching ip2nets syntax at the user level and then passing down the network interfaces down to the kernel to be configured. Signed-off-by: Amir Shehata Change-Id: I19ee7dc76514beb6f34de6517d19654d6468bcec Reviewed-on: http://review.whamcloud.com/18886 Tested-by: Maloo Signed-off-by: NeilBrown --- .../lustre/include/linux/libcfs/libcfs_string.h | 12 - .../staging/lustre/include/linux/lnet/lib-lnet.h | 13 - .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 6 .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 57 ++ .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 3 drivers/staging/lustre/lnet/lnet/api-ni.c | 479 +++++++++++++++++--- drivers/staging/lustre/lnet/lnet/config.c | 107 +++- drivers/staging/lustre/lnet/lnet/module.c | 70 ++- drivers/staging/lustre/lnet/lnet/peer.c | 21 + drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 2 drivers/staging/lustre/lustre/ptlrpc/service.c | 4 11 files changed, 650 insertions(+), 124 deletions(-) diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h index cd7c3ccb2dc0..3117708b9ebb 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h @@ -83,20 +83,10 @@ int cfs_expr_list_print(char *buffer, int count, struct cfs_expr_list *expr_list); int cfs_expr_list_values(struct cfs_expr_list *expr_list, int max, u32 **values); -static inline void -cfs_expr_list_values_free(u32 *values, int num) -{ - /* - * This array is allocated by kvalloc(), so it shouldn't be freed - * by OBD_FREE() if it's called by module other than libcfs & LNet, - * otherwise we will see fake memory leak - */ - kvfree(values); -} - void cfs_expr_list_free(struct cfs_expr_list *expr_list); int cfs_expr_list_parse(char *str, int len, unsigned int min, unsigned int max, struct cfs_expr_list **elpp); +void cfs_expr_list_free(struct cfs_expr_list *expr_list); void cfs_expr_list_free_list(struct list_head *list); #endif diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 11642f8aee90..a7cff6426ad8 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -377,6 +377,9 @@ lnet_net_alloc(__u32 net_type, struct list_head *netlist); struct lnet_ni * lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface); +struct lnet_ni * +lnet_ni_alloc_w_cpt_array(struct lnet_net *net, __u32 *cpts, __u32 ncpts, + char *iface); static inline int lnet_nid2peerhash(lnet_nid_t nid) @@ -401,7 +404,7 @@ int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); struct lnet_ni *lnet_nid2ni_addref(lnet_nid_t nid); struct lnet_ni *lnet_net2ni_locked(__u32 net, int cpt); -struct lnet_ni *lnet_net2ni(__u32 net); +struct lnet_ni *lnet_net2ni_addref(__u32 net); bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); struct lnet_net *lnet_get_net_locked(u32 net_id); @@ -435,9 +438,10 @@ int lnet_rtrpools_enable(void); void lnet_rtrpools_disable(void); void lnet_rtrpools_free(int keep_pools); struct lnet_remotenet *lnet_find_rnet_locked(__u32 net); -int lnet_dyn_add_ni(lnet_pid_t requested_pid, - struct lnet_ioctl_config_data *conf); -int lnet_dyn_del_ni(__u32 net); +int lnet_dyn_add_net(struct lnet_ioctl_config_data *conf); +int lnet_dyn_del_net(__u32 net); +int lnet_dyn_add_ni(struct lnet_ioctl_config_ni *conf); +int lnet_dyn_del_ni(struct lnet_ioctl_config_ni *conf); int lnet_clear_lazy_portal(struct lnet_ni *ni, int portal, char *reason); struct lnet_net *lnet_get_net_locked(__u32 net_id); @@ -646,6 +650,7 @@ int lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, struct lnet_peer **peer); int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid); +void lnet_peer_net_added(struct lnet_net *net); void lnet_peer_tables_cleanup(struct lnet_ni *ni); void lnet_peer_uninit(void); int lnet_peer_tables_create(void); diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h index d5a3e7c85aa4..fa58aaf6ad9d 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h @@ -139,6 +139,10 @@ struct libcfs_debug_ioctl_data { #define IOC_LIBCFS_ADD_PEER_NI _IOWR(IOC_LIBCFS_TYPE, 92, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_DEL_PEER_NI _IOWR(IOC_LIBCFS_TYPE, 93, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_GET_PEER_NI _IOWR(IOC_LIBCFS_TYPE, 94, IOCTL_CONFIG_SIZE) -#define IOC_LIBCFS_MAX_NR 94 +#define IOC_LIBCFS_ADD_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 95, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_DEL_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 96, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_GET_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 97, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_DBG _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_MAX_NR 98 #endif /* __LIBCFS_IOCTL_H__ */ diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index 9c4e05e1b683..bfd9fc6bc4df 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -37,6 +37,18 @@ #define LNET_MAX_SHOW_NUM_CPT 128 #define LNET_UNDEFINED_HOPS ((__u32)(-1)) +/* + * To allow for future enhancements to extend the tunables + * add a hdr to this structure, so that the version can be set + * and checked for backwards compatibility. Newer versions of LNet + * can still work with older versions of lnetctl. The restriction is + * that the structure can be added to and not removed from in order + * to not invalidate older lnetctl utilities. Moreover, the order of + * fields must remain the same, and new fields appended to the structure + * + * That said all existing LND tunables will be added in this structure + * to avoid future changes. + */ struct lnet_ioctl_config_lnd_cmn_tunables { __u32 lct_version; __s32 lct_peer_timeout; @@ -82,6 +94,10 @@ struct lnet_ioctl_net_config { /* # different router buffer pools */ #define LNET_NRBPOOLS (LNET_LARGE_BUF_IDX + 1) +enum lnet_dbg_task { + LNET_DBG_INCR_DLC_SEQ = 0 +}; + struct lnet_ioctl_pool_cfg { struct { __u32 pl_npages; @@ -126,6 +142,29 @@ struct lnet_ioctl_config_data { char cfg_bulk[0]; }; +/* + * lnet_ioctl_config_ni + * This structure describes an NI configuration. There are multiple components + * when configuring an NI: Net, Interfaces, CPT list and LND tunables + * A network is passed as a string to the DLC and translated using + * libcfs_str2net() + * An interface is the name of the system configured interface + * (ex eth0, ib1) + * CPT is the list of CPTS LND tunables are passed in the lic_bulk area + */ +struct lnet_ioctl_config_ni { + struct libcfs_ioctl_hdr lic_cfg_hdr; + lnet_nid_t lic_nid; + char lic_ni_intf[LNET_MAX_INTERFACES][LNET_MAX_STR_LEN]; + char lic_legacy_ip2nets[LNET_MAX_STR_LEN]; + __u32 lic_cpts[LNET_MAX_SHOW_NUM_CPT]; + __u32 lic_ncpts; + __u32 lic_status; + __u32 lic_tcp_bonding; + __u32 lic_idx; + char lic_bulk[0]; +}; + struct lnet_peer_ni_credit_info { char cr_aliveness[LNET_MAX_STR_LEN]; __u32 cr_refcount; @@ -148,6 +187,24 @@ struct lnet_ioctl_peer { } pr_lnd_u; }; +struct lnet_dbg_task_info { + /* + * TODO: a union can be added if the task requires more + * information from user space to be carried out in kernel space. + */ +}; + +/* + * This structure is intended to allow execution of debugging tasks. This + * is not intended to be backwards compatible. Extra tasks can be added in + * the future + */ +struct lnet_ioctl_dbg { + struct libcfs_ioctl_hdr dbg_hdr; + enum lnet_dbg_task dbg_task; + char dbg_bulk[0]; +}; + struct lnet_ioctl_peer_cfg { struct libcfs_ioctl_hdr prcfg_hdr; lnet_nid_t prcfg_key_nid; diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 766f0d525661..9df66c6d160f 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2700,7 +2700,8 @@ ksocknal_net_start_threads(struct ksock_net *net, __u32 *cpts, int ncpts) int rc; int i; - LASSERT(ncpts > 0 && ncpts <= cfs_cpt_number(lnet_cpt_table())); + if (ncpts > 0 && ncpts > cfs_cpt_number(lnet_cpt_table())) + return -EINVAL; for (i = 0; i < ncpts; i++) { struct ksock_sched_info *info; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 710f8a0be934..1ef9a39b517d 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -679,17 +679,19 @@ lnet_net2ni_locked(__u32 net_id, int cpt) } struct lnet_ni * -lnet_net2ni(__u32 net) +lnet_net2ni_addref(__u32 net) { struct lnet_ni *ni; lnet_net_lock(0); ni = lnet_net2ni_locked(net, 0); + if (ni) + lnet_ni_addref_locked(ni, 0); lnet_net_unlock(0); return ni; } -EXPORT_SYMBOL(lnet_net2ni); +EXPORT_SYMBOL(lnet_net2ni_addref); struct lnet_net * lnet_get_net_locked(__u32 net_id) @@ -897,6 +899,18 @@ lnet_get_net_ni_count_locked(struct lnet_net *net) return count; } +static inline int +lnet_get_net_ni_count_pre(struct lnet_net *net) +{ + struct lnet_ni *ni; + int count = 0; + + list_for_each_entry(ni, &net->net_ni_added, ni_netlist) + count++; + + return count; +} + static inline int lnet_get_ni_count(void) { @@ -1839,15 +1853,91 @@ LNetNIFini(void) } EXPORT_SYMBOL(LNetNIFini); +static int lnet_handle_dbg_task(struct lnet_ioctl_dbg *dbg, + struct lnet_dbg_task_info *dbg_info) +{ + switch (dbg->dbg_task) { + case LNET_DBG_INCR_DLC_SEQ: + lnet_incr_dlc_seq(); + } + + return 0; +} + /** * Grabs the ni data from the ni structure and fills the out * parameters * - * \param[in] ni network interface structure - * \param[out] config NI configuration + * \param[in] ni network interface structure + * \param[out] cfg_ni NI config information + * \param[out] tun network and LND tunables */ static void -lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) +lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_ni *cfg_ni, + struct lnet_ioctl_config_lnd_tunables *tun, + __u32 tun_size) +{ + size_t min_size = 0; + int i; + + if (!ni || !cfg_ni || !tun) + return; + + if (ni->ni_interfaces[0]) { + for (i = 0; i < ARRAY_SIZE(ni->ni_interfaces); i++) { + if (ni->ni_interfaces[i]) { + strncpy(cfg_ni->lic_ni_intf[i], + ni->ni_interfaces[i], + sizeof(cfg_ni->lic_ni_intf[i])); + } + } + } + + cfg_ni->lic_nid = ni->ni_nid; + cfg_ni->lic_status = ni->ni_status->ns_status; + cfg_ni->lic_tcp_bonding = use_tcp_bonding; + + memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn)); + + /* + * tun->lt_tun will always be present, but in order to be + * backwards compatible, we need to deal with the cases when + * tun->lt_tun is smaller than what the kernel has, because it + * comes from an older version of a userspace program, then we'll + * need to copy as much information as we have available space. + */ + min_size = tun_size - sizeof(tun->lt_cmn); + memcpy(&tun->lt_tun, &ni->ni_lnd_tunables, min_size); + + /* copy over the cpts */ + if (ni->ni_ncpts == LNET_CPT_NUMBER && + !ni->ni_cpts) { + for (i = 0; i < ni->ni_ncpts; i++) + cfg_ni->lic_cpts[i] = i; + } else { + for (i = 0; + ni->ni_cpts && i < ni->ni_ncpts && + i < LNET_MAX_SHOW_NUM_CPT; + i++) + cfg_ni->lic_cpts[i] = ni->ni_cpts[i]; + } + cfg_ni->lic_ncpts = ni->ni_ncpts; +} + +/** + * NOTE: This is a legacy function left in the code to be backwards + * compatible with older userspace programs. It should eventually be + * removed. + * + * Grabs the ni data from the ni structure and fills the out + * parameters + * + * \param[in] ni network interface structure + * \param[out] config config information + */ +static void +lnet_fill_ni_info_legacy(struct lnet_ni *ni, + struct lnet_ioctl_config_data *config) { struct lnet_ioctl_config_lnd_tunables *lnd_cfg = NULL; struct lnet_ioctl_net_config *net_config; @@ -1994,7 +2084,7 @@ lnet_get_net_config(struct lnet_ioctl_config_data *config) if (ni) { rc = 0; lnet_ni_lock(ni); - lnet_fill_ni_info(ni, config); + lnet_fill_ni_info_legacy(ni, config); lnet_ni_unlock(ni); } @@ -2003,38 +2093,43 @@ lnet_get_net_config(struct lnet_ioctl_config_data *config) } int -lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) +lnet_get_ni_config(struct lnet_ioctl_config_ni *cfg_ni, + struct lnet_ioctl_config_lnd_tunables *tun, + __u32 tun_size) { - char *nets = conf->cfg_config_u.cfg_net.net_intf; - struct lnet_ping_info *pinfo; - struct lnet_handle_md md_handle; - struct lnet_net *net; - struct list_head net_head; - struct lnet_remotenet *rnet; - int rc; - int net_ni_count; - int num_acceptor_nets; - u32 net_type; - struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; - - INIT_LIST_HEAD(&net_head); + struct lnet_ni *ni; + int cpt; + int rc = -ENOENT; - if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) - lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; + if (!cfg_ni || !tun) + return -EINVAL; - /* Create a net/ni structures for the network string */ - rc = lnet_parse_networks(&net_head, nets, use_tcp_bonding); - if (rc <= 0) - return !rc ? -EINVAL : rc; + cpt = lnet_net_lock_current(); - mutex_lock(&the_lnet.ln_api_mutex); + ni = lnet_get_ni_idx_locked(cfg_ni->lic_idx); - if (rc > 1) { - rc = -EINVAL; /* only add one network per call */ - goto failed0; + if (ni) { + rc = 0; + lnet_ni_lock(ni); + lnet_fill_ni_info(ni, cfg_ni, tun, tun_size); + lnet_ni_unlock(ni); } - net = list_entry(net_head.next, struct lnet_net, net_list); + lnet_net_unlock(cpt); + return rc; +} + +static int lnet_add_net_common(struct lnet_net *net, + struct lnet_ioctl_config_lnd_tunables *tun) +{ + struct lnet_net *netl = NULL; + u32 net_id; + struct lnet_ping_info *pinfo; + struct lnet_handle_md md_handle; + int rc; + struct lnet_remotenet *rnet; + int net_ni_count; + int num_acceptor_nets; lnet_net_lock(LNET_LOCK_EX); rnet = lnet_find_rnet_locked(net->net_id); @@ -2045,9 +2140,9 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) */ if (rnet) { CERROR("Adding net %s will invalidate routing configuration\n", - nets); + libcfs_net2str(net->net_id)); rc = -EUSERS; - goto failed0; + goto failed1; } /* @@ -2056,21 +2151,21 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) * we should allocate enough slots to accomodate the number of NIs * which will be added. * - * We can use lnet_get_net_ni_count_locked() since the net is not - * on a public list yet, so locking is not a problem + * since ni hasn't been configured yet, use + * lnet_get_net_ni_count_pre() which checks the net_ni_added list */ - net_ni_count = lnet_get_net_ni_count_locked(net); + net_ni_count = lnet_get_net_ni_count_pre(net); rc = lnet_ping_info_setup(&pinfo, &md_handle, net_ni_count + lnet_get_ni_count(), false); - if (rc) - goto failed0; - - list_del_init(&net->net_list); - if (lnd_tunables) + if (rc < 0) + goto failed1; + if (tun) memcpy(&net->net_tunables, - &lnd_tunables->lt_cmn, sizeof(lnd_tunables->lt_cmn)); + &tun->lt_cmn, sizeof(net->net_tunables)); + else + memset(&net->net_tunables, -1, sizeof(net->net_tunables)); /* * before starting this network get a count of the current TCP @@ -2080,47 +2175,269 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) */ num_acceptor_nets = lnet_count_acceptor_nets(); - /* - * lnd_startup_lndnet() can deallocate 'net' even if it it returns - * success, because we endded up adding interfaces to an existing - * network. So grab the net_type now - */ - net_type = LNET_NETTYP(net->net_id); + net_id = net->net_id; - rc = lnet_startup_lndnet(net, (lnd_tunables ? - &lnd_tunables->lt_tun : NULL)); + rc = lnet_startup_lndnet(net, (tun ? + &tun->lt_tun : NULL)); if (rc < 0) - goto failed1; + goto failed; + + lnet_net_lock(LNET_LOCK_EX); + netl = lnet_get_net_locked(net_id); + lnet_net_unlock(LNET_LOCK_EX); + + LASSERT(netl); /* * Start the acceptor thread if this is the first network * being added that requires the thread. */ - if (net_type == SOCKLND && num_acceptor_nets == 0) { + if (netl->net_lnd->lnd_accept && + num_acceptor_nets == 0) { rc = lnet_acceptor_start(); if (rc < 0) { /* shutdown the net that we just started */ CERROR("Failed to start up acceptor thread\n"); - /* - * Note that if we needed to start the acceptor - * thread, then 'net' must have been the first TCP - * network, therefore was unique, and therefore - * wasn't deallocated by lnet_startup_lndnet() - */ lnet_shutdown_lndnet(net); - goto failed1; + goto failed; } } + lnet_net_lock(LNET_LOCK_EX); + lnet_peer_net_added(netl); + lnet_net_unlock(LNET_LOCK_EX); + lnet_ping_target_update(pinfo, md_handle); - mutex_unlock(&the_lnet.ln_api_mutex); return 0; -failed1: +failed: lnet_ping_md_unlink(pinfo, &md_handle); lnet_ping_info_free(pinfo); -failed0: +failed1: + lnet_net_free(net); + return rc; +} + +static int lnet_handle_legacy_ip2nets(char *ip2nets, + struct lnet_ioctl_config_lnd_tunables *tun) +{ + struct lnet_net *net; + char *nets; + int rc; + struct list_head net_head; + + INIT_LIST_HEAD(&net_head); + + rc = lnet_parse_ip2nets(&nets, ip2nets); + if (rc < 0) + return rc; + + rc = lnet_parse_networks(&net_head, nets, use_tcp_bonding); + if (rc < 0) + return rc; + + mutex_lock(&the_lnet.ln_api_mutex); + while (!list_empty(&net_head)) { + net = list_entry(net_head.next, struct lnet_net, net_list); + list_del_init(&net->net_list); + rc = lnet_add_net_common(net, tun); + if (rc < 0) + goto out; + } + +out: + mutex_unlock(&the_lnet.ln_api_mutex); + + while (!list_empty(&net_head)) { + net = list_entry(net_head.next, struct lnet_net, net_list); + list_del_init(&net->net_list); + lnet_net_free(net); + } + return rc; +} + +int lnet_dyn_add_ni(struct lnet_ioctl_config_ni *conf) +{ + struct lnet_net *net; + struct lnet_ni *ni; + struct lnet_ioctl_config_lnd_tunables *tun = NULL; + int rc; + u32 net_id; + + /* get the tunables if they are available */ + if (conf->lic_cfg_hdr.ioc_len >= + sizeof(*conf) + sizeof(*tun)) + tun = (struct lnet_ioctl_config_lnd_tunables *) + conf->lic_bulk; + + /* handle legacy ip2nets from DLC */ + if (conf->lic_legacy_ip2nets[0] != '\0') + return lnet_handle_legacy_ip2nets(conf->lic_legacy_ip2nets, + tun); + + net_id = LNET_NIDNET(conf->lic_nid); + + net = lnet_net_alloc(net_id, NULL); + if (!net) + return -ENOMEM; + + ni = lnet_ni_alloc_w_cpt_array(net, conf->lic_cpts, conf->lic_ncpts, + conf->lic_ni_intf[0]); + if (!ni) + return -ENOMEM; + + mutex_lock(&the_lnet.ln_api_mutex); + + rc = lnet_add_net_common(net, tun); + + mutex_unlock(&the_lnet.ln_api_mutex); + + return rc; +} + +int lnet_dyn_del_ni(struct lnet_ioctl_config_ni *conf) +{ + struct lnet_net *net; + struct lnet_ni *ni; + u32 net_id = LNET_NIDNET(conf->lic_nid); + struct lnet_ping_info *pinfo; + struct lnet_handle_md md_handle; + int rc; + int net_count; + u32 addr; + + /* don't allow userspace to shutdown the LOLND */ + if (LNET_NETTYP(net_id) == LOLND) + return -EINVAL; + + mutex_lock(&the_lnet.ln_api_mutex); + + lnet_net_lock(0); + + net = lnet_get_net_locked(net_id); + if (!net) { + CERROR("net %s not found\n", + libcfs_net2str(net_id)); + rc = -ENOENT; + goto net_unlock; + } + + addr = LNET_NIDADDR(conf->lic_nid); + if (addr == 0) { + /* remove the entire net */ + net_count = lnet_get_net_ni_count_locked(net); + + lnet_net_unlock(0); + + /* create and link a new ping info, before removing the old one */ + rc = lnet_ping_info_setup(&pinfo, &md_handle, + lnet_get_ni_count() - net_count, + false); + if (rc != 0) + goto out; + + lnet_shutdown_lndnet(net); + + if (lnet_count_acceptor_nets() == 0) + lnet_acceptor_stop(); + + lnet_ping_target_update(pinfo, md_handle); + + goto out; + } + + ni = lnet_nid2ni_locked(conf->lic_nid, 0); + if (!ni) { + CERROR("nid %s not found\n", + libcfs_nid2str(conf->lic_nid)); + rc = -ENOENT; + goto net_unlock; + } + + net_count = lnet_get_net_ni_count_locked(net); + + lnet_net_unlock(0); + + /* create and link a new ping info, before removing the old one */ + rc = lnet_ping_info_setup(&pinfo, &md_handle, + lnet_get_ni_count() - 1, false); + if (rc != 0) + goto out; + + lnet_shutdown_lndni(ni); + + if (lnet_count_acceptor_nets() == 0) + lnet_acceptor_stop(); + + lnet_ping_target_update(pinfo, md_handle); + + /* check if the net is empty and remove it if it is */ + if (net_count == 1) + lnet_shutdown_lndnet(net); + + goto out; + +net_unlock: + lnet_net_unlock(0); +out: + mutex_unlock(&the_lnet.ln_api_mutex); + + return rc; +} + +/* + * lnet_dyn_add_net and lnet_dyn_del_net are now deprecated. + * They are only expected to be called for unique networks. + * That can be as a result of older DLC library + * calls. Multi-Rail DLC and beyond no longer uses these APIs. + */ +int +lnet_dyn_add_net(struct lnet_ioctl_config_data *conf) +{ + struct lnet_net *net; + struct list_head net_head; + int rc; + struct lnet_ioctl_config_lnd_tunables tun; + char *nets = conf->cfg_config_u.cfg_net.net_intf; + + INIT_LIST_HEAD(&net_head); + + /* Create a net/ni structures for the network string */ + rc = lnet_parse_networks(&net_head, nets, use_tcp_bonding); + if (rc <= 0) + return rc == 0 ? -EINVAL : rc; + + mutex_lock(&the_lnet.ln_api_mutex); + + if (rc > 1) { + rc = -EINVAL; /* only add one network per call */ + goto failed; + } + + net = list_entry(net_head.next, struct lnet_net, net_list); + list_del_init(&net->net_list); + + LASSERT(lnet_net_unique(net->net_id, &the_lnet.ln_nets, NULL)); + + memset(&tun, 0, sizeof(tun)); + + tun.lt_cmn.lct_peer_timeout = + conf->cfg_config_u.cfg_net.net_peer_timeout; + tun.lt_cmn.lct_peer_tx_credits = + conf->cfg_config_u.cfg_net.net_peer_tx_credits; + tun.lt_cmn.lct_peer_rtr_credits = + conf->cfg_config_u.cfg_net.net_peer_rtr_credits; + tun.lt_cmn.lct_max_tx_credits = + conf->cfg_config_u.cfg_net.net_max_tx_credits; + + rc = lnet_add_net_common(net, &tun); + if (rc != 0) + goto failed; + + return 0; + +failed: mutex_unlock(&the_lnet.ln_api_mutex); while (!list_empty(&net_head)) { net = list_entry(net_head.next, struct lnet_net, net_list); @@ -2131,7 +2448,7 @@ lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) } int -lnet_dyn_del_ni(__u32 net_id) +lnet_dyn_del_net(__u32 net_id) { struct lnet_net *net; struct lnet_ping_info *pinfo; @@ -2256,6 +2573,25 @@ LNetCtl(unsigned int cmd, void *arg) &config->cfg_config_u.cfg_route.rtr_flags, &config->cfg_config_u.cfg_route.rtr_priority); + case IOC_LIBCFS_GET_LOCAL_NI: { + struct lnet_ioctl_config_ni *cfg_ni; + struct lnet_ioctl_config_lnd_tunables *tun = NULL; + __u32 tun_size; + + cfg_ni = arg; + /* get the tunables if they are available */ + if (cfg_ni->lic_cfg_hdr.ioc_len < + sizeof(*cfg_ni) + sizeof(*tun)) + return -EINVAL; + + tun = (struct lnet_ioctl_config_lnd_tunables *) + cfg_ni->lic_bulk; + + tun_size = cfg_ni->lic_cfg_hdr.ioc_len - sizeof(*cfg_ni); + + return lnet_get_ni_config(cfg_ni, tun, tun_size); + } + case IOC_LIBCFS_GET_NET: { size_t total = sizeof(*config) + sizeof(struct lnet_ioctl_net_config); @@ -2423,8 +2759,22 @@ LNetCtl(unsigned int cmd, void *arg) data->ioc_count = rc; return 0; } + + case IOC_LIBCFS_DBG: { + struct lnet_ioctl_dbg *dbg = arg; + struct lnet_dbg_task_info *dbg_info; + size_t total = sizeof(*dbg) + sizeof(*dbg_info); + + if (dbg->dbg_hdr.ioc_len < total) + return -EINVAL; + + dbg_info = (struct lnet_dbg_task_info *)dbg->dbg_bulk; + + return lnet_handle_dbg_task(dbg, dbg_info); + } + default: - ni = lnet_net2ni(data->ioc_net); + ni = lnet_net2ni_addref(data->ioc_net); if (!ni) return -EINVAL; @@ -2433,6 +2783,7 @@ LNetCtl(unsigned int cmd, void *arg) else rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg); + lnet_ni_decref(ni); return rc; } /* not reached */ diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 9539ce07ae05..c11821a5838c 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -87,6 +87,9 @@ lnet_net_unique(__u32 net_id, struct list_head *netlist, { struct lnet_net *net_l; + if (!netlist) + return true; + list_for_each_entry(net_l, netlist, net_list) { if (net_l->net_id == net_id) { if (net) @@ -172,6 +175,7 @@ lnet_net_append_cpts(__u32 *cpts, __u32 ncpts, struct lnet_net *net) if (!net->net_cpts) return -ENOMEM; memcpy(net->net_cpts, cpts, ncpts); + net->net_ncpts = ncpts; return 0; } @@ -298,8 +302,7 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_tx_queues) cfs_percpt_free(ni->ni_tx_queues); - if (ni->ni_cpts) - cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts); + kfree(ni->ni_cpts); for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) kfree(ni->ni_interfaces[i]); @@ -371,7 +374,8 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) net->net_tunables.lct_peer_tx_credits = -1; net->net_tunables.lct_peer_rtr_credits = -1; - list_add_tail(&net->net_list, net_list); + if (net_list) + list_add_tail(&net->net_list, net_list); return net; } @@ -414,13 +418,11 @@ lnet_ni_add_interface(struct lnet_ni *ni, char *iface) return 0; } -/* allocate and add to the provided network */ -struct lnet_ni * -lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) +static struct lnet_ni * +lnet_ni_alloc_common(struct lnet_net *net, char *iface) { struct lnet_tx_queue *tq; struct lnet_ni *ni; - int rc; int i; if (iface) @@ -452,6 +454,45 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) cfs_percpt_for_each(tq, i, ni->ni_tx_queues) INIT_LIST_HEAD(&tq->tq_delayed); + ni->ni_net = net; + /* LND will fill in the address part of the NID */ + ni->ni_nid = LNET_MKNID(net->net_id, 0); + + /* Store net namespace in which current ni is being created */ + if (current->nsproxy->net_ns) + ni->ni_net_ns = get_net(current->nsproxy->net_ns); + else + ni->ni_net_ns = NULL; + + ni->ni_last_alive = ktime_get_real_seconds(); + ni->ni_state = LNET_NI_STATE_INIT; + list_add_tail(&ni->ni_netlist, &net->net_ni_added); + + /* + * if an interface name is provided then make sure to add in that + * interface name in NI + */ + if (iface) + if (lnet_ni_add_interface(ni, iface) != 0) + goto failed; + + return ni; +failed: + lnet_ni_free(ni); + return NULL; +} + +/* allocate and add to the provided network */ +struct lnet_ni * +lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) +{ + struct lnet_ni *ni; + int rc; + + ni = lnet_ni_alloc_common(net, iface); + if (!ni) + return NULL; + if (!el) { ni->ni_cpts = NULL; ni->ni_ncpts = LNET_CPT_NUMBER; @@ -466,35 +507,51 @@ lnet_ni_alloc(struct lnet_net *net, struct cfs_expr_list *el, char *iface) LASSERT(rc <= LNET_CPT_NUMBER); if (rc == LNET_CPT_NUMBER) { - cfs_expr_list_values_free(ni->ni_cpts, LNET_CPT_NUMBER); + kfree(ni->ni_cpts); ni->ni_cpts = NULL; } ni->ni_ncpts = rc; } - ni->ni_net = net; - /* LND will fill in the address part of the NID */ - ni->ni_nid = LNET_MKNID(net->net_id, 0); - - /* Store net namespace in which current ni is being created */ - if (current->nsproxy->net_ns) - ni->ni_net_ns = get_net(current->nsproxy->net_ns); - else - ni->ni_net_ns = NULL; - - ni->ni_last_alive = ktime_get_real_seconds(); - ni->ni_state = LNET_NI_STATE_INIT; rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); if (rc != 0) goto failed; - list_add_tail(&ni->ni_netlist, &net->net_ni_added); - /* if an interface name is provided then make sure to add in that - * interface name in NI */ - if (iface) - if (lnet_ni_add_interface(ni, iface) != 0) + return ni; +failed: + lnet_ni_free(ni); + return NULL; +} + +struct lnet_ni * +lnet_ni_alloc_w_cpt_array(struct lnet_net *net, __u32 *cpts, __u32 ncpts, + char *iface) +{ + struct lnet_ni *ni; + int rc; + + ni = lnet_ni_alloc_common(net, iface); + if (!ni) + return NULL; + + if (ncpts == 0) { + ni->ni_cpts = NULL; + ni->ni_ncpts = LNET_CPT_NUMBER; + } else { + size_t array_size = ncpts * sizeof(ni->ni_cpts[0]); + + ni->ni_cpts = kmalloc_array(ncpts, sizeof(ni->ni_cpts[0]), + GFP_KERNEL); + if (!ni->ni_cpts) goto failed; + memcpy(ni->ni_cpts, cpts, array_size); + ni->ni_ncpts = ncpts; + } + + rc = lnet_net_append_cpts(ni->ni_cpts, ni->ni_ncpts, net); + if (rc != 0) + goto failed; return ni; failed: diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c index 9d06664f0c17..c82d27592391 100644 --- a/drivers/staging/lustre/lnet/lnet/module.c +++ b/drivers/staging/lustre/lnet/lnet/module.c @@ -92,7 +92,7 @@ lnet_unconfigure(void) } static int -lnet_dyn_configure(struct libcfs_ioctl_hdr *hdr) +lnet_dyn_configure_net(struct libcfs_ioctl_hdr *hdr) { struct lnet_ioctl_config_data *conf = (struct lnet_ioctl_config_data *)hdr; @@ -102,19 +102,17 @@ lnet_dyn_configure(struct libcfs_ioctl_hdr *hdr) return -EINVAL; mutex_lock(&lnet_config_mutex); - if (!the_lnet.ln_niinit_self) { + if (the_lnet.ln_niinit_self) + rc = lnet_dyn_add_net(conf); + else rc = -EINVAL; - goto out_unlock; - } - rc = lnet_dyn_add_ni(LNET_PID_LUSTRE, conf); -out_unlock: mutex_unlock(&lnet_config_mutex); return rc; } static int -lnet_dyn_unconfigure(struct libcfs_ioctl_hdr *hdr) +lnet_dyn_unconfigure_net(struct libcfs_ioctl_hdr *hdr) { struct lnet_ioctl_config_data *conf = (struct lnet_ioctl_config_data *)hdr; @@ -124,12 +122,50 @@ lnet_dyn_unconfigure(struct libcfs_ioctl_hdr *hdr) return -EINVAL; mutex_lock(&lnet_config_mutex); - if (!the_lnet.ln_niinit_self) { + if (the_lnet.ln_niinit_self) + rc = lnet_dyn_del_net(conf->cfg_net); + else + rc = -EINVAL; + mutex_unlock(&lnet_config_mutex); + + return rc; +} + +static int +lnet_dyn_configure_ni(struct libcfs_ioctl_hdr *hdr) +{ + struct lnet_ioctl_config_ni *conf = + (struct lnet_ioctl_config_ni *)hdr; + int rc; + + if (conf->lic_cfg_hdr.ioc_len < sizeof(*conf)) + return -EINVAL; + + mutex_lock(&lnet_config_mutex); + if (the_lnet.ln_niinit_self) + rc = lnet_dyn_add_ni(conf); + else + rc = -EINVAL; + mutex_unlock(&lnet_config_mutex); + + return rc; +} + +static int +lnet_dyn_unconfigure_ni(struct libcfs_ioctl_hdr *hdr) +{ + struct lnet_ioctl_config_ni *conf = + (struct lnet_ioctl_config_ni *)hdr; + int rc; + + if (conf->lic_cfg_hdr.ioc_len < sizeof(*conf)) + return -EINVAL; + + mutex_lock(&lnet_config_mutex); + if (the_lnet.ln_niinit_self) + rc = lnet_dyn_del_ni(conf); + else rc = -EINVAL; - goto out_unlock; - } - rc = lnet_dyn_del_ni(conf->cfg_net); -out_unlock: mutex_unlock(&lnet_config_mutex); return rc; @@ -161,11 +197,17 @@ lnet_ioctl(struct notifier_block *nb, break; case IOC_LIBCFS_ADD_NET: - rc = lnet_dyn_configure(hdr); + rc = lnet_dyn_configure_net(hdr); break; case IOC_LIBCFS_DEL_NET: - rc = lnet_dyn_unconfigure(hdr); + rc = lnet_dyn_unconfigure_net(hdr); + + case IOC_LIBCFS_ADD_LOCAL_NI: + return lnet_dyn_configure_ni(hdr); + + case IOC_LIBCFS_DEL_LOCAL_NI: + return lnet_dyn_unconfigure_ni(hdr); break; default: diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index d081440579e0..a760e43bcf7e 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -47,6 +47,27 @@ lnet_peer_remove_from_remote_list(struct lnet_peer_ni *lpni) } } +void +lnet_peer_net_added(struct lnet_net *net) +{ + struct lnet_peer_ni *lpni, *tmp; + + list_for_each_entry_safe(lpni, tmp, &the_lnet.ln_remote_peer_ni_list, + lpni_on_remote_peer_ni_list) { + if (LNET_NIDNET(lpni->lpni_nid) == net->net_id) { + lpni->lpni_net = net; + lpni->lpni_txcredits = + lpni->lpni_mintxcredits = + lpni->lpni_net->net_tunables.lct_peer_tx_credits; + lpni->lpni_rtrcredits = + lpni->lpni_minrtrcredits = + lnet_peer_buffer_credits(lpni->lpni_net); + + lnet_peer_remove_from_remote_list(lpni); + } + } +} + void lnet_peer_tables_destroy(void) { diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index 66295b4fcdab..c201a8871943 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -726,7 +726,7 @@ static int ptlrpcd_init(void) ptlrpcds_cpt_idx[cpt] = i; } - cfs_expr_list_values_free(cpts, rc); + kfree(cpts); ncpts = rc; } ptlrpcds_num = ncpts; diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c index 55f68b9b3818..79baadc0d09f 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/service.c +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c @@ -2780,9 +2780,7 @@ ptlrpc_service_free(struct ptlrpc_service *svc) ptlrpc_service_for_each_part(svcpt, i, svc) kfree(svcpt); - if (svc->srv_cpts) - cfs_expr_list_values_free(svc->srv_cpts, svc->srv_ncpts); - + kfree(svc->srv_cpts); kfree(svc); } From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 12/34] LU-7734 lnet: NUMA support In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763531.32103.14595088461405832909.stgit@noble> From: Amir Shehata This patch adds NUMA node support. NUMA node information is stored in the CPT table. A NUMA node mask is maintained for the entire table as well as for each CPT to track the NUMA nodes related to each of the CPTs. Following key APIs added: cfs_cpt_of_node(): returns the CPT of particular NUMA node cfs_cpt_distance(): calculates the distance between two CPTs When the LND device is started it finds the NUMA node of the physical device and then from there it finds the CPT, which is subsequently stored in the NI structure. When selecting the NI, the MD CPT is determined and the distance between the MD CPT and the device CPT is calculated. The NI with the shortest distance is preferred. If the device or system is not NUMA aware then the CPT for the device will default to CFS_CPT_ANY and the distance calculated when CFS_CPT_ANY is used is largest in the system. IE, none NUMA aware devices are least preferred. A NUMA range value can be set. If the value is large enough it amounts to basically turning off NUMA criterion completely. Signed-off-by: Amir Shehata Change-Id: I2d7c63f8e8fc8e8a6a249b0d6bfdd08fd090a837 Reviewed-on: http://review.whamcloud.com/18916 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 .../staging/lustre/include/linux/lnet/lib-types.h | 3 .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 6 + .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 6 + .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 4 + .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 13 ++ drivers/staging/lustre/lnet/lnet/api-ni.c | 27 +++ drivers/staging/lustre/lnet/lnet/lib-move.c | 160 +++++++++++++++++--- 8 files changed, 195 insertions(+), 25 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index a7cff6426ad8..c338e31b2cdd 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -408,6 +408,7 @@ struct lnet_ni *lnet_net2ni_addref(__u32 net); bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); struct lnet_net *lnet_get_net_locked(u32 net_id); +extern unsigned int lnet_numa_range; extern int portal_rotor; int lnet_lib_init(void); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 22b141cb6cff..5083b72ca20f 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -346,6 +346,9 @@ struct lnet_ni { /* lnd tunables set explicitly */ bool ni_lnd_tunables_set; + /* physical device CPT */ + int dev_cpt; + /* sequence number used to round robin over nis within a net */ u32 ni_seq; diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h index fa58aaf6ad9d..a231f6d89e95 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h @@ -142,7 +142,9 @@ struct libcfs_debug_ioctl_data { #define IOC_LIBCFS_ADD_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 95, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_DEL_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 96, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_GET_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 97, IOCTL_CONFIG_SIZE) -#define IOC_LIBCFS_DBG _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE) -#define IOC_LIBCFS_MAX_NR 98 +#define IOC_LIBCFS_SET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_GET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 99, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_DBG _IOWR(IOC_LIBCFS_TYPE, 100, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_MAX_NR 100 #endif /* __LIBCFS_IOCTL_H__ */ diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index bfd9fc6bc4df..5eaaf0eae470 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -162,6 +162,7 @@ struct lnet_ioctl_config_ni { __u32 lic_status; __u32 lic_tcp_bonding; __u32 lic_idx; + __s32 lic_dev_cpt; char lic_bulk[0]; }; @@ -213,6 +214,11 @@ struct lnet_ioctl_peer_cfg { char prcfg_bulk[0]; }; +struct lnet_ioctl_numa_range { + struct libcfs_ioctl_hdr nr_hdr; + __u32 nr_range; +}; + struct lnet_ioctl_lnet_stats { struct libcfs_ioctl_hdr st_hdr; struct lnet_counters st_cntrs; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 958ac9a99045..2e71abbf8a0c 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2829,6 +2829,7 @@ static int kiblnd_startup(struct lnet_ni *ni) unsigned long flags; int rc; int newdev; + int node_id; LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); @@ -2878,6 +2879,9 @@ static int kiblnd_startup(struct lnet_ni *ni) if (!ibdev) goto failed; + node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device); + ni->dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); + net->ibn_dev = ibdev; ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 9df66c6d160f..ba1ec35a017a 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -38,6 +38,7 @@ * Author: Eric Barton */ +#include #include "socklnd.h" #include @@ -2726,6 +2727,8 @@ ksocknal_startup(struct lnet_ni *ni) struct ksock_net *net; int rc; int i; + struct net_device *net_dev; + int node_id; LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); @@ -2773,6 +2776,16 @@ ksocknal_startup(struct lnet_ni *ni) } } + net_dev = dev_get_by_name(&init_net, + net->ksnn_interfaces[0].ksni_name); + if (net_dev) { + node_id = dev_to_node(&net_dev->dev); + ni->dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); + dev_put(net_dev); + } else { + ni->dev_cpt = CFS_CPT_ANY; + } + /* call it before add it to ksocknal_data.ksnd_nets */ rc = ksocknal_net_start_threads(net, ni->ni_cpts, ni->ni_ncpts); if (rc) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 1ef9a39b517d..67a3301258d4 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -64,6 +64,12 @@ module_param(use_tcp_bonding, int, 0444); MODULE_PARM_DESC(use_tcp_bonding, "Set to 1 to use socklnd bonding. 0 to use Multi-Rail"); +unsigned int lnet_numa_range; +EXPORT_SYMBOL(lnet_numa_range); +module_param(lnet_numa_range, uint, 0444); +MODULE_PARM_DESC(lnet_numa_range, + "NUMA range to consider during Multi-Rail selection"); + /* * This sequence number keeps track of how many times DLC was used to * update the configuration. It is incremented on any DLC update and @@ -1896,6 +1902,7 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_ni *cfg_ni, cfg_ni->lic_nid = ni->ni_nid; cfg_ni->lic_status = ni->ni_status->ns_status; cfg_ni->lic_tcp_bonding = use_tcp_bonding; + cfg_ni->lic_dev_cpt = ni->dev_cpt; memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn)); @@ -2642,6 +2649,26 @@ LNetCtl(unsigned int cmd, void *arg) mutex_unlock(&the_lnet.ln_api_mutex); return rc; + case IOC_LIBCFS_SET_NUMA_RANGE: { + struct lnet_ioctl_numa_range *numa; + + numa = arg; + if (numa->nr_hdr.ioc_len != sizeof(*numa)) + return -EINVAL; + lnet_numa_range = numa->nr_range; + return 0; + } + + case IOC_LIBCFS_GET_NUMA_RANGE: { + struct lnet_ioctl_numa_range *numa; + + numa = arg; + if (numa->nr_hdr.ioc_len != sizeof(*numa)) + return -EINVAL; + numa->nr_range = lnet_numa_range; + return 0; + } + case IOC_LIBCFS_GET_BUF: { struct lnet_ioctl_pool_cfg *pool_cfg; size_t total = sizeof(*config) + sizeof(*pool_cfg); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index fbf209610ff9..bf2256da6122 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1109,6 +1109,10 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, int best_credits = 0; u32 seq, seq2; int best_lpni_credits = INT_MIN; + int md_cpt = 0; + unsigned int shortest_distance = UINT_MAX; + unsigned int distance = 0; + bool found_ir = false; again: /* @@ -1127,12 +1131,20 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, routing = false; local_net = NULL; best_ni = NULL; + shortest_distance = UINT_MAX; + found_ir = false; if (the_lnet.ln_shutdown) { lnet_net_unlock(cpt); return -ESHUTDOWN; } + if (msg->msg_md) + /* get the cpt of the MD, used during NUMA based selection */ + md_cpt = lnet_cpt_of_cookie(msg->msg_md->md_lh.lh_cookie); + else + md_cpt = CFS_CPT_ANY; + /* * initialize the variables which could be reused if we go to * again @@ -1258,34 +1270,113 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, continue; /* - * Second jab at determining best_ni - * if we get here then the peer we're trying to send - * to is on a directly connected network, and we'll - * need to pick the local_ni on that network to send - * from + * Iterate through the NIs in this local Net and select + * the NI to send from. The selection is determined by + * these 3 criterion in the following priority: + * 1. NUMA + * 2. NI available credits + * 3. Round Robin */ while ((ni = lnet_get_next_ni_locked(local_net, ni))) { if (!lnet_is_ni_healthy_locked(ni)) continue; - /* TODO: compare NUMA distance */ - if (ni->ni_tx_queues[cpt]->tq_credits <= - best_credits) { + + /* + * calculate the distance from the cpt on which + * the message memory is allocated to the CPT of + * the NI's physical device + */ + distance = cfs_cpt_distance(lnet_cpt_table(), + md_cpt, + ni->dev_cpt); + + /* + * If we already have a closer NI within the NUMA + * range provided, then there is no need to + * consider the current NI. Move on to the next + * one. + */ + if (distance > shortest_distance && + distance > lnet_numa_range) + continue; + + if (distance < shortest_distance && + distance > lnet_numa_range) { /* - * all we want is to read tq_credits - * value as an approximation of how - * busy the NI is. No need to grab a lock + * The current NI is the closest one that we + * have found, even though it's not in the + * NUMA range specified. This occurs if + * the NUMA range is less than the least + * of the distances in the system. + * In effect NUMA range consideration is + * turned off. */ - continue; - } else if (best_ni) { - if ((best_ni)->ni_seq - ni->ni_seq <= 0) + shortest_distance = distance; + } else if ((distance <= shortest_distance && + distance < lnet_numa_range) || + distance == shortest_distance) { + /* + * This NI is either within range or it's + * equidistant. In both of these cases we + * would want to select the NI based on + * its available credits first, and then + * via Round Robin. + */ + if (distance <= shortest_distance && + distance < lnet_numa_range) { + /* + * If this is the first NI that's + * within range, then set the + * shortest distance to the range + * specified by the user. In + * effect we're saying that all + * NIs that fall within this NUMA + * range shall be dealt with as + * having equal NUMA weight. Which + * will mean that we should select + * through that set by their + * available credits first + * followed by Round Robin. + * + * And since this is the first NI + * in the range, let's just set it + * as our best_ni for now. The + * following NIs found in the + * range will be dealt with as + * mentioned previously. + */ + shortest_distance = lnet_numa_range; + if (!found_ir) { + found_ir = true; + goto set_ni; + } + } + /* + * This NI is NUMA equidistant let's + * select using credits followed by Round + * Robin. + */ + if (ni->ni_tx_queues[cpt]->tq_credits < + best_credits) { continue; - (best_ni)->ni_seq = ni->ni_seq + 1; + } else if (ni->ni_tx_queues[cpt]->tq_credits == + best_credits) { + if (best_ni && + best_ni->ni_seq <= ni->ni_seq) + continue; + } } - +set_ni: best_ni = ni; best_credits = ni->ni_tx_queues[cpt]->tq_credits; } } + /* + * Now that we selected the NI to use increment its sequence + * number so the Round Robin algorithm will detect that it has + * been used and pick the next NI. + */ + best_ni->ni_seq++; if (!best_ni) { lnet_net_unlock(cpt); @@ -1372,29 +1463,52 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, best_lpni = NULL; while ((lpni = lnet_get_next_peer_ni_locked(peer, peer_net, lpni))) { /* - * if this peer ni is not healty just skip it, no point in + * if this peer ni is not healthy just skip it, no point in * examining it further */ if (!lnet_is_peer_ni_healthy_locked(lpni)) continue; ni_is_pref = lnet_peer_is_ni_pref_locked(lpni, best_ni); + /* if this is a preferred peer use it */ if (!preferred && ni_is_pref) { preferred = true; } else if (preferred && !ni_is_pref) { + /* + * this is not the preferred peer so let's ignore + * it. + */ continue; - } else if (lpni->lpni_txcredits <= best_lpni_credits) { + } else if (lpni->lpni_txcredits < best_lpni_credits) { + /* + * We already have a peer that has more credits + * available than this one. No need to consider + * this peer further. + */ continue; - } else if (best_lpni) { - if (best_lpni->lpni_seq - lpni->lpni_seq <= 0) - continue; - best_lpni->lpni_seq = lpni->lpni_seq + 1; + } else if (lpni->lpni_txcredits == best_lpni_credits) { + /* + * The best peer found so far and the current peer + * have the same number of available credits let's + * make sure to select between them using Round + * Robin + */ + if (best_lpni) { + if (best_lpni->lpni_seq <= lpni->lpni_seq) + continue; + } } best_lpni = lpni; best_lpni_credits = lpni->lpni_txcredits; } + /* + * Increment sequence number of the peer selected so that we can + * pick the next one in Round Robin. + */ + best_lpni->lpni_seq++; + /* if we still can't find a peer ni then we can't reach it */ if (!best_lpni) { u32 net_id = peer_net ? peer_net->lpn_net_id : @@ -1403,7 +1517,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, lnet_net_unlock(cpt); LCONSOLE_WARN("no peer_ni found on peer net %s\n", libcfs_net2str(net_id)); - goto again; + return -EHOSTUNREACH; } send: From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 13/34] LU-7734 lnet: Primary NID and traffic distribution In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763535.32103.1496474509485326901.stgit@noble> From: Amir Shehata When receiving messages from a multi-rail peer we must keep track of both the source NID and the primary NID of the peer. When sending a reply message or RPC respone, the source NID is preferred. But most other uses require identifcation of the peer regardless of which source NID the message came from, and so the primary NID of the peer must then be used. An example for this is the creation of match entries. Another occurs when an event is created: the initiator should be the primary NID, to ensure upper layers (PtlRPC and Lustre) always see the same NID for that peer. This change also contains code to have PtlRPC use LNET_NID_ANY for the 'self' parameter of LNetPut() and LNetGet() when it doesn't care which NI it sends from, and to provide a local/peer NID pair when it does. This can be broken out into a separate change. Signed-off-by: Olaf Weber Signed-off-by: Amir Shehata Change-Id: If4391f2537a94f5784e8c61ae03aad266b2f8e7d Reviewed-on: http://review.whamcloud.com/18938 Tested-by: Maloo Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 .../staging/lustre/include/linux/lnet/lib-types.h | 2 + .../lustre/include/uapi/linux/lnet/lnet-types.h | 4 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 49 ++++++++++++-------- drivers/staging/lustre/lnet/lnet/lib-msg.c | 10 +++- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 3 + drivers/staging/lustre/lnet/lnet/peer.c | 18 +++++++ drivers/staging/lustre/lustre/include/lustre_net.h | 2 + drivers/staging/lustre/lustre/ptlrpc/events.c | 5 ++ drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 16 +++---- 10 files changed, 77 insertions(+), 33 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index c338e31b2cdd..0259cd2251ed 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -652,6 +652,7 @@ int lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid); void lnet_peer_net_added(struct lnet_net *net); +lnet_nid_t lnet_peer_primary_nid(lnet_nid_t nid); void lnet_peer_tables_cleanup(struct lnet_ni *ni); void lnet_peer_uninit(void); int lnet_peer_tables_create(void); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 5083b72ca20f..dbcd9b3da914 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -61,6 +61,8 @@ struct lnet_msg { struct list_head msg_list; /* Q for credits/MD */ struct lnet_process_id msg_target; + /* Primary NID of the source. */ + lnet_nid_t msg_initiator; /* where is it from, it's only for building event */ lnet_nid_t msg_from; __u32 msg_type; diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h index 5770876201c8..e80ef4182e5d 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h @@ -563,10 +563,12 @@ struct lnet_event { struct lnet_process_id target; /** The identifier (nid, pid) of the initiator. */ struct lnet_process_id initiator; + /** The source NID on the initiator. */ + struct lnet_process_id source; /** * The NID of the immediate sender. If the request has been forwarded * by routers, this is the NID of the last hop; otherwise it's the - * same as the initiator. + * same as the source. */ lnet_nid_t sender; /** Indicates the type of the event. */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index bf2256da6122..5153de984ede 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1189,23 +1189,6 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, } } - if (best_ni == the_lnet.ln_loni) { - /* No send credit hassles with LOLND */ - msg->msg_hdr.dest_nid = cpu_to_le64(best_ni->ni_nid); - if (!msg->msg_routing) - msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); - msg->msg_target.nid = best_ni->ni_nid; - lnet_msg_commit(msg, cpt); - - lnet_ni_addref_locked(best_ni, cpt); - lnet_net_unlock(cpt); - msg->msg_txni = best_ni; - lnet_ni_send(best_ni, msg); - - *lo_sent = true; - return 0; - } - if (best_ni) goto pick_peer; @@ -1389,6 +1372,23 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, goto send; pick_peer: + if (best_ni == the_lnet.ln_loni) { + /* No send credit hassles with LOLND */ + lnet_ni_addref_locked(best_ni, cpt); + msg->msg_hdr.dest_nid = cpu_to_le64(best_ni->ni_nid); + if (!msg->msg_routing) + msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); + msg->msg_target.nid = best_ni->ni_nid; + lnet_msg_commit(msg, cpt); + + lnet_net_unlock(cpt); + msg->msg_txni = best_ni; + lnet_ni_send(best_ni, msg); + + *lo_sent = true; + return 0; + } + lpni = NULL; if (msg->msg_type == LNET_MSG_REPLY || @@ -1674,7 +1674,8 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) le32_to_cpus(&hdr->msg.put.ptl_index); le32_to_cpus(&hdr->msg.put.offset); - info.mi_id.nid = hdr->src_nid; + /* Primary peer NID. */ + info.mi_id.nid = msg->msg_initiator; info.mi_id.pid = hdr->src_pid; info.mi_opc = LNET_MD_OP_PUT; info.mi_portal = hdr->msg.put.ptl_index; @@ -1725,6 +1726,7 @@ lnet_parse_get(struct lnet_ni *ni, struct lnet_msg *msg, int rdma_get) { struct lnet_match_info info; struct lnet_hdr *hdr = &msg->msg_hdr; + struct lnet_process_id source_id; struct lnet_handle_wire reply_wmd; int rc; @@ -1734,7 +1736,10 @@ lnet_parse_get(struct lnet_ni *ni, struct lnet_msg *msg, int rdma_get) le32_to_cpus(&hdr->msg.get.sink_length); le32_to_cpus(&hdr->msg.get.src_offset); - info.mi_id.nid = hdr->src_nid; + source_id.nid = hdr->src_nid; + source_id.pid = hdr->src_pid; + /* Primary peer NID */ + info.mi_id.nid = msg->msg_initiator; info.mi_id.pid = hdr->src_pid; info.mi_opc = LNET_MD_OP_GET; info.mi_portal = hdr->msg.get.ptl_index; @@ -1756,7 +1761,7 @@ lnet_parse_get(struct lnet_ni *ni, struct lnet_msg *msg, int rdma_get) reply_wmd = hdr->msg.get.return_wmd; - lnet_prep_send(msg, LNET_MSG_REPLY, info.mi_id, + lnet_prep_send(msg, LNET_MSG_REPLY, source_id, msg->msg_offset, msg->msg_wanted); msg->msg_hdr.msg.reply.dst_wmd = reply_wmd; @@ -2200,6 +2205,8 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, msg->msg_hdr.dest_pid = dest_pid; msg->msg_hdr.payload_length = payload_length; } + /* Multi-Rail: Primary NID of source. */ + msg->msg_initiator = lnet_peer_primary_nid(src_nid); lnet_net_lock(cpt); rc = lnet_nid2peerni_locked(&msg->msg_rxpeer, from_nid, cpt); @@ -2518,6 +2525,8 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id), getmd); /* setup information for lnet_build_msg_event */ + msg->msg_initiator = lnet_peer_primary_nid(peer_id.nid); + /* Cheaper: msg->msg_initiator = getmsg->msg_txpeer->lp_nid; */ msg->msg_from = peer_id.nid; msg->msg_type = LNET_MSG_GET; /* flag this msg as an "optimized" GET */ msg->msg_hdr.src_nid = peer_id.nid; diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index 27bdefa161cc..8628899e1631 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -70,13 +70,19 @@ lnet_build_msg_event(struct lnet_msg *msg, enum lnet_event_kind ev_type) ev->target.pid = le32_to_cpu(hdr->dest_pid); ev->initiator.nid = LNET_NID_ANY; ev->initiator.pid = the_lnet.ln_pid; + ev->source.nid = LNET_NID_ANY; + ev->source.pid = the_lnet.ln_pid; ev->sender = LNET_NID_ANY; } else { /* event for passive message */ ev->target.pid = hdr->dest_pid; ev->target.nid = hdr->dest_nid; ev->initiator.pid = hdr->src_pid; - ev->initiator.nid = hdr->src_nid; + /* Multi-Rail: resolve src_nid to "primary" peer NID */ + ev->initiator.nid = msg->msg_initiator; + /* Multi-Rail: track source NID. */ + ev->source.pid = hdr->src_pid; + ev->source.nid = hdr->src_nid; ev->rlength = hdr->payload_length; ev->sender = msg->msg_from; ev->mlength = msg->msg_wanted; @@ -381,7 +387,7 @@ lnet_complete_msg_locked(struct lnet_msg *msg, int cpt) ack_wmd = msg->msg_hdr.msg.put.ack_wmd; - lnet_prep_send(msg, LNET_MSG_ACK, msg->msg_ev.initiator, 0, 0); + lnet_prep_send(msg, LNET_MSG_ACK, msg->msg_ev.source, 0, 0); msg->msg_hdr.msg.ack.dst_wmd = ack_wmd; msg->msg_hdr.msg.ack.match_bits = msg->msg_ev.match_bits; diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index c8d8162cc706..d4033530112e 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -687,7 +687,8 @@ lnet_ptl_attach_md(struct lnet_me *me, struct lnet_libmd *md, LASSERT(msg->msg_rx_delayed || head == &ptl->ptl_msg_stealing); hdr = &msg->msg_hdr; - info.mi_id.nid = hdr->src_nid; + /* Multi-Rail: Primary peer NID */ + info.mi_id.nid = msg->msg_initiator; info.mi_id.pid = hdr->src_pid; info.mi_opc = LNET_MD_OP_PUT; info.mi_portal = hdr->msg.put.ptl_index; diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index a760e43bcf7e..bde7b6214668 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -394,6 +394,24 @@ lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, struct lnet_ni *ni) return false; } +lnet_nid_t +lnet_peer_primary_nid(lnet_nid_t nid) +{ + struct lnet_peer_ni *lpni; + lnet_nid_t primary_nid = nid; + int cpt; + + cpt = lnet_net_lock_current(); + lpni = lnet_find_peer_ni_locked(nid); + if (lpni) { + primary_nid = lpni->lpni_peer_net->lpn_peer->lp_primary_nid; + lnet_peer_ni_decref_locked(lpni); + } + lnet_net_unlock(cpt); + + return primary_nid; +} + static void lnet_try_destroy_peer_hierarchy_locked(struct lnet_peer_ni *lpni) { diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h index 361b8970368e..2dbd20851b39 100644 --- a/drivers/staging/lustre/lustre/include/lustre_net.h +++ b/drivers/staging/lustre/lustre/include/lustre_net.h @@ -882,6 +882,8 @@ struct ptlrpc_request { lnet_nid_t rq_self; /** Peer description (the other side) */ struct lnet_process_id rq_peer; + /** Descriptor for the NID from which the peer sent the request. */ + struct lnet_process_id rq_source; /** * service time estimate (secs) * If the request is not served by this time, it is marked as timed out. diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c index ebf985ec17a1..ab6dd74d0ae3 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/events.c +++ b/drivers/staging/lustre/lustre/ptlrpc/events.c @@ -342,7 +342,9 @@ void request_in_callback(struct lnet_event *ev) if (ev->type == LNET_EVENT_PUT && ev->status == 0) req->rq_reqdata_len = ev->mlength; ktime_get_real_ts64(&req->rq_arrival_time); + /* Multi-Rail: keep track of both initiator and source NID. */ req->rq_peer = ev->initiator; + req->rq_source = ev->source; req->rq_self = ev->target.nid; req->rq_rqbd = rqbd; req->rq_phase = RQ_PHASE_NEW; @@ -350,7 +352,8 @@ void request_in_callback(struct lnet_event *ev) CDEBUG(D_INFO, "incoming req@%p x%llu msgsize %u\n", req, req->rq_xid, ev->mlength); - CDEBUG(D_RPCTRACE, "peer: %s\n", libcfs_id2str(req->rq_peer)); + CDEBUG(D_RPCTRACE, "peer: %s (source: %s)\n", + libcfs_id2str(req->rq_peer), libcfs_id2str(req->rq_source)); spin_lock(&svcpt->scp_lock); diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index 2897afb8806c..d0bcd8827f8a 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -47,14 +47,14 @@ */ static int ptl_send_buf(struct lnet_handle_md *mdh, void *base, int len, enum lnet_ack_req ack, struct ptlrpc_cb_id *cbid, - struct ptlrpc_connection *conn, int portal, __u64 xid, - unsigned int offset) + lnet_nid_t self, struct lnet_process_id peer_id, + int portal, __u64 xid, unsigned int offset) { int rc; struct lnet_md md; LASSERT(portal != 0); - CDEBUG(D_INFO, "conn=%p id %s\n", conn, libcfs_id2str(conn->c_peer)); + CDEBUG(D_INFO, "peer_id %s\n", libcfs_id2str(peer_id)); md.start = base; md.length = len; md.threshold = (ack == LNET_ACK_REQ) ? 2 : 1; @@ -79,8 +79,8 @@ static int ptl_send_buf(struct lnet_handle_md *mdh, void *base, int len, CDEBUG(D_NET, "Sending %d bytes to portal %d, xid %lld, offset %u\n", len, portal, xid, offset); - rc = LNetPut(conn->c_self, *mdh, ack, - conn->c_peer, portal, xid, offset, 0); + rc = LNetPut(self, *mdh, ack, + peer_id, portal, xid, offset, 0); if (unlikely(rc != 0)) { int rc2; /* We're going to get an UNLINK event when I unlink below, @@ -88,7 +88,7 @@ static int ptl_send_buf(struct lnet_handle_md *mdh, void *base, int len, * I fall through and return success here! */ CERROR("LNetPut(%s, %d, %lld) failed: %d\n", - libcfs_id2str(conn->c_peer), portal, xid, rc); + libcfs_id2str(peer_id), portal, xid, rc); rc2 = LNetMDUnlink(*mdh); LASSERTF(rc2 == 0, "rc2 = %d\n", rc2); } @@ -415,7 +415,7 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags) rc = ptl_send_buf(&rs->rs_md_h, rs->rs_repbuf, rs->rs_repdata_len, (rs->rs_difficult && !rs->rs_no_ack) ? LNET_ACK_REQ : LNET_NOACK_REQ, - &rs->rs_cb_id, conn, + &rs->rs_cb_id, req->rq_self, req->rq_source, ptlrpc_req2svc(req)->srv_rep_portal, req->rq_xid, req->rq_reply_off); out: @@ -683,7 +683,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) rc = ptl_send_buf(&request->rq_req_md_h, request->rq_reqbuf, request->rq_reqdata_len, LNET_NOACK_REQ, &request->rq_req_cbid, - connection, + LNET_NID_ANY, connection->c_peer, request->rq_request_portal, request->rq_xid, 0); if (likely(rc == 0)) From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 14/34] LU-7734 lnet: handle non-MR peers In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763540.32103.13948722910331939075.stgit@noble> From: Amir Shehata Add the ability to declare a peer to be non-MR from the DLC interface. By default if a peer is configured from DLC it is assumed to be MR capable, except when the non-mr flag is set. For non-MR peers always use the same NI to communicate with it. If multiple NIs are used to communicate with a non-MR peer the peer will consider that it's talking to different peers which could cause upper layers to be confused. Signed-off-by: Amir Shehata Change-Id: Ie3ec45f5f44fa7d72e3e0335b1383f9c3cc92627 Reviewed-on: http://review.whamcloud.com/19305 Tested-by: Jenkins Reviewed-by: Doug Oucharek Tested-by: Maloo Reviewed-by: Olaf Weber Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 17 ++++++++++++++++- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 1 + drivers/staging/lustre/lnet/lnet/api-ni.c | 3 ++- drivers/staging/lustre/lnet/lnet/lib-move.c | 13 +++++++++++++ drivers/staging/lustre/lnet/lnet/peer.c | 7 ++++--- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 0259cd2251ed..08fc4abad332 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -661,7 +661,7 @@ struct lnet_peer_net *lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id); bool lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, struct lnet_ni *ni); -int lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid); +int lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr); int lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid); int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, struct lnet_peer_ni_credit_info *peer_ni_info); @@ -672,6 +672,21 @@ int lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, __u32 *peer_rtr_credits, __u32 *peer_min_rtr_credtis, __u32 *peer_tx_qnob); +static inline __u32 +lnet_get_num_peer_nis(struct lnet_peer *peer) +{ + struct lnet_peer_net *lpn; + struct lnet_peer_ni *lpni; + __u32 count = 0; + + list_for_each_entry(lpn, &peer->lp_peer_nets, lpn_on_peer_list) + list_for_each_entry(lpni, &lpn->lpn_peer_nis, + lpni_on_peer_net_list) + count++; + + return count; +} + static inline bool lnet_is_peer_ni_healthy_locked(struct lnet_peer_ni *lpni) { diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index 5eaaf0eae470..8be322dd4bd2 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -211,6 +211,7 @@ struct lnet_ioctl_peer_cfg { lnet_nid_t prcfg_key_nid; lnet_nid_t prcfg_cfg_nid; __u32 prcfg_idx; + bool prcfg_mr; char prcfg_bulk[0]; }; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 67a3301258d4..2d5d657de058 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -2689,7 +2689,8 @@ LNetCtl(unsigned int cmd, void *arg) return -EINVAL; return lnet_add_peer_ni_to_peer(cfg->prcfg_key_nid, - cfg->prcfg_cfg_nid); + cfg->prcfg_cfg_nid, + cfg->prcfg_mr); } case IOC_LIBCFS_DEL_PEER_NI: { diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 5153de984ede..6c5bb953a6d3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1164,6 +1164,12 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, return -EHOSTUNREACH; } + if (!peer->lp_multi_rail && lnet_get_num_peer_nis(peer) > 1) { + CERROR("peer %s is declared to be non MR capable, yet configured with more than one NID\n", + libcfs_nid2str(dst_nid)); + return -EINVAL; + } + /* * STEP 1: first jab at determineing best_ni * if src_nid is explicitly specified, then best_ni is already @@ -1361,6 +1367,13 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, */ best_ni->ni_seq++; + /* + * if the peer is not MR capable, then we should always send to it + * using the first NI in the NET we determined. + */ + if (!peer->lp_multi_rail && local_net) + best_ni = lnet_net2ni_locked(local_net->net_id, cpt); + if (!best_ni) { lnet_net_unlock(cpt); LCONSOLE_WARN("No local ni found to send from to %s\n", diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index bde7b6214668..ecbd276703f1 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -477,6 +477,7 @@ lnet_build_peer_hierarchy(struct lnet_peer_ni *lpni) peer_net->lpn_peer = peer; lpni->lpni_peer_net = peer_net; peer->lp_primary_nid = lpni->lpni_nid; + peer->lp_multi_rail = false; list_add_tail(&peer_net->lpn_on_peer_list, &peer->lp_peer_nets); list_add_tail(&lpni->lpni_on_peer_net_list, &peer_net->lpn_peer_nis); list_add_tail(&peer->lp_on_lnet_peer_list, &the_lnet.ln_peers); @@ -502,7 +503,7 @@ lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id) * is unique */ int -lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid) +lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr) { struct lnet_peer_ni *lpni, *lpni2; struct lnet_peer *peer; @@ -535,14 +536,14 @@ lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid) return -EINVAL; } peer = lpni->lpni_peer_net->lpn_peer; - peer->lp_multi_rail = true; + peer->lp_multi_rail = mr; lnet_peer_ni_decref_locked(lpni); lnet_net_unlock(cpt2); } else { lnet_net_lock(LNET_LOCK_EX); rc = lnet_nid2peerni_locked(&lpni, nid, LNET_LOCK_EX); if (rc == 0) { - lpni->lpni_peer_net->lpn_peer->lp_multi_rail = true; + lpni->lpni_peer_net->lpn_peer->lp_multi_rail = mr; lnet_peer_ni_decref_locked(lpni); } lnet_net_unlock(LNET_LOCK_EX); From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 15/34] LU-7734 lnet: handle N NIs to 1 LND peer In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763544.32103.10828937501297905304.stgit@noble> From: Amir Shehata This patch changes o2iblnd only, as socklnd already handles this case. In the new design you can have multiple NIs communicating to one peer. In the o2ilbnd the kib_peer has a pointer to the NI which implies a 1:1 relationship. This patch changes kiblnd_find_peer_locked() to use the peer NID and the NI NID as the key. This way a new peer will be created for each unique NI/peer_NI pair. This is similar to how socklnd handles this case. Signed-off-by: Amir Shehata Change-Id: Ifab7764489757ea473b15c46c1a22ef9ceeeceea Reviewed-on: http://review.whamcloud.com/19306 Reviewed-by: Doug Oucharek Tested-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 13 ++++++++++--- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 2 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 2e71abbf8a0c..64df49146413 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -379,7 +379,7 @@ void kiblnd_destroy_peer(struct kib_peer *peer) atomic_dec(&net->ibn_npeers); } -struct kib_peer *kiblnd_find_peer_locked(lnet_nid_t nid) +struct kib_peer *kiblnd_find_peer_locked(struct lnet_ni *ni, lnet_nid_t nid) { /* * the caller is responsible for accounting the additional reference @@ -391,7 +391,14 @@ struct kib_peer *kiblnd_find_peer_locked(lnet_nid_t nid) list_for_each_entry(peer, peer_list, ibp_list) { LASSERT(!kiblnd_peer_idle(peer)); - if (peer->ibp_nid != nid) + /* + * Match a peer if its NID and the NID of the local NI it + * communicates over are the same. Otherwise don't match + * the peer, which will result in a new lnd peer being + * created. + */ + if (peer->ibp_nid != nid || + peer->ibp_ni->ni_nid != ni->ni_nid) continue; CDEBUG(D_NET, "got peer [%p] -> %s (%d) version: %x\n", @@ -1041,7 +1048,7 @@ static void kiblnd_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when) read_lock_irqsave(glock, flags); - peer = kiblnd_find_peer_locked(nid); + peer = kiblnd_find_peer_locked(ni, nid); if (peer) last_alive = peer->ibp_last_alive; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 522eb150d9a6..520f586015f4 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -1019,7 +1019,7 @@ void kiblnd_destroy_peer(struct kib_peer *peer); bool kiblnd_reconnect_peer(struct kib_peer *peer); void kiblnd_destroy_dev(struct kib_dev *dev); void kiblnd_unlink_peer_locked(struct kib_peer *peer); -struct kib_peer *kiblnd_find_peer_locked(lnet_nid_t nid); +struct kib_peer *kiblnd_find_peer_locked(struct lnet_ni *ni, lnet_nid_t nid); int kiblnd_close_stale_conns_locked(struct kib_peer *peer, int version, __u64 incarnation); int kiblnd_close_peer_conns_locked(struct kib_peer *peer, int why); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index af8f863b6a68..f4b76347e1c6 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1370,7 +1370,7 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) */ read_lock_irqsave(g_lock, flags); - peer = kiblnd_find_peer_locked(nid); + peer = kiblnd_find_peer_locked(ni, nid); if (peer && !list_empty(&peer->ibp_conns)) { /* Found a peer with an established connection */ conn = kiblnd_get_conn_locked(peer); @@ -1388,7 +1388,7 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) /* Re-try with a write lock */ write_lock(g_lock); - peer = kiblnd_find_peer_locked(nid); + peer = kiblnd_find_peer_locked(ni, nid); if (peer) { if (list_empty(&peer->ibp_conns)) { /* found a peer, but it's still connecting... */ @@ -1426,7 +1426,7 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) write_lock_irqsave(g_lock, flags); - peer2 = kiblnd_find_peer_locked(nid); + peer2 = kiblnd_find_peer_locked(ni, nid); if (peer2) { if (list_empty(&peer2->ibp_conns)) { /* found a peer, but it's still connecting... */ @@ -2388,7 +2388,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) write_lock_irqsave(g_lock, flags); - peer2 = kiblnd_find_peer_locked(nid); + peer2 = kiblnd_find_peer_locked(ni, nid); if (peer2) { if (!peer2->ibp_version) { peer2->ibp_version = version; From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 17/34] LU-7734 lnet: Add peer_ni and NI stats for DLC In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763552.32103.13888609534957205718.stgit@noble> From: Doug Oucharek This patch adds three stats to the peer_ni and NI structures: send_count, recv_count, and drop_count. These stats get printed when you do an "lnetctl net show -v" (for NI) and "lnetctl peer show" (for peer_ni). Signed-off-by: Doug Oucharek Change-Id: Ic41c88cbc68dba677151d87a1fab53a48d36ea29 Reviewed-on: http://review.whamcloud.com/20170 Reviewed-by: Amir Shehata Tested-by: Amir Shehata Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 +- .../staging/lustre/include/linux/lnet/lib-types.h | 11 +++++++ .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 6 ++++ drivers/staging/lustre/lnet/lnet/api-ni.c | 32 +++++++++++++++----- drivers/staging/lustre/lnet/lnet/lib-move.c | 4 +++ drivers/staging/lustre/lnet/lnet/lib-msg.c | 8 +++++ drivers/staging/lustre/lnet/lnet/peer.c | 7 ++++ 7 files changed, 61 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 08fc4abad332..53a5ee8632a6 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -664,7 +664,8 @@ bool lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, int lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr); int lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid); int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, - struct lnet_peer_ni_credit_info *peer_ni_info); + struct lnet_peer_ni_credit_info *peer_ni_info, + struct lnet_ioctl_element_stats *peer_ni_stats); int lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, char alivness[LNET_MAX_STR_LEN], __u32 *cpt_iter, __u32 *refcount, diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index dbcd9b3da914..e17ca716dce1 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -271,6 +271,12 @@ enum lnet_ni_state { LNET_NI_STATE_DELETING }; +struct lnet_element_stats { + atomic_t send_count; + atomic_t recv_count; + atomic_t drop_count; +}; + struct lnet_net { /* chain on the ln_nets */ struct list_head net_list; @@ -348,6 +354,9 @@ struct lnet_ni { /* lnd tunables set explicitly */ bool ni_lnd_tunables_set; + /* NI statistics */ + struct lnet_element_stats ni_stats; + /* physical device CPT */ int dev_cpt; @@ -403,6 +412,8 @@ struct lnet_peer_ni { struct list_head lpni_rtrq; /* chain on router list */ struct list_head lpni_rtr_list; + /* statistics kept on each peer NI */ + struct lnet_element_stats lpni_stats; /* # tx credits available */ int lpni_txcredits; struct lnet_peer_net *lpni_peer_net; diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index 8be322dd4bd2..b31b69c25ef2 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -142,6 +142,12 @@ struct lnet_ioctl_config_data { char cfg_bulk[0]; }; +struct lnet_ioctl_element_stats { + u32 send_count; + u32 recv_count; + u32 drop_count; +}; + /* * lnet_ioctl_config_ni * This structure describes an NI configuration. There are multiple components diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2d5d657de058..a01858374211 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1881,6 +1881,7 @@ static int lnet_handle_dbg_task(struct lnet_ioctl_dbg *dbg, static void lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_ni *cfg_ni, struct lnet_ioctl_config_lnd_tunables *tun, + struct lnet_ioctl_element_stats *stats, __u32 tun_size) { size_t min_size = 0; @@ -1906,6 +1907,11 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_ni *cfg_ni, memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn)); + if (stats) { + stats->send_count = atomic_read(&ni->ni_stats.send_count); + stats->recv_count = atomic_read(&ni->ni_stats.recv_count); + } + /* * tun->lt_tun will always be present, but in order to be * backwards compatible, we need to deal with the cases when @@ -2102,13 +2108,14 @@ lnet_get_net_config(struct lnet_ioctl_config_data *config) int lnet_get_ni_config(struct lnet_ioctl_config_ni *cfg_ni, struct lnet_ioctl_config_lnd_tunables *tun, + struct lnet_ioctl_element_stats *stats, __u32 tun_size) { struct lnet_ni *ni; int cpt; int rc = -ENOENT; - if (!cfg_ni || !tun) + if (!cfg_ni || !tun || !stats) return -EINVAL; cpt = lnet_net_lock_current(); @@ -2118,7 +2125,7 @@ lnet_get_ni_config(struct lnet_ioctl_config_ni *cfg_ni, if (ni) { rc = 0; lnet_ni_lock(ni); - lnet_fill_ni_info(ni, cfg_ni, tun, tun_size); + lnet_fill_ni_info(ni, cfg_ni, tun, stats, tun_size); lnet_ni_unlock(ni); } @@ -2583,20 +2590,24 @@ LNetCtl(unsigned int cmd, void *arg) case IOC_LIBCFS_GET_LOCAL_NI: { struct lnet_ioctl_config_ni *cfg_ni; struct lnet_ioctl_config_lnd_tunables *tun = NULL; + struct lnet_ioctl_element_stats *stats; __u32 tun_size; cfg_ni = arg; /* get the tunables if they are available */ if (cfg_ni->lic_cfg_hdr.ioc_len < - sizeof(*cfg_ni) + sizeof(*tun)) + sizeof(*cfg_ni) + sizeof(*stats) + sizeof(*tun)) return -EINVAL; + stats = (struct lnet_ioctl_element_stats *) + cfg_ni->lic_bulk; tun = (struct lnet_ioctl_config_lnd_tunables *) - cfg_ni->lic_bulk; + (cfg_ni->lic_bulk + sizeof(*stats)); - tun_size = cfg_ni->lic_cfg_hdr.ioc_len - sizeof(*cfg_ni); + tun_size = cfg_ni->lic_cfg_hdr.ioc_len - sizeof(*cfg_ni) - + sizeof(*stats); - return lnet_get_ni_config(cfg_ni, tun, tun_size); + return lnet_get_ni_config(cfg_ni, tun, stats, tun_size); } case IOC_LIBCFS_GET_NET: { @@ -2724,15 +2735,20 @@ LNetCtl(unsigned int cmd, void *arg) case IOC_LIBCFS_GET_PEER_NI: { struct lnet_ioctl_peer_cfg *cfg = arg; struct lnet_peer_ni_credit_info *lpni_cri; - size_t total = sizeof(*cfg) + sizeof(*lpni_cri); + struct lnet_ioctl_element_stats *lpni_stats; + size_t total = sizeof(*cfg) + sizeof(*lpni_cri) + + sizeof(*lpni_stats); if (cfg->prcfg_hdr.ioc_len < total) return -EINVAL; lpni_cri = (struct lnet_peer_ni_credit_info *)cfg->prcfg_bulk; + lpni_stats = (struct lnet_ioctl_element_stats *) + (cfg->prcfg_bulk + sizeof(*lpni_cri)); return lnet_get_peer_info(cfg->prcfg_idx, &cfg->prcfg_key_nid, - &cfg->prcfg_cfg_nid, lpni_cri); + &cfg->prcfg_cfg_nid, lpni_cri, + lpni_stats); } case IOC_LIBCFS_NOTIFY_ROUTER: { diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 6c5bb953a6d3..3f28f3b87176 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -614,6 +614,10 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) the_lnet.ln_counters[cpt]->drop_count++; the_lnet.ln_counters[cpt]->drop_length += msg->msg_len; lnet_net_unlock(cpt); + if (msg->msg_txpeer) + atomic_inc(&msg->msg_txpeer->lpni_stats.drop_count); + if (msg->msg_txni) + atomic_inc(&msg->msg_txni->ni_stats.drop_count); CNETERR("Dropping message for %s: peer not alive\n", libcfs_id2str(msg->msg_target)); diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index 8628899e1631..aa28b6a12f81 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -215,6 +215,10 @@ lnet_msg_decommit_tx(struct lnet_msg *msg, int status) } counters->send_count++; + if (msg->msg_txpeer) + atomic_inc(&msg->msg_txpeer->lpni_stats.send_count); + if (msg->msg_txni) + atomic_inc(&msg->msg_txni->ni_stats.send_count); out: lnet_return_tx_credits_locked(msg); msg->msg_tx_committed = 0; @@ -270,6 +274,10 @@ lnet_msg_decommit_rx(struct lnet_msg *msg, int status) } counters->recv_count++; + if (msg->msg_rxpeer) + atomic_inc(&msg->msg_rxpeer->lpni_stats.recv_count); + if (msg->msg_rxni) + atomic_inc(&msg->msg_rxni->ni_stats.recv_count); if (ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_REPLY) counters->recv_length += msg->msg_wanted; diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index ecbd276703f1..f626a3fcf00e 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -973,7 +973,8 @@ lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, } int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, - struct lnet_peer_ni_credit_info *peer_ni_info) + struct lnet_peer_ni_credit_info *peer_ni_info, + struct lnet_ioctl_element_stats *peer_ni_stats) { struct lnet_peer_ni *lpni = NULL; struct lnet_peer_net *lpn = NULL; @@ -1000,5 +1001,9 @@ int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, peer_ni_info->cr_peer_min_rtr_credits = lpni->lpni_mintxcredits; peer_ni_info->cr_peer_tx_qnob = lpni->lpni_txqnob; + peer_ni_stats->send_count = atomic_read(&lpni->lpni_stats.send_count); + peer_ni_stats->recv_count = atomic_read(&lpni->lpni_stats.recv_count); + peer_ni_stats->drop_count = atomic_read(&lpni->lpni_stats.drop_count); + return 0; } From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 18/34] LU-7734 lnet: peer/peer_ni handling adjustments In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763556.32103.9233364631803474395.stgit@noble> From: Amir Shehata A peer can be added by specifying a list of NIDs The first NID shall be used as the primary NID. The rest of the NIDs will be added under the primary NID A peer can be added by explicitly specifying the key NID, and then by adding a set of other NIDs, all done through one API call If a key NID already exists, but it's not an MR NI, then adding that Key NID from DLC shall convert that NI to an MR NI If a key NID already exists, and it is an MR NI, then re-adding the Key NID shall have no effect if a Key NID already exists as part of another peer, then adding that NID as part of another peer or as primary shall fail if a NID is being added to a peer NI and that NID is a non-MR, then that NID is moved under the peer and is made to be MR capable if a NID is being added to a peer and that NID is an MR NID and part of another peer, then the operation shall fail if a NID is being added to a peer and it is already part of that Peer then the operation is a no-op. Moreover, the code is structured to consider the addition of Dynamic Discovery in later patches. Signed-off-by: Amir Shehata Change-Id: I71f740192a31ae00f83014ca3e9e06b61ae4ecd5 Reviewed-on: http://review.whamcloud.com/20531 Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 9 .../staging/lustre/include/linux/lnet/lib-types.h | 10 drivers/staging/lustre/lnet/lnet/api-ni.c | 77 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 32 - drivers/staging/lustre/lnet/lnet/peer.c | 907 +++++++++++--------- drivers/staging/lustre/lnet/lnet/router.c | 8 6 files changed, 600 insertions(+), 443 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 53a5ee8632a6..55bcd17cd4dc 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -647,13 +647,12 @@ u32 lnet_get_dlc_seq_locked(void); struct lnet_peer_ni *lnet_get_next_peer_ni_locked(struct lnet_peer *peer, struct lnet_peer_net *peer_net, struct lnet_peer_ni *prev); -int lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, - struct lnet_peer **peer); -int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); +struct lnet_peer *lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt); +struct lnet_peer_ni *lnet_nid2peerni_locked(lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid); void lnet_peer_net_added(struct lnet_net *net); lnet_nid_t lnet_peer_primary_nid(lnet_nid_t nid); -void lnet_peer_tables_cleanup(struct lnet_ni *ni); +void lnet_peer_tables_cleanup(struct lnet_net *net); void lnet_peer_uninit(void); int lnet_peer_tables_create(void); void lnet_debug_peer(lnet_nid_t nid); @@ -664,7 +663,7 @@ bool lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, int lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr); int lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid); int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, - struct lnet_peer_ni_credit_info *peer_ni_info, + bool *mr, struct lnet_peer_ni_credit_info *peer_ni_info, struct lnet_ioctl_element_stats *peer_ni_stats); int lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, char alivness[LNET_MAX_STR_LEN], diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index e17ca716dce1..71ec0eaf8200 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -281,9 +281,9 @@ struct lnet_net { /* chain on the ln_nets */ struct list_head net_list; - /* net ID, which is compoed of + /* net ID, which is composed of * (net_type << 16) | net_num. - * net_type can be one of the enumarated types defined in + * net_type can be one of the enumerated types defined in * lnet/include/lnet/nidstr.h */ __u32 net_id; @@ -513,11 +513,13 @@ struct lnet_peer_table { /* /proc validity stamp */ int pt_version; /* # peers extant */ - int pt_number; + atomic_t pt_number; /* # zombies to go to deathrow (and not there yet) */ int pt_zombies; /* zombie peers */ - struct list_head pt_deathrow; + struct list_head pt_zombie_list; + /* protect list and count */ + spinlock_t pt_zombie_lock; /* NID->peer hash */ struct list_head *pt_hash; }; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index a01858374211..d3db4853c690 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1229,9 +1229,6 @@ lnet_shutdown_lndni(struct lnet_ni *ni) for (i = 0; i < the_lnet.ln_nportals; i++) lnet_clear_lazy_portal(ni, i, "Shutting down NI"); - /* Do peer table cleanup for this ni */ - lnet_peer_tables_cleanup(ni); - lnet_net_lock(LNET_LOCK_EX); lnet_clear_zombies_nis_locked(net); lnet_net_unlock(LNET_LOCK_EX); @@ -1254,6 +1251,12 @@ lnet_shutdown_lndnet(struct lnet_net *net) lnet_net_lock(LNET_LOCK_EX); } + lnet_net_unlock(LNET_LOCK_EX); + + /* Do peer table cleanup for this net */ + lnet_peer_tables_cleanup(net); + + lnet_net_lock(LNET_LOCK_EX); /* * decrement ref count on lnd only when the entire network goes * away @@ -2580,12 +2583,15 @@ LNetCtl(unsigned int cmd, void *arg) if (config->cfg_hdr.ioc_len < sizeof(*config)) return -EINVAL; - return lnet_get_route(config->cfg_count, - &config->cfg_net, - &config->cfg_config_u.cfg_route.rtr_hop, - &config->cfg_nid, - &config->cfg_config_u.cfg_route.rtr_flags, - &config->cfg_config_u.cfg_route.rtr_priority); + mutex_lock(&the_lnet.ln_api_mutex); + rc = lnet_get_route(config->cfg_count, + &config->cfg_net, + &config->cfg_config_u.cfg_route.rtr_hop, + &config->cfg_nid, + &config->cfg_config_u.cfg_route.rtr_flags, + &config->cfg_config_u.cfg_route.rtr_priority); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; case IOC_LIBCFS_GET_LOCAL_NI: { struct lnet_ioctl_config_ni *cfg_ni; @@ -2607,7 +2613,10 @@ LNetCtl(unsigned int cmd, void *arg) tun_size = cfg_ni->lic_cfg_hdr.ioc_len - sizeof(*cfg_ni) - sizeof(*stats); - return lnet_get_ni_config(cfg_ni, tun, stats, tun_size); + mutex_lock(&the_lnet.ln_api_mutex); + rc = lnet_get_ni_config(cfg_ni, tun, stats, tun_size); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; } case IOC_LIBCFS_GET_NET: { @@ -2618,7 +2627,10 @@ LNetCtl(unsigned int cmd, void *arg) if (config->cfg_hdr.ioc_len < total) return -EINVAL; - return lnet_get_net_config(config); + mutex_lock(&the_lnet.ln_api_mutex); + rc = lnet_get_net_config(config); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; } case IOC_LIBCFS_GET_LNET_STATS: { @@ -2627,7 +2639,9 @@ LNetCtl(unsigned int cmd, void *arg) if (lnet_stats->st_hdr.ioc_len < sizeof(*lnet_stats)) return -EINVAL; + mutex_lock(&the_lnet.ln_api_mutex); lnet_counters_get(&lnet_stats->st_cntrs); + mutex_unlock(&the_lnet.ln_api_mutex); return 0; } @@ -2666,7 +2680,9 @@ LNetCtl(unsigned int cmd, void *arg) numa = arg; if (numa->nr_hdr.ioc_len != sizeof(*numa)) return -EINVAL; + mutex_lock(&the_lnet.ln_api_mutex); lnet_numa_range = numa->nr_range; + mutex_unlock(&the_lnet.ln_api_mutex); return 0; } @@ -2690,7 +2706,11 @@ LNetCtl(unsigned int cmd, void *arg) return -EINVAL; pool_cfg = (struct lnet_ioctl_pool_cfg *)config->cfg_bulk; - return lnet_get_rtr_pool_cfg(config->cfg_count, pool_cfg); + + mutex_lock(&the_lnet.ln_api_mutex); + rc = lnet_get_rtr_pool_cfg(config->cfg_count, pool_cfg); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; } case IOC_LIBCFS_ADD_PEER_NI: { @@ -2699,9 +2719,13 @@ LNetCtl(unsigned int cmd, void *arg) if (cfg->prcfg_hdr.ioc_len < sizeof(*cfg)) return -EINVAL; - return lnet_add_peer_ni_to_peer(cfg->prcfg_key_nid, - cfg->prcfg_cfg_nid, - cfg->prcfg_mr); + mutex_lock(&the_lnet.ln_api_mutex); + lnet_incr_dlc_seq(); + rc = lnet_add_peer_ni_to_peer(cfg->prcfg_key_nid, + cfg->prcfg_cfg_nid, + cfg->prcfg_mr); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; } case IOC_LIBCFS_DEL_PEER_NI: { @@ -2710,8 +2734,12 @@ LNetCtl(unsigned int cmd, void *arg) if (cfg->prcfg_hdr.ioc_len < sizeof(*cfg)) return -EINVAL; - return lnet_del_peer_ni_from_peer(cfg->prcfg_key_nid, - cfg->prcfg_cfg_nid); + mutex_lock(&the_lnet.ln_api_mutex); + lnet_incr_dlc_seq(); + rc = lnet_del_peer_ni_from_peer(cfg->prcfg_key_nid, + cfg->prcfg_cfg_nid); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; } case IOC_LIBCFS_GET_PEER_INFO: { @@ -2720,7 +2748,9 @@ LNetCtl(unsigned int cmd, void *arg) if (peer_info->pr_hdr.ioc_len < sizeof(*peer_info)) return -EINVAL; - return lnet_get_peer_ni_info(peer_info->pr_count, + mutex_lock(&the_lnet.ln_api_mutex); + rc = lnet_get_peer_ni_info( + peer_info->pr_count, &peer_info->pr_nid, peer_info->pr_lnd_u.pr_peer_credits.cr_aliveness, &peer_info->pr_lnd_u.pr_peer_credits.cr_ncpt, @@ -2730,6 +2760,8 @@ LNetCtl(unsigned int cmd, void *arg) &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_rtr_credits, &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_min_rtr_credits, &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_qnob); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; } case IOC_LIBCFS_GET_PEER_NI: { @@ -2746,9 +2778,12 @@ LNetCtl(unsigned int cmd, void *arg) lpni_stats = (struct lnet_ioctl_element_stats *) (cfg->prcfg_bulk + sizeof(*lpni_cri)); - return lnet_get_peer_info(cfg->prcfg_idx, &cfg->prcfg_key_nid, - &cfg->prcfg_cfg_nid, lpni_cri, - lpni_stats); + mutex_lock(&the_lnet.ln_api_mutex); + rc = lnet_get_peer_info(cfg->prcfg_idx, &cfg->prcfg_key_nid, + &cfg->prcfg_cfg_nid, &cfg->prcfg_mr, + lpni_cri, lpni_stats); + mutex_unlock(&the_lnet.ln_api_mutex); + return rc; } case IOC_LIBCFS_NOTIFY_ROUTER: { diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 3f28f3b87176..5d9acce26287 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1156,10 +1156,10 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, lpni = NULL; seq = lnet_get_dlc_seq_locked(); - rc = lnet_find_or_create_peer_locked(dst_nid, cpt, &peer); - if (rc != 0) { + peer = lnet_find_or_create_peer_locked(dst_nid, cpt); + if (IS_ERR(peer)) { lnet_net_unlock(cpt); - return rc; + return PTR_ERR(peer); } /* If peer is not healthy then can not send anything to it */ @@ -1364,13 +1364,6 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, best_credits = ni->ni_tx_queues[cpt]->tq_credits; } } - /* - * Now that we selected the NI to use increment its sequence - * number so the Round Robin algorithm will detect that it has - * been used and pick the next NI. - */ - best_ni->ni_seq++; - /* * if the peer is not MR capable, then we should always send to it * using the first NI in the NET we determined. @@ -1385,6 +1378,13 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, return -EINVAL; } + /* + * Now that we selected the NI to use increment its sequence + * number so the Round Robin algorithm will detect that it has + * been used and pick the next NI. + */ + best_ni->ni_seq++; + if (routing) goto send; @@ -1452,7 +1452,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, } CDEBUG(D_NET, "Best route to %s via %s for %s %d\n", - libcfs_nid2str(lpni->lpni_nid), + libcfs_nid2str(dst_nid), libcfs_nid2str(best_gw->lpni_nid), lnet_msgtyp2str(msg->msg_type), msg->msg_len); @@ -2065,6 +2065,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, lnet_pid_t dest_pid; lnet_nid_t dest_nid; lnet_nid_t src_nid; + struct lnet_peer_ni *lpni; __u32 payload_length; __u32 type; @@ -2226,18 +2227,19 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, msg->msg_initiator = lnet_peer_primary_nid(src_nid); lnet_net_lock(cpt); - rc = lnet_nid2peerni_locked(&msg->msg_rxpeer, from_nid, cpt); - if (rc) { + lpni = lnet_nid2peerni_locked(from_nid, cpt); + if (IS_ERR(lpni)) { lnet_net_unlock(cpt); - CERROR("%s, src %s: Dropping %s (error %d looking up sender)\n", + CERROR("%s, src %s: Dropping %s (error %ld looking up sender)\n", libcfs_nid2str(from_nid), libcfs_nid2str(src_nid), - lnet_msgtyp2str(type), rc); + lnet_msgtyp2str(type), PTR_ERR(lpni)); kfree(msg); if (rc == -ESHUTDOWN) /* We are shutting down. Don't do anything more */ return 0; goto drop; } + msg->msg_rxpeer = lpni; msg->msg_rxni = ni; lnet_ni_addref_locked(ni, cpt); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index f626a3fcf00e..c2a04526a59a 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -84,6 +84,8 @@ lnet_peer_tables_destroy(void) if (!hash) /* not initialized */ break; + LASSERT(list_empty(&ptable->pt_zombie_list)); + ptable->pt_hash = NULL; for (j = 0; j < LNET_PEER_HASH_SIZE; j++) LASSERT(list_empty(&hash[j])); @@ -95,27 +97,179 @@ lnet_peer_tables_destroy(void) the_lnet.ln_peer_tables = NULL; } -void lnet_peer_uninit(void) +static struct lnet_peer_ni * +lnet_peer_ni_alloc(lnet_nid_t nid) { + struct lnet_peer_ni *lpni; + struct lnet_net *net; int cpt; - struct lnet_peer_ni *lpni, *tmp; - struct lnet_peer_table *ptable = NULL; - /* remove all peer_nis from the remote peer and he hash list */ - list_for_each_entry_safe(lpni, tmp, &the_lnet.ln_remote_peer_ni_list, - lpni_on_remote_peer_ni_list) { - list_del_init(&lpni->lpni_on_remote_peer_ni_list); - lnet_peer_ni_decref_locked(lpni); + cpt = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); + + lpni = kzalloc_cpt(sizeof(*lpni), GFP_KERNEL, cpt); + if (!lpni) + return NULL; - cpt = lnet_cpt_of_nid_locked(lpni->lpni_nid, NULL); - ptable = the_lnet.ln_peer_tables[cpt]; - ptable->pt_zombies++; + INIT_LIST_HEAD(&lpni->lpni_txq); + INIT_LIST_HEAD(&lpni->lpni_rtrq); + INIT_LIST_HEAD(&lpni->lpni_routes); + INIT_LIST_HEAD(&lpni->lpni_hashlist); + INIT_LIST_HEAD(&lpni->lpni_on_peer_net_list); + INIT_LIST_HEAD(&lpni->lpni_on_remote_peer_ni_list); - list_del_init(&lpni->lpni_hashlist); - lnet_peer_ni_decref_locked(lpni); + lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ + lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ + lpni->lpni_ping_feats = LNET_PING_FEAT_INVAL; + lpni->lpni_nid = nid; + lpni->lpni_cpt = cpt; + lnet_set_peer_ni_health_locked(lpni, true); + + net = lnet_get_net_locked(LNET_NIDNET(nid)); + lpni->lpni_net = net; + if (net) { + lpni->lpni_txcredits = net->net_tunables.lct_peer_tx_credits; + lpni->lpni_mintxcredits = lpni->lpni_txcredits; + lpni->lpni_rtrcredits = lnet_peer_buffer_credits(net); + lpni->lpni_minrtrcredits = lpni->lpni_rtrcredits; + } else { + /* + * This peer_ni is not on a local network, so we + * cannot add the credits here. In case the net is + * added later, add the peer_ni to the remote peer ni + * list so it can be easily found and revisited. + */ + /* FIXME: per-net implementation instead? */ + atomic_inc(&lpni->lpni_refcount); + list_add_tail(&lpni->lpni_on_remote_peer_ni_list, + &the_lnet.ln_remote_peer_ni_list); } + /* TODO: update flags */ + + return lpni; +} + +static struct lnet_peer_net * +lnet_peer_net_alloc(u32 net_id) +{ + struct lnet_peer_net *lpn; + + lpn = kzalloc_cpt(sizeof(*lpn), GFP_KERNEL, CFS_CPT_ANY); + if (!lpn) + return NULL; + + INIT_LIST_HEAD(&lpn->lpn_on_peer_list); + INIT_LIST_HEAD(&lpn->lpn_peer_nis); + lpn->lpn_net_id = net_id; + + return lpn; +} + +static struct lnet_peer * +lnet_peer_alloc(lnet_nid_t nid) +{ + struct lnet_peer *lp; + + lp = kzalloc_cpt(sizeof(*lp), GFP_KERNEL, CFS_CPT_ANY); + if (!lp) + return NULL; + + INIT_LIST_HEAD(&lp->lp_on_lnet_peer_list); + INIT_LIST_HEAD(&lp->lp_peer_nets); + lp->lp_primary_nid = nid; + + /* TODO: update flags */ + + return lp; +} + +static void +lnet_try_destroy_peer_hierarchy_locked(struct lnet_peer_ni *lpni) +{ + struct lnet_peer_net *peer_net; + struct lnet_peer *peer; + + /* TODO: could the below situation happen? accessing an already + * destroyed peer? + */ + if (!lpni->lpni_peer_net || + !lpni->lpni_peer_net->lpn_peer) + return; + + peer_net = lpni->lpni_peer_net; + peer = lpni->lpni_peer_net->lpn_peer; + + list_del_init(&lpni->lpni_on_peer_net_list); + lpni->lpni_peer_net = NULL; + + /* if peer_net is empty, then remove it from the peer */ + if (list_empty(&peer_net->lpn_peer_nis)) { + list_del_init(&peer_net->lpn_on_peer_list); + peer_net->lpn_peer = NULL; + kfree(peer_net); + + /* If the peer is empty then remove it from the + * the_lnet.ln_peers. + */ + if (list_empty(&peer->lp_peer_nets)) { + list_del_init(&peer->lp_on_lnet_peer_list); + kfree(peer); + } + } +} + +/* called with lnet_net_lock LNET_LOCK_EX held */ +static void +lnet_peer_ni_del_locked(struct lnet_peer_ni *lpni) +{ + struct lnet_peer_table *ptable = NULL; + + lnet_peer_remove_from_remote_list(lpni); + + /* remove peer ni from the hash list. */ + list_del_init(&lpni->lpni_hashlist); + + /* decrement the ref count on the peer table */ + ptable = the_lnet.ln_peer_tables[lpni->lpni_cpt]; + LASSERT(atomic_read(&ptable->pt_number) > 0); + atomic_dec(&ptable->pt_number); + + /* + * The peer_ni can no longer be found with a lookup. But there + * can be current users, so keep track of it on the zombie + * list until the reference count has gone to zero. + * + * The last reference may be lost in a place where the + * lnet_net_lock locks only a single cpt, and that cpt may not + * be lpni->lpni_cpt. So the zombie list of this peer_table + * has its own lock. + */ + spin_lock(&ptable->pt_zombie_lock); + list_add(&lpni->lpni_hashlist, &ptable->pt_zombie_list); + ptable->pt_zombies++; + spin_unlock(&ptable->pt_zombie_lock); + + /* no need to keep this peer on the hierarchy anymore */ + lnet_try_destroy_peer_hierarchy_locked(lpni); + + /* decrement reference on peer */ + lnet_peer_ni_decref_locked(lpni); +} + +void lnet_peer_uninit(void) +{ + struct lnet_peer_ni *lpni, *tmp; + + lnet_net_lock(LNET_LOCK_EX); + + /* remove all peer_nis from the remote peer and the hash list */ + list_for_each_entry_safe(lpni, tmp, &the_lnet.ln_remote_peer_ni_list, + lpni_on_remote_peer_ni_list) + lnet_peer_ni_del_locked(lpni); + lnet_peer_tables_destroy(); + + lnet_net_unlock(LNET_LOCK_EX); } int @@ -142,6 +296,9 @@ lnet_peer_tables_create(void) return -ENOMEM; } + spin_lock_init(&ptable->pt_zombie_lock); + INIT_LIST_HEAD(&ptable->pt_zombie_list); + for (j = 0; j < LNET_PEER_HASH_SIZE; j++) INIT_LIST_HEAD(&hash[j]); ptable->pt_hash = hash; /* sign of initialization */ @@ -151,34 +308,55 @@ lnet_peer_tables_create(void) } static void -lnet_peer_table_cleanup_locked(struct lnet_ni *ni, +lnet_peer_del_locked(struct lnet_peer *peer) +{ + struct lnet_peer_ni *lpni = NULL, *lpni2; + + lpni = lnet_get_next_peer_ni_locked(peer, NULL, lpni); + while (lpni) { + lpni2 = lnet_get_next_peer_ni_locked(peer, NULL, lpni); + lnet_peer_ni_del_locked(lpni); + lpni = lpni2; + } +} + +static void +lnet_peer_table_cleanup_locked(struct lnet_net *net, struct lnet_peer_table *ptable) { int i; - struct lnet_peer_ni *lp; + struct lnet_peer_ni *lpni; struct lnet_peer_ni *tmp; + struct lnet_peer *peer; for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { - list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], + list_for_each_entry_safe(lpni, tmp, &ptable->pt_hash[i], lpni_hashlist) { - if (ni && ni->ni_net != lp->lpni_net) + if (net && net != lpni->lpni_net) continue; - list_del_init(&lp->lpni_hashlist); - /* Lose hash table's ref */ - ptable->pt_zombies++; - lnet_peer_ni_decref_locked(lp); + + /* + * check if by removing this peer ni we should be + * removing the entire peer. + */ + peer = lpni->lpni_peer_net->lpn_peer; + + if (peer->lp_primary_nid == lpni->lpni_nid) + lnet_peer_del_locked(peer); + else + lnet_peer_ni_del_locked(lpni); } } } static void -lnet_peer_table_finalize_wait_locked(struct lnet_peer_table *ptable, - int cpt_locked) +lnet_peer_ni_finalize_wait(struct lnet_peer_table *ptable) { - int i; + int i = 3; - for (i = 3; ptable->pt_zombies; i++) { - lnet_net_unlock(cpt_locked); + spin_lock(&ptable->pt_zombie_lock); + while (ptable->pt_zombies) { + spin_unlock(&ptable->pt_zombie_lock); if (is_power_of_2(i)) { CDEBUG(D_WARNING, @@ -186,14 +364,14 @@ lnet_peer_table_finalize_wait_locked(struct lnet_peer_table *ptable, ptable->pt_zombies); } schedule_timeout_uninterruptible(HZ >> 1); - lnet_net_lock(cpt_locked); + spin_lock(&ptable->pt_zombie_lock); } + spin_unlock(&ptable->pt_zombie_lock); } static void -lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, - struct lnet_peer_table *ptable, - int cpt_locked) +lnet_peer_table_del_rtrs_locked(struct lnet_net *net, + struct lnet_peer_table *ptable) { struct lnet_peer_ni *lp; struct lnet_peer_ni *tmp; @@ -203,7 +381,7 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], lpni_hashlist) { - if (ni->ni_net != lp->lpni_net) + if (net != lp->lpni_net) continue; if (!lp->lpni_rtr_refcount) @@ -211,27 +389,27 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, lpni_nid = lp->lpni_nid; - lnet_net_unlock(cpt_locked); + lnet_net_unlock(LNET_LOCK_EX); lnet_del_route(LNET_NIDNET(LNET_NID_ANY), lpni_nid); - lnet_net_lock(cpt_locked); + lnet_net_lock(LNET_LOCK_EX); } } } void -lnet_peer_tables_cleanup(struct lnet_ni *ni) +lnet_peer_tables_cleanup(struct lnet_net *net) { struct lnet_peer_table *ptable; int i; - LASSERT(the_lnet.ln_shutdown || ni); + LASSERT(the_lnet.ln_shutdown || net); /* * If just deleting the peers for a NI, get rid of any routes these * peers are gateways for. */ cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { lnet_net_lock(LNET_LOCK_EX); - lnet_peer_table_del_rtrs_locked(ni, ptable, i); + lnet_peer_table_del_rtrs_locked(net, ptable); lnet_net_unlock(LNET_LOCK_EX); } @@ -240,16 +418,12 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) */ cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { lnet_net_lock(LNET_LOCK_EX); - lnet_peer_table_cleanup_locked(ni, ptable); + lnet_peer_table_cleanup_locked(net, ptable); lnet_net_unlock(LNET_LOCK_EX); } - /* Wait until all peers have been destroyed. */ - cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { - lnet_net_lock(LNET_LOCK_EX); - lnet_peer_table_finalize_wait_locked(ptable, i); - lnet_net_unlock(LNET_LOCK_EX); - } + cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) + lnet_peer_ni_finalize_wait(ptable); } static struct lnet_peer_ni * @@ -286,25 +460,23 @@ lnet_find_peer_ni_locked(lnet_nid_t nid) return lpni; } -int -lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt, - struct lnet_peer **peer) +struct lnet_peer * +lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt) { struct lnet_peer_ni *lpni; + struct lnet_peer *lp; lpni = lnet_find_peer_ni_locked(dst_nid); if (!lpni) { - int rc; - - rc = lnet_nid2peerni_locked(&lpni, dst_nid, cpt); - if (rc != 0) - return rc; + lpni = lnet_nid2peerni_locked(dst_nid, cpt); + if (IS_ERR(lpni)) + return ERR_CAST(lpni); } - *peer = lpni->lpni_peer_net->lpn_peer; + lp = lpni->lpni_peer_net->lpn_peer; lnet_peer_ni_decref_locked(lpni); - return 0; + return lp; } struct lnet_peer_ni * @@ -412,269 +584,318 @@ lnet_peer_primary_nid(lnet_nid_t nid) return primary_nid; } -static void -lnet_try_destroy_peer_hierarchy_locked(struct lnet_peer_ni *lpni) +struct lnet_peer_net * +lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id) { struct lnet_peer_net *peer_net; - struct lnet_peer *peer; + list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_on_peer_list) { + if (peer_net->lpn_net_id == net_id) + return peer_net; + } + return NULL; +} - /* TODO: could the below situation happen? accessing an already - * destroyed peer? +static int +lnet_peer_setup_hierarchy(struct lnet_peer *lp, struct lnet_peer_ni + *lpni, + lnet_nid_t nid) +{ + struct lnet_peer_net *lpn = NULL; + struct lnet_peer_table *ptable; + u32 net_id = LNET_NIDNET(nid); + + /* + * Create the peer_ni, peer_net, and peer if they don't exist + * yet. */ - if (!lpni->lpni_peer_net || - !lpni->lpni_peer_net->lpn_peer) - return; + if (lp) { + lpn = lnet_peer_get_net_locked(lp, net_id); + } else { + lp = lnet_peer_alloc(nid); + if (!lp) + goto out_enomem; + } - peer_net = lpni->lpni_peer_net; - peer = lpni->lpni_peer_net->lpn_peer; + if (!lpn) { + lpn = lnet_peer_net_alloc(net_id); + if (!lpn) + goto out_maybe_free_lp; + } - list_del_init(&lpni->lpni_on_peer_net_list); - lpni->lpni_peer_net = NULL; + if (!lpni) { + lpni = lnet_peer_ni_alloc(nid); + if (!lpni) + goto out_maybe_free_lpn; + } - /* if peer_net is empty, then remove it from the peer */ - if (list_empty(&peer_net->lpn_peer_nis)) { - list_del_init(&peer_net->lpn_on_peer_list); - peer_net->lpn_peer = NULL; - kfree(peer_net); + /* Install the new peer_ni */ + lnet_net_lock(LNET_LOCK_EX); + /* Add peer_ni to global peer table hash, if necessary. */ + if (list_empty(&lpni->lpni_hashlist)) { + ptable = the_lnet.ln_peer_tables[lpni->lpni_cpt]; + list_add_tail(&lpni->lpni_hashlist, + &ptable->pt_hash[lnet_nid2peerhash(nid)]); + ptable->pt_version++; + atomic_inc(&ptable->pt_number); + atomic_inc(&lpni->lpni_refcount); + } - /* If the peer is empty then remove it from the - * the_lnet.ln_peers - */ - if (list_empty(&peer->lp_peer_nets)) { - list_del_init(&peer->lp_on_lnet_peer_list); - kfree(peer); - } + /* Detach the peer_ni from an existing peer, if necessary. */ + if (lpni->lpni_peer_net && lpni->lpni_peer_net->lpn_peer != lp) + lnet_try_destroy_peer_hierarchy_locked(lpni); + + /* Add peer_ni to peer_net */ + lpni->lpni_peer_net = lpn; + list_add_tail(&lpni->lpni_on_peer_net_list, &lpn->lpn_peer_nis); + + /* Add peer_net to peer */ + if (!lpn->lpn_peer) { + lpn->lpn_peer = lp; + list_add_tail(&lpn->lpn_on_peer_list, &lp->lp_peer_nets); } + + /* Add peer to global peer list */ + if (list_empty(&lp->lp_on_lnet_peer_list)) + list_add_tail(&lp->lp_on_lnet_peer_list, &the_lnet.ln_peers); + lnet_net_unlock(LNET_LOCK_EX); + + return 0; + +out_maybe_free_lpn: + if (list_empty(&lpn->lpn_on_peer_list)) + kfree(lpn); +out_maybe_free_lp: + if (list_empty(&lp->lp_on_lnet_peer_list)) + kfree(lp); +out_enomem: + return -ENOMEM; } static int -lnet_build_peer_hierarchy(struct lnet_peer_ni *lpni) +lnet_add_prim_lpni(lnet_nid_t nid) { + int rc; struct lnet_peer *peer; - struct lnet_peer_net *peer_net; - __u32 lpni_net = LNET_NIDNET(lpni->lpni_nid); - - peer = NULL; - peer_net = NULL; + struct lnet_peer_ni *lpni; - peer = kzalloc(sizeof(*peer), GFP_KERNEL); - if (!peer) - return -ENOMEM; + LASSERT(nid != LNET_NID_ANY); - peer_net = kzalloc(sizeof(*peer_net), GFP_KERNEL); - if (!peer_net) { - kfree(peer); - return -ENOMEM; + /* + * lookup the NID and its peer + * if the peer doesn't exist, create it. + * if this is a non-MR peer then change its state to MR and exit. + * if this is an MR peer and it's a primary NI: NO-OP. + * if this is an MR peer and it's not a primary NI. Operation not + * allowed. + * + * The adding and deleting of peer nis is being serialized through + * the api_mutex. So we can look up peers with the mutex locked + * safely. Only when we need to change the ptable, do we need to + * exclusively lock the lnet_net_lock() + */ + lpni = lnet_find_peer_ni_locked(nid); + if (!lpni) { + rc = lnet_peer_setup_hierarchy(NULL, NULL, nid); + if (rc != 0) + return rc; + lpni = lnet_find_peer_ni_locked(nid); } - INIT_LIST_HEAD(&peer->lp_on_lnet_peer_list); - INIT_LIST_HEAD(&peer->lp_peer_nets); - INIT_LIST_HEAD(&peer_net->lpn_on_peer_list); - INIT_LIST_HEAD(&peer_net->lpn_peer_nis); + LASSERT(lpni); - /* build the hierarchy */ - peer_net->lpn_net_id = lpni_net; - peer_net->lpn_peer = peer; - lpni->lpni_peer_net = peer_net; - peer->lp_primary_nid = lpni->lpni_nid; - peer->lp_multi_rail = false; - list_add_tail(&peer_net->lpn_on_peer_list, &peer->lp_peer_nets); - list_add_tail(&lpni->lpni_on_peer_net_list, &peer_net->lpn_peer_nis); - list_add_tail(&peer->lp_on_lnet_peer_list, &the_lnet.ln_peers); + lnet_peer_ni_decref_locked(lpni); - return 0; -} + peer = lpni->lpni_peer_net->lpn_peer; -struct lnet_peer_net * -lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id) -{ - struct lnet_peer_net *peer_net; + /* + * If we found a lpni with the same nid as the NID we're trying to + * create, then we're trying to create an already existing lpni + * that belongs to a different peer + */ + if (peer->lp_primary_nid != nid) + return -EEXIST; - list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_on_peer_list) { - if (peer_net->lpn_net_id == net_id) - return peer_net; - } - return NULL; + /* + * if we found an lpni that is not a multi-rail, which could occur + * if lpni is already created as a non-mr lpni or we just created + * it, then make sure you indicate that this lpni is a primary mr + * capable peer. + * + * TODO: update flags if necessary + */ + if (!peer->lp_multi_rail && peer->lp_primary_nid == nid) + peer->lp_multi_rail = true; + + return rc; } -/* - * given the key nid find the peer to add the new peer NID to. If the key - * nid is NULL, then create a new peer, but first make sure that the NID - * is unique - */ -int -lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr) +static int +lnet_add_peer_ni_to_prim_lpni(lnet_nid_t key_nid, lnet_nid_t nid) { - struct lnet_peer_ni *lpni, *lpni2; - struct lnet_peer *peer; - struct lnet_peer_net *peer_net, *pn; - int cpt, cpt2, rc; - struct lnet_peer_table *ptable = NULL; - __u32 net_id = LNET_NIDNET(nid); + struct lnet_peer *peer, *primary_peer; + struct lnet_peer_ni *lpni = NULL, *klpni = NULL; - if (nid == LNET_NID_ANY) - return -EINVAL; + LASSERT(key_nid != LNET_NID_ANY && nid != LNET_NID_ANY); + + /* + * key nid must be created by this point. If not then this + * operation is not permitted + */ + klpni = lnet_find_peer_ni_locked(key_nid); + if (!klpni) + return -ENOENT; + + lnet_peer_ni_decref_locked(klpni); + + primary_peer = klpni->lpni_peer_net->lpn_peer; - /* check that nid is unique */ - cpt = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); - lnet_net_lock(cpt); lpni = lnet_find_peer_ni_locked(nid); if (lpni) { lnet_peer_ni_decref_locked(lpni); - lnet_net_unlock(cpt); - return -EEXIST; - } - lnet_net_unlock(cpt); - if (key_nid != LNET_NID_ANY) { - cpt2 = lnet_nid_cpt_hash(key_nid, LNET_CPT_NUMBER); - lnet_net_lock(cpt2); - lpni = lnet_find_peer_ni_locked(key_nid); - if (!lpni) { - lnet_net_unlock(cpt2); - /* key_nid refers to a non-existent peer_ni.*/ - return -EINVAL; - } peer = lpni->lpni_peer_net->lpn_peer; - peer->lp_multi_rail = mr; - lnet_peer_ni_decref_locked(lpni); - lnet_net_unlock(cpt2); - } else { - lnet_net_lock(LNET_LOCK_EX); - rc = lnet_nid2peerni_locked(&lpni, nid, LNET_LOCK_EX); - if (rc == 0) { - lpni->lpni_peer_net->lpn_peer->lp_multi_rail = mr; - lnet_peer_ni_decref_locked(lpni); + /* + * lpni already exists in the system but it belongs to + * a different peer. We can't re-added it + */ + if (peer->lp_primary_nid != key_nid && peer->lp_multi_rail) { + CERROR("Cannot add NID %s owned by peer %s to peer %s\n", + libcfs_nid2str(lpni->lpni_nid), + libcfs_nid2str(peer->lp_primary_nid), + libcfs_nid2str(key_nid)); + return -EEXIST; + } else if (peer->lp_primary_nid == key_nid) { + /* + * found a peer_ni that is already part of the + * peer. This is a no-op operation. + */ + return 0; } - lnet_net_unlock(LNET_LOCK_EX); - return rc; - } - - lpni = kzalloc_cpt(sizeof(*lpni), GFP_KERNEL, cpt); - if (!lpni) - return -ENOMEM; - INIT_LIST_HEAD(&lpni->lpni_txq); - INIT_LIST_HEAD(&lpni->lpni_rtrq); - INIT_LIST_HEAD(&lpni->lpni_routes); - INIT_LIST_HEAD(&lpni->lpni_hashlist); - INIT_LIST_HEAD(&lpni->lpni_on_peer_net_list); - INIT_LIST_HEAD(&lpni->lpni_on_remote_peer_ni_list); + /* + * TODO: else if (peer->lp_primary_nid != key_nid && + * !peer->lp_multi_rail) + * peer is not an MR peer and it will be moved in the next + * step to klpni, so update its flags accordingly. + * lnet_move_peer_ni() + */ - lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ - lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ - lpni->lpni_ping_feats = LNET_PING_FEAT_INVAL; - lpni->lpni_nid = nid; - lpni->lpni_cpt = cpt; - lnet_set_peer_ni_health_locked(lpni, true); + /* + * TODO: call lnet_update_peer() from here to update the + * flags. This is the case when the lpni you're trying to + * add is already part of the peer. This could've been + * added by the DD previously, so go ahead and do any + * updates to the state if necessary + */ - /* allocate here in case we need to add a new peer_net */ - peer_net = NULL; - peer_net = kzalloc(sizeof(*peer_net), GFP_KERNEL); - if (!peer_net) { - rc = -ENOMEM; - kfree(lpni); - return rc; } - lnet_net_lock(LNET_LOCK_EX); + /* + * When we get here we either have found an existing lpni, which + * we can switch to the new peer. Or we need to create one and + * add it to the new peer + */ + return lnet_peer_setup_hierarchy(primary_peer, lpni, nid); +} - ptable = the_lnet.ln_peer_tables[cpt]; - ptable->pt_number++; - - lpni2 = lnet_find_peer_ni_locked(nid); - if (lpni2) { - lnet_peer_ni_decref_locked(lpni2); - /* sanity check that lpni2's peer is what we expect */ - if (lpni2->lpni_peer_net->lpn_peer != peer) - rc = -EEXIST; - else - rc = -EINVAL; - - ptable->pt_number--; - /* another thread has already added it */ - lnet_net_unlock(LNET_LOCK_EX); - kfree(peer_net); - return rc; - } +/* + * lpni creation initiated due to traffic either sending or receiving. + */ +static int +lnet_peer_ni_traffic_add(lnet_nid_t nid) +{ + struct lnet_peer_ni *lpni; + int rc = 0; - lpni->lpni_net = lnet_get_net_locked(LNET_NIDNET(lpni->lpni_nid)); - if (lpni->lpni_net) { - lpni->lpni_txcredits = - lpni->lpni_mintxcredits = - lpni->lpni_net->net_tunables.lct_peer_tx_credits; - lpni->lpni_rtrcredits = - lpni->lpni_minrtrcredits = - lnet_peer_buffer_credits(lpni->lpni_net); - } else { + if (nid == LNET_NID_ANY) + return -EINVAL; + + /* lnet_net_lock is not needed here because ln_api_lock is held */ + lpni = lnet_find_peer_ni_locked(nid); + if (lpni) { /* - * if you're adding a peer which is not on a local network - * then we can't assign any of the credits. It won't be - * picked for sending anyway. Eventually a network can be - * added, in this case we need to revisit this peer and - * update its credits. + * TODO: lnet_update_primary_nid() but not all of it + * only indicate if we're converting this to MR capable + * Can happen due to DD */ - - /* increment refcount for remote peer list */ - atomic_inc(&lpni->lpni_refcount); - list_add_tail(&lpni->lpni_on_remote_peer_ni_list, - &the_lnet.ln_remote_peer_ni_list); + lnet_peer_ni_decref_locked(lpni); + } else { + rc = lnet_peer_setup_hierarchy(NULL, NULL, nid); } - /* increment refcount for peer on hash list */ - atomic_inc(&lpni->lpni_refcount); + return rc; +} - list_add_tail(&lpni->lpni_hashlist, - &ptable->pt_hash[lnet_nid2peerhash(nid)]); - ptable->pt_version++; +static int +lnet_peer_ni_add_non_mr(lnet_nid_t nid) +{ + struct lnet_peer_ni *lpni; - /* add the lpni to a net */ - list_for_each_entry(pn, &peer->lp_peer_nets, lpn_on_peer_list) { - if (pn->lpn_net_id == net_id) { - list_add_tail(&lpni->lpni_on_peer_net_list, - &pn->lpn_peer_nis); - lpni->lpni_peer_net = pn; - lnet_net_unlock(LNET_LOCK_EX); - kfree(peer_net); - return 0; - } + lpni = lnet_find_peer_ni_locked(nid); + if (lpni) { + CERROR("Cannot add %s as non-mr when it already exists\n", + libcfs_nid2str(nid)); + lnet_peer_ni_decref_locked(lpni); + return -EEXIST; } - INIT_LIST_HEAD(&peer_net->lpn_on_peer_list); - INIT_LIST_HEAD(&peer_net->lpn_peer_nis); + return lnet_peer_setup_hierarchy(NULL, NULL, nid); +} - /* build the hierarchy */ - peer_net->lpn_net_id = net_id; - peer_net->lpn_peer = peer; - lpni->lpni_peer_net = peer_net; - list_add_tail(&lpni->lpni_on_peer_net_list, &peer_net->lpn_peer_nis); - list_add_tail(&peer_net->lpn_on_peer_list, &peer->lp_peer_nets); +/* + * This API handles the following combinations: + * Create a primary NI if only the key_nid is provided + * Create or add an lpni to a primary NI. Primary NI must've already + * been created + * Create a non-MR peer. + */ +int +lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr) +{ + /* + * Caller trying to setup an MR like peer hierarchy but + * specifying it to be non-MR. This is not allowed. + */ + if (key_nid != LNET_NID_ANY && + nid != LNET_NID_ANY && !mr) + return -EPERM; + + /* Add the primary NID of a peer */ + if (key_nid != LNET_NID_ANY && + nid == LNET_NID_ANY && mr) + return lnet_add_prim_lpni(key_nid); + + /* Add a NID to an existing peer */ + if (key_nid != LNET_NID_ANY && + nid != LNET_NID_ANY && mr) + return lnet_add_peer_ni_to_prim_lpni(key_nid, nid); + + /* Add a non-MR peer NI */ + if (((key_nid != LNET_NID_ANY && + nid == LNET_NID_ANY) || + (key_nid == LNET_NID_ANY && + nid != LNET_NID_ANY)) && !mr) + return lnet_peer_ni_add_non_mr(key_nid != LNET_NID_ANY ? + key_nid : nid); - lnet_net_unlock(LNET_LOCK_EX); return 0; } int lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid) { - int cpt; lnet_nid_t local_nid; struct lnet_peer *peer; - struct lnet_peer_ni *lpni, *lpni2; - struct lnet_peer_table *ptable = NULL; + struct lnet_peer_ni *lpni; if (key_nid == LNET_NID_ANY) return -EINVAL; local_nid = (nid != LNET_NID_ANY) ? nid : key_nid; - cpt = lnet_nid_cpt_hash(local_nid, LNET_CPT_NUMBER); - lnet_net_lock(LNET_LOCK_EX); lpni = lnet_find_peer_ni_locked(local_nid); - if (!lpni) { - lnet_net_unlock(cpt); + if (!lpni) return -EINVAL; - } lnet_peer_ni_decref_locked(lpni); peer = lpni->lpni_peer_net->lpn_peer; @@ -685,30 +906,15 @@ lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid) * deleting the primary ni is equivalent to deleting the * entire peer */ - lpni = NULL; - lpni = lnet_get_next_peer_ni_locked(peer, NULL, lpni); - while (lpni) { - lpni2 = lnet_get_next_peer_ni_locked(peer, NULL, lpni); - cpt = lnet_nid_cpt_hash(lpni->lpni_nid, - LNET_CPT_NUMBER); - lnet_peer_remove_from_remote_list(lpni); - ptable = the_lnet.ln_peer_tables[cpt]; - ptable->pt_zombies++; - list_del_init(&lpni->lpni_hashlist); - lnet_peer_ni_decref_locked(lpni); - lpni = lpni2; - } + lnet_net_lock(LNET_LOCK_EX); + lnet_peer_del_locked(peer); lnet_net_unlock(LNET_LOCK_EX); return 0; } - lnet_peer_remove_from_remote_list(lpni); - cpt = lnet_nid_cpt_hash(lpni->lpni_nid, LNET_CPT_NUMBER); - ptable = the_lnet.ln_peer_tables[cpt]; - ptable->pt_zombies++; - list_del_init(&lpni->lpni_hashlist); - lnet_peer_ni_decref_locked(lpni); + lnet_net_lock(LNET_LOCK_EX); + lnet_peer_ni_del_locked(lpni); lnet_net_unlock(LNET_LOCK_EX); return 0; @@ -722,159 +928,70 @@ lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lpni) LASSERT(atomic_read(&lpni->lpni_refcount) == 0); LASSERT(lpni->lpni_rtr_refcount == 0); LASSERT(list_empty(&lpni->lpni_txq)); - LASSERT(list_empty(&lpni->lpni_hashlist)); LASSERT(lpni->lpni_txqnob == 0); - LASSERT(lpni->lpni_peer_net); - LASSERT(lpni->lpni_peer_net->lpn_peer); - - ptable = the_lnet.ln_peer_tables[lpni->lpni_cpt]; - LASSERT(ptable->pt_number > 0); - ptable->pt_number--; lpni->lpni_net = NULL; - lnet_try_destroy_peer_hierarchy_locked(lpni); + /* remove the peer ni from the zombie list */ + ptable = the_lnet.ln_peer_tables[lpni->lpni_cpt]; + spin_lock(&ptable->pt_zombie_lock); + list_del_init(&lpni->lpni_hashlist); + ptable->pt_zombies--; + spin_unlock(&ptable->pt_zombie_lock); kfree(lpni); - - LASSERT(ptable->pt_zombies > 0); - ptable->pt_zombies--; } -int -lnet_nid2peerni_locked(struct lnet_peer_ni **lpnip, lnet_nid_t nid, int cpt) +struct lnet_peer_ni * +lnet_nid2peerni_locked(lnet_nid_t nid, int cpt) { struct lnet_peer_table *ptable; struct lnet_peer_ni *lpni = NULL; - struct lnet_peer_ni *lpni2; int cpt2; - int rc = 0; + int rc; - *lpnip = NULL; if (the_lnet.ln_shutdown) /* it's shutting down */ - return -ESHUTDOWN; + return ERR_PTR(-ESHUTDOWN); /* * calculate cpt2 with the standard hash function - * This cpt2 becomes the slot where we'll find or create the peer. + * This cpt2 is the slot where we'll find or create the peer. */ cpt2 = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); - - /* - * Any changes to the peer tables happen under exclusive write - * lock. Any reads to the peer tables can be done via a standard - * CPT read lock. - */ - if (cpt != LNET_LOCK_EX) { - lnet_net_unlock(cpt); - lnet_net_lock(LNET_LOCK_EX); - } - ptable = the_lnet.ln_peer_tables[cpt2]; lpni = lnet_get_peer_ni_locked(ptable, nid); - if (lpni) { - *lpnip = lpni; - if (cpt != LNET_LOCK_EX) { - lnet_net_unlock(LNET_LOCK_EX); - lnet_net_lock(cpt); - } - return 0; - } + if (lpni) + return lpni; + /* Slow path: serialized using the ln_api_mutex. */ + lnet_net_unlock(cpt); + mutex_lock(&the_lnet.ln_api_mutex); /* - * take extra refcount in case another thread has shutdown LNet - * and destroyed locks and peer-table before I finish the allocation + * Shutdown is only set under the ln_api_lock, so a single + * check here is sufficent. + * + * lnet_add_nid_to_peer() also handles the case where we've + * raced and a different thread added the NID. */ - ptable->pt_number++; - lnet_net_unlock(LNET_LOCK_EX); - - lpni = kzalloc_cpt(sizeof(*lpni), GFP_KERNEL, cpt2); - if (!lpni) { - rc = -ENOMEM; - lnet_net_lock(cpt); - goto out; - } - - INIT_LIST_HEAD(&lpni->lpni_txq); - INIT_LIST_HEAD(&lpni->lpni_rtrq); - INIT_LIST_HEAD(&lpni->lpni_routes); - INIT_LIST_HEAD(&lpni->lpni_hashlist); - INIT_LIST_HEAD(&lpni->lpni_on_peer_net_list); - INIT_LIST_HEAD(&lpni->lpni_on_remote_peer_ni_list); - - lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ - lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ - lpni->lpni_ping_feats = LNET_PING_FEAT_INVAL; - lpni->lpni_nid = nid; - lpni->lpni_cpt = cpt2; - atomic_set(&lpni->lpni_refcount, 2); /* 1 for caller; 1 for hash */ - - rc = lnet_build_peer_hierarchy(lpni); - if (rc != 0) - goto out; - - lnet_net_lock(LNET_LOCK_EX); - if (the_lnet.ln_shutdown) { - rc = -ESHUTDOWN; - goto out; - } - - lpni2 = lnet_get_peer_ni_locked(ptable, nid); - if (lpni2) { - *lpnip = lpni2; - goto out; + lpni = ERR_PTR(-ESHUTDOWN); + goto out_mutex_unlock; } - lpni->lpni_net = lnet_get_net_locked(LNET_NIDNET(lpni->lpni_nid)); - if (lpni->lpni_net) { - lpni->lpni_txcredits = - lpni->lpni_mintxcredits = - lpni->lpni_net->net_tunables.lct_peer_tx_credits; - lpni->lpni_rtrcredits = - lpni->lpni_minrtrcredits = - lnet_peer_buffer_credits(lpni->lpni_net); - } else { - /* - * if you're adding a peer which is not on a local network - * then we can't assign any of the credits. It won't be - * picked for sending anyway. Eventually a network can be - * added, in this case we need to revisit this peer and - * update its credits. - */ - - CDEBUG(D_NET, "peer_ni %s is not directly connected\n", - libcfs_nid2str(nid)); - /* increment refcount for remote peer list */ - atomic_inc(&lpni->lpni_refcount); - list_add_tail(&lpni->lpni_on_remote_peer_ni_list, - &the_lnet.ln_remote_peer_ni_list); + rc = lnet_peer_ni_traffic_add(nid); + if (rc) { + lpni = ERR_PTR(rc); + goto out_mutex_unlock; } - lnet_set_peer_ni_health_locked(lpni, true); - - list_add_tail(&lpni->lpni_hashlist, - &ptable->pt_hash[lnet_nid2peerhash(nid)]); - ptable->pt_version++; - *lpnip = lpni; + lpni = lnet_get_peer_ni_locked(ptable, nid); + LASSERT(lpni); - if (cpt != LNET_LOCK_EX) { - lnet_net_unlock(LNET_LOCK_EX); - lnet_net_lock(cpt); - } +out_mutex_unlock: + mutex_unlock(&the_lnet.ln_api_mutex); + lnet_net_lock(cpt); - return 0; -out: - if (lpni) { - lnet_try_destroy_peer_hierarchy_locked(lpni); - kfree(lpni); - } - ptable->pt_number--; - if (cpt != LNET_LOCK_EX) { - lnet_net_unlock(LNET_LOCK_EX); - lnet_net_lock(cpt); - } - return rc; + return lpni; } void @@ -882,14 +999,13 @@ lnet_debug_peer(lnet_nid_t nid) { char *aliveness = "NA"; struct lnet_peer_ni *lp; - int rc; int cpt; cpt = lnet_cpt_of_nid(nid, NULL); lnet_net_lock(cpt); - rc = lnet_nid2peerni_locked(&lp, nid, cpt); - if (rc) { + lp = lnet_nid2peerni_locked(nid, cpt); + if (IS_ERR(lp)) { lnet_net_unlock(cpt); CDEBUG(D_WARNING, "No peer %s\n", libcfs_nid2str(nid)); return; @@ -973,7 +1089,7 @@ lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, } int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, - struct lnet_peer_ni_credit_info *peer_ni_info, + bool *mr, struct lnet_peer_ni_credit_info *peer_ni_info, struct lnet_ioctl_element_stats *peer_ni_stats) { struct lnet_peer_ni *lpni = NULL; @@ -986,6 +1102,7 @@ int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, return -ENOENT; *primary_nid = lp->lp_primary_nid; + *mr = lp->lp_multi_rail; *nid = lpni->lpni_nid; snprintf(peer_ni_info->cr_aliveness, LNET_MAX_STR_LEN, "NA"); if (lnet_isrouter(lpni) || diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 7913914620f3..1c79a19f5a25 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -296,6 +296,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, struct lnet_route *route; struct lnet_route *route2; struct lnet_ni *ni; + struct lnet_peer_ni *lpni; int add_route; int rc; @@ -332,13 +333,14 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, lnet_net_lock(LNET_LOCK_EX); - rc = lnet_nid2peerni_locked(&route->lr_gateway, gateway, LNET_LOCK_EX); - if (rc) { + lpni = lnet_nid2peerni_locked(gateway, LNET_LOCK_EX); + if (IS_ERR(lpni)) { lnet_net_unlock(LNET_LOCK_EX); kfree(route); kfree(rnet); + rc = PTR_ERR(lpni); if (rc == -EHOSTUNREACH) /* gateway is not on a local net */ return rc; /* ignore the route entry */ CERROR("Error %d creating route %s %d %s\n", rc, @@ -346,7 +348,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, libcfs_nid2str(gateway)); return rc; } - + route->lr_gateway = lpni; LASSERT(!the_lnet.ln_shutdown); rnet2 = lnet_find_rnet_locked(net); From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 19/34] LU-7734 lnet: proper cpt locking In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763561.32103.4423090846180857161.stgit@noble> From: Amir Shehata 1. add a per NI credits, which is just the total credits assigned on NI creation 2. Whenever percpt credits are added or decremented, we mirror that in the NI credits 3. We use the NI credits to determine best NI 4. After we have completed the peer_ni/ni selection we determine the cpt to use for locking: cpt_of_nid(lpni->nid, ni) The lpni_cpt is not enough to protect all the fields in the lnet_peer_ni structure. This is due to the fact that multiple NIs can talk to the same peer, and functions can be called with different cpts locked. To properly protect the fields in the lnet_peer_ni structure, a spin lock is introduced for the purpose. Signed-off-by: Amir Shehata Change-Id: Ief7868c3c8ff7e00ea9e908dd50d8cef77d9f9a4 Reviewed-on: http://review.whamcloud.com/20701 Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 15 +++-- drivers/staging/lustre/lnet/lnet/api-ni.c | 3 + drivers/staging/lustre/lnet/lnet/lib-move.c | 58 ++++++++++++------ drivers/staging/lustre/lnet/lnet/peer.c | 2 + drivers/staging/lustre/lnet/lnet/router.c | 63 +++++++++++++++++++- 5 files changed, 113 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 71ec0eaf8200..90a5c6e40dea 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -330,6 +330,9 @@ struct lnet_ni { /* instance-specific data */ void *ni_data; + /* per ni credits */ + atomic_t ni_tx_credits; + /* percpt TX queues */ struct lnet_tx_queue **ni_tx_queues; @@ -414,6 +417,8 @@ struct lnet_peer_ni { struct list_head lpni_rtr_list; /* statistics kept on each peer NI */ struct lnet_element_stats lpni_stats; + /* spin lock protecting credits and lpni_txq / lpni_rtrq */ + spinlock_t lpni_lock; /* # tx credits available */ int lpni_txcredits; struct lnet_peer_net *lpni_peer_net; @@ -424,13 +429,13 @@ struct lnet_peer_ni { /* low water mark */ int lpni_minrtrcredits; /* alive/dead? */ - unsigned int lpni_alive:1; + bool lpni_alive; /* notification outstanding? */ - unsigned int lpni_notify:1; + bool lpni_notify; /* outstanding notification for LND? */ - unsigned int lpni_notifylnd:1; + bool lpni_notifylnd; /* some thread is handling notification */ - unsigned int lpni_notifying:1; + bool lpni_notifying; /* SEND event outstanding from ping */ unsigned int lpni_ping_notsent; /* # times router went dead<->alive */ @@ -461,7 +466,7 @@ struct lnet_peer_ni { u32 lpni_seq; /* health flag */ bool lpni_healthy; - /* returned RC ping features */ + /* returned RC ping features. Protected with lpni_lock */ unsigned int lpni_ping_feats; /* routers on this peer */ struct list_head lpni_routes; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index d3db4853c690..9807cfb3a0fc 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1382,6 +1382,9 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun) seed = LNET_NIDADDR(ni->ni_nid); add_device_randomness(&seed, sizeof(seed)); + atomic_set(&ni->ni_tx_credits, + lnet_ni_tq_credits(ni) * ni->ni_ncpts); + CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n", libcfs_nid2str(ni->ni_nid), ni->ni_net->net_tunables.lct_peer_tx_credits, diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 5d9acce26287..51224a4cb218 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -488,18 +488,26 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) return rc; } -/* NB: caller shall hold a ref on 'lp' as I'd drop lnet_net_lock */ +/* + * This function can be called from two paths: + * 1. when sending a message + * 2. when decommiting a message (lnet_msg_decommit_tx()) + * In both these cases the peer_ni should have it's reference count + * acquired by the caller and therefore it is safe to drop the spin + * lock before calling lnd_query() + */ static void lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) { time64_t last_alive = 0; + int cpt = lnet_cpt_of_nid_locked(lp->lpni_nid, ni); LASSERT(lnet_peer_aliveness_enabled(lp)); LASSERT(ni->ni_net->net_lnd->lnd_query); - lnet_net_unlock(lp->lpni_cpt); + lnet_net_unlock(cpt); ni->ni_net->net_lnd->lnd_query(ni, lp->lpni_nid, &last_alive); - lnet_net_lock(lp->lpni_cpt); + lnet_net_lock(cpt); lp->lpni_last_query = ktime_get_seconds(); @@ -519,9 +527,12 @@ lnet_peer_is_alive(struct lnet_peer_ni *lp, unsigned long now) /* Trust lnet_notify() if it has more recent aliveness news, but * ignore the initial assumed death (see lnet_peers_start_down()). */ + spin_lock(&lp->lpni_lock); if (!lp->lpni_alive && lp->lpni_alive_count > 0 && - lp->lpni_timestamp >= lp->lpni_last_alive) + lp->lpni_timestamp >= lp->lpni_last_alive) { + spin_unlock(&lp->lpni_lock); return 0; + } deadline = lp->lpni_last_alive + lp->lpni_net->net_tunables.lct_peer_timeout; @@ -532,8 +543,12 @@ lnet_peer_is_alive(struct lnet_peer_ni *lp, unsigned long now) * case, and moreover lpni_last_alive at peer creation is assumed. */ if (alive && !lp->lpni_alive && - !(lnet_isrouter(lp) && !lp->lpni_alive_count)) + !(lnet_isrouter(lp) && !lp->lpni_alive_count)) { + spin_unlock(&lp->lpni_lock); lnet_notify_locked(lp, 0, 1, lp->lpni_last_alive); + } else { + spin_unlock(&lp->lpni_lock); + } return alive; } @@ -665,6 +680,7 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) msg->msg_txcredit = 1; tq->tq_credits--; + atomic_dec(&ni->ni_tx_credits); if (tq->tq_credits < tq->tq_credits_min) tq->tq_credits_min = tq->tq_credits; @@ -798,6 +814,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) !list_empty(&tq->tq_delayed)); tq->tq_credits++; + atomic_inc(&ni->ni_tx_credits); if (tq->tq_credits <= 0) { msg2 = list_entry(tq->tq_delayed.next, struct lnet_msg, msg_list); @@ -1271,9 +1288,13 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * 3. Round Robin */ while ((ni = lnet_get_next_ni_locked(local_net, ni))) { + int ni_credits; + if (!lnet_is_ni_healthy_locked(ni)) continue; + ni_credits = atomic_read(&ni->ni_tx_credits); + /* * calculate the distance from the cpt on which * the message memory is allocated to the CPT of @@ -1349,11 +1370,9 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * select using credits followed by Round * Robin. */ - if (ni->ni_tx_queues[cpt]->tq_credits < - best_credits) { + if (ni_credits < best_credits) { continue; - } else if (ni->ni_tx_queues[cpt]->tq_credits == - best_credits) { + } else if (ni_credits == best_credits) { if (best_ni && best_ni->ni_seq <= ni->ni_seq) continue; @@ -1361,7 +1380,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, } set_ni: best_ni = ni; - best_credits = ni->ni_tx_queues[cpt]->tq_credits; + best_credits = ni_credits; } } /* @@ -1539,13 +1558,15 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, send: /* - * determine the cpt to use and if it has changed then - * lock the new cpt and check if the config has changed. - * If it has changed then repeat the algorithm since the - * ni or peer list could have changed and the algorithm - * would endup picking a different ni/peer_ni pair. + * Use lnet_cpt_of_nid() to determine the CPT used to commit the + * message. This ensures that we get a CPT that is correct for + * the NI when the NI has been restricted to a subset of all CPTs. + * If the selected CPT differs from the one currently locked, we + * must unlock and relock the lnet_net_lock(), and then check whether + * the configuration has changed. We don't have a hold on the best_ni + * or best_peer_ni yet, and they may have vanished. */ - cpt2 = best_lpni->lpni_cpt; + cpt2 = lnet_cpt_of_nid_locked(best_lpni->lpni_nid, best_ni); if (cpt != cpt2) { lnet_net_unlock(cpt); cpt = cpt2; @@ -1699,7 +1720,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) info.mi_rlength = hdr->payload_length; info.mi_roffset = hdr->msg.put.offset; info.mi_mbits = hdr->msg.put.match_bits; - info.mi_cpt = msg->msg_rxpeer->lpni_cpt; + info.mi_cpt = lnet_cpt_of_nid(msg->msg_rxpeer->lpni_nid, ni); msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; ready_delay = msg->msg_rx_ready_delay; @@ -2326,8 +2347,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) * called lnet_drop_message(), so I just hang onto msg as well * until that's done */ - lnet_drop_message(msg->msg_rxni, - msg->msg_rxpeer->lpni_cpt, + lnet_drop_message(msg->msg_rxni, msg->msg_rx_cpt, msg->msg_private, msg->msg_len); /* * NB: message will not generate event because w/o attached MD, diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index c2a04526a59a..dc4527f86113 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -117,6 +117,8 @@ lnet_peer_ni_alloc(lnet_nid_t nid) INIT_LIST_HEAD(&lpni->lpni_on_peer_net_list); INIT_LIST_HEAD(&lpni->lpni_on_remote_peer_ni_list); + spin_lock_init(&lpni->lpni_lock); + lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ lpni->lpni_ping_feats = LNET_PING_FEAT_INVAL; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 1c79a19f5a25..d3c41f5664a4 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -108,11 +108,20 @@ lnet_notify_locked(struct lnet_peer_ni *lp, int notifylnd, int alive, return; } + /* + * This function can be called with different cpt locks being + * held. lpni_alive_count modification needs to be properly protected. + * Significant reads to lpni_alive_count are also protected with + * the same lock + */ + spin_lock(&lp->lpni_lock); + lp->lpni_timestamp = when; /* update timestamp */ lp->lpni_ping_deadline = 0; /* disable ping timeout */ if (lp->lpni_alive_count && /* got old news */ (!lp->lpni_alive) == (!alive)) { /* new date for old news */ + spin_unlock(&lp->lpni_lock); CDEBUG(D_NET, "Old news\n"); return; } @@ -120,15 +129,20 @@ lnet_notify_locked(struct lnet_peer_ni *lp, int notifylnd, int alive, /* Flag that notification is outstanding */ lp->lpni_alive_count++; - lp->lpni_alive = !(!alive); /* 1 bit! */ + lp->lpni_alive = !!alive; /* 1 bit! */ lp->lpni_notify = 1; - lp->lpni_notifylnd |= notifylnd; + lp->lpni_notifylnd = notifylnd; if (lp->lpni_alive) lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; /* reset */ + spin_unlock(&lp->lpni_lock); + CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lpni_nid), alive); } +/* + * This function will always be called with lp->lpni_cpt lock held. + */ static void lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) { @@ -140,11 +154,19 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) * NB individual events can be missed; the only guarantee is that you * always get the most recent news */ - if (lp->lpni_notifying || !ni) + spin_lock(&lp->lpni_lock); + + if (lp->lpni_notifying || !ni) { + spin_unlock(&lp->lpni_lock); return; + } lp->lpni_notifying = 1; + /* + * lp->lpni_notify needs to be protected because it can be set in + * lnet_notify_locked(). + */ while (lp->lpni_notify) { alive = lp->lpni_alive; notifylnd = lp->lpni_notifylnd; @@ -153,6 +175,7 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) lp->lpni_notify = 0; if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { + spin_unlock(&lp->lpni_lock); lnet_net_unlock(lp->lpni_cpt); /* @@ -163,10 +186,12 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) alive); lnet_net_lock(lp->lpni_cpt); + spin_lock(&lp->lpni_lock); } } lp->lpni_notifying = 0; + spin_unlock(&lp->lpni_lock); } static void @@ -623,6 +648,12 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) if (!gw->lpni_alive) return; + /* + * Protect gw->lpni_ping_feats. This can be set from + * lnet_notify_locked with different locks being held + */ + spin_lock(&gw->lpni_lock); + if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) lnet_swap_pinginfo(info); @@ -631,6 +662,7 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) CDEBUG(D_NET, "%s: Unexpected magic %08x\n", libcfs_nid2str(gw->lpni_nid), info->pi_magic); gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; + spin_unlock(&gw->lpni_lock); return; } @@ -638,11 +670,14 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) if (!(gw->lpni_ping_feats & LNET_PING_FEAT_MASK)) { CDEBUG(D_NET, "%s: Unexpected features 0x%x\n", libcfs_nid2str(gw->lpni_nid), gw->lpni_ping_feats); + spin_unlock(&gw->lpni_lock); return; /* nothing I can understand */ } - if (!(gw->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS)) + if (!(gw->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS)) { + spin_unlock(&gw->lpni_lock); return; /* can't carry NI status info */ + } list_for_each_entry(rte, &gw->lpni_routes, lr_gwlist) { int down = 0; @@ -662,6 +697,7 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) CDEBUG(D_NET, "%s: unexpected LNET_NID_ANY\n", libcfs_nid2str(gw->lpni_nid)); gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; + spin_unlock(&gw->lpni_lock); return; } @@ -684,6 +720,7 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) CDEBUG(D_NET, "%s: Unexpected status 0x%x\n", libcfs_nid2str(gw->lpni_nid), stat->ns_status); gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; + spin_unlock(&gw->lpni_lock); return; } @@ -700,6 +737,8 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) rte->lr_downis = down; } + + spin_unlock(&gw->lpni_lock); } static void @@ -773,10 +812,14 @@ lnet_wait_known_routerstate(void) all_known = 1; list_for_each_entry(rtr, &the_lnet.ln_routers, lpni_rtr_list) { + spin_lock(&rtr->lpni_lock); + if (!rtr->lpni_alive_count) { all_known = 0; + spin_unlock(&rtr->lpni_lock); break; } + spin_unlock(&rtr->lpni_lock); } lnet_net_unlock(cpt); @@ -1744,6 +1787,18 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) return 0; } + /* + * It is possible for this function to be called for the same peer + * but with different NIs. We want to synchronize the notification + * between the different calls. So we will use the lpni_cpt to + * grab the net lock. + */ + if (lp->lpni_cpt != cpt) { + lnet_net_unlock(cpt); + cpt = lp->lpni_cpt; + lnet_net_lock(cpt); + } + /* * We can't fully trust LND on reporting exact peer last_alive * if he notifies us about dead peer. For example ksocklnd can From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 20/34] LU-7734 lnet: protect peer_ni credits In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763565.32103.14024172070634950028.stgit@noble> From: Amir Shehata Currently multiple NIs can talk to the same peer_ni. The per-CPT lnet_net_lock therefore no longer protects the lpni against concurrent updates. To resolve this issue a spinlock is added to the lnet_peer_ni, which must be locked when the peer NI credits, delayed message queue, and delayed routed message queue are modified. The lock is not taken when reporting credits. Signed-off-by: Amir Shehata Signed-off-by: Olaf Weber Change-Id: I52153680a74d43e595314b63487026cc3f6a5a8f Reviewed-on: http://review.whamcloud.com/20702 Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/lib-move.c | 40 ++++++++++++++++++++------- drivers/staging/lustre/lnet/lnet/peer.c | 8 ++++- drivers/staging/lustre/lnet/lnet/router.c | 3 +- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 51224a4cb218..b4c7c8aa33a7 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -657,6 +657,7 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) } if (!msg->msg_peertxcredit) { + spin_lock(&lp->lpni_lock); LASSERT((lp->lpni_txcredits < 0) == !list_empty(&lp->lpni_txq)); @@ -670,8 +671,10 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) if (lp->lpni_txcredits < 0) { msg->msg_tx_delayed = 1; list_add_tail(&msg->msg_list, &lp->lpni_txq); + spin_unlock(&lp->lpni_lock); return LNET_CREDIT_WAIT; } + spin_unlock(&lp->lpni_lock); } if (!msg->msg_txcredit) { @@ -744,6 +747,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) LASSERT(!do_recv || msg->msg_rx_delayed); if (!msg->msg_peerrtrcredit) { + spin_lock(&lp->lpni_lock); LASSERT((lp->lpni_rtrcredits < 0) == !list_empty(&lp->lpni_rtrq)); @@ -757,8 +761,10 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) LASSERT(msg->msg_rx_ready_delay); msg->msg_rx_delayed = 1; list_add_tail(&msg->msg_list, &lp->lpni_rtrq); + spin_unlock(&lp->lpni_lock); return LNET_CREDIT_WAIT; } + spin_unlock(&lp->lpni_lock); } rbp = lnet_msg2bufpool(msg); @@ -822,6 +828,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) LASSERT(msg2->msg_txni == ni); LASSERT(msg2->msg_tx_delayed); + LASSERT(msg2->msg_tx_cpt == msg->msg_tx_cpt); (void)lnet_post_send_locked(msg2, 1); } @@ -831,6 +838,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) /* give back peer txcredits */ msg->msg_peertxcredit = 0; + spin_lock(&txpeer->lpni_lock); LASSERT((txpeer->lpni_txcredits < 0) == !list_empty(&txpeer->lpni_txq)); @@ -842,11 +850,22 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) msg2 = list_entry(txpeer->lpni_txq.next, struct lnet_msg, msg_list); list_del(&msg2->msg_list); + spin_unlock(&txpeer->lpni_lock); LASSERT(msg2->msg_txpeer == txpeer); LASSERT(msg2->msg_tx_delayed); + if (msg2->msg_tx_cpt != msg->msg_tx_cpt) { + lnet_net_unlock(msg->msg_tx_cpt); + lnet_net_lock(msg2->msg_tx_cpt); + } (void)lnet_post_send_locked(msg2, 1); + if (msg2->msg_tx_cpt != msg->msg_tx_cpt) { + lnet_net_unlock(msg2->msg_tx_cpt); + lnet_net_lock(msg->msg_tx_cpt); + } + } else { + spin_unlock(&txpeer->lpni_lock); } } @@ -887,17 +906,12 @@ lnet_schedule_blocked_locked(struct lnet_rtrbufpool *rbp) void lnet_drop_routed_msgs_locked(struct list_head *list, int cpt) { - struct list_head drop; struct lnet_msg *msg; - INIT_LIST_HEAD(&drop); - - list_splice_init(list, &drop); - lnet_net_unlock(cpt); - while(!list_empty(&drop)) { - msg = list_first_entry(&drop, struct lnet_msg, msg_list); + while (!list_empty(list)) { + msg = list_first_entry(list, struct lnet_msg, msg_list); lnet_ni_recv(msg->msg_rxni, msg->msg_private, NULL, 0, 0, 0, msg->msg_hdr.payload_length); list_del_init(&msg->msg_list); @@ -968,6 +982,7 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) /* give back peer router credits */ msg->msg_peerrtrcredit = 0; + spin_lock(&rxpeer->lpni_lock); LASSERT((rxpeer->lpni_rtrcredits < 0) == !list_empty(&rxpeer->lpni_rtrq)); @@ -977,14 +992,19 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) * peer. */ if (!the_lnet.ln_routing) { - lnet_drop_routed_msgs_locked(&rxpeer->lpni_rtrq, - msg->msg_rx_cpt); + LIST_HEAD(drop); + + list_splice_init(&rxpeer->lpni_rtrq, &drop); + spin_unlock(&rxpeer->lpni_lock); + lnet_drop_routed_msgs_locked(&drop, msg->msg_rx_cpt); } else if (rxpeer->lpni_rtrcredits <= 0) { msg2 = list_entry(rxpeer->lpni_rtrq.next, struct lnet_msg, msg_list); list_del(&msg2->msg_list); - + spin_unlock(&rxpeer->lpni_lock); (void)lnet_post_routed_recv_locked(msg2, 1); + } else { + spin_unlock(&rxpeer->lpni_lock); } } if (rxni) { diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index dc4527f86113..3555e9bd1db1 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -56,12 +56,16 @@ lnet_peer_net_added(struct lnet_net *net) lpni_on_remote_peer_ni_list) { if (LNET_NIDNET(lpni->lpni_nid) == net->net_id) { lpni->lpni_net = net; + + spin_lock(&lpni->lpni_lock); lpni->lpni_txcredits = - lpni->lpni_mintxcredits = lpni->lpni_net->net_tunables.lct_peer_tx_credits; + lpni->lpni_mintxcredits = + lpni->lpni_txcredits; lpni->lpni_rtrcredits = - lpni->lpni_minrtrcredits = lnet_peer_buffer_credits(lpni->lpni_net); + lpni->lpni_minrtrcredits = lpni->lpni_rtrcredits; + spin_unlock(&lpni->lpni_lock); lnet_peer_remove_from_remote_list(lpni); } diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index d3c41f5664a4..6c50e8cc7833 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -1358,7 +1358,8 @@ lnet_rtrpool_free_bufs(struct lnet_rtrbufpool *rbp, int cpt) INIT_LIST_HEAD(&tmp); lnet_net_lock(cpt); - lnet_drop_routed_msgs_locked(&rbp->rbp_msgs, cpt); + list_splice_init(&rbp->rbp_msgs, &tmp); + lnet_drop_routed_msgs_locked(&tmp, cpt); list_splice_init(&rbp->rbp_bufs, &tmp); rbp->rbp_req_nbuffers = 0; rbp->rbp_nbuffers = 0; From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 21/34] LU-7734 lnet: simplify and fix lnet_select_pathway() In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763568.32103.16087987326485396768.stgit@noble> From: Amir Shehata In lnet_select_pathway() we restart selection if the DLC seq counter changes. Provided we take a hold on the preferred lnet_peer_ni, we only need to restart if an lnet_ni was added or removed. Update the locations where lnet_incr_dlc_seq() is called to take this into account. A number of local variables must be reset whenever we goto again. Do this immediately after the label for the global variables, and immediately before the block that uses them for the helper variables. In the loop where NUMA distances are compared, use the NUMA range for distances smaller than the NUMA range, simplifying the subsequent comparisons between distances. Remote the lo_sent output parameter. Instead do an early return with LNET_CREDIT_OK. Move the increment of the best_lpni->lpni_seq number after the check that best_lpni isn't NULL. When routing, the best_gw should be treated as the best_lpni for the purpose of determining the CPT to lock. Signed-off-by: Amir Shehata Signed-off-by: Olaf Weber Change-Id: Ie71eebc2301601cf1c85c6248dbed06951b89274 Reviewed-on: http://review.whamcloud.com/20720 Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 11 + drivers/staging/lustre/lnet/lnet/lib-move.c | 213 +++++++++++---------------- 2 files changed, 88 insertions(+), 136 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 9807cfb3a0fc..ac6efcd746c5 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -72,10 +72,10 @@ MODULE_PARM_DESC(lnet_numa_range, /* * This sequence number keeps track of how many times DLC was used to - * update the configuration. It is incremented on any DLC update and - * checked when sending a message to determine if there is a need to - * re-run the selection algorithm to handle configuration change. - * Look at lnet_select_pathway() for more details on its usage. + * update the local NIs. It is incremented when a NI is added or + * removed and checked when sending a message to determine if there is + * a need to re-run the selection algorithm. See lnet_select_pathway() + * for more details on its usage. */ static atomic_t lnet_dlc_seq_no = ATOMIC_INIT(0); @@ -1223,6 +1223,7 @@ lnet_shutdown_lndni(struct lnet_ni *ni) lnet_net_lock(LNET_LOCK_EX); ni->ni_state = LNET_NI_STATE_DELETING; lnet_ni_unlink_locked(ni); + lnet_incr_dlc_seq(); lnet_net_unlock(LNET_LOCK_EX); /* clear messages for this NI on the lazy portal */ @@ -2723,7 +2724,6 @@ LNetCtl(unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&the_lnet.ln_api_mutex); - lnet_incr_dlc_seq(); rc = lnet_add_peer_ni_to_peer(cfg->prcfg_key_nid, cfg->prcfg_cfg_nid, cfg->prcfg_mr); @@ -2738,7 +2738,6 @@ LNetCtl(unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&the_lnet.ln_api_mutex); - lnet_incr_dlc_seq(); rc = lnet_del_peer_ni_from_peer(cfg->prcfg_key_nid, cfg->prcfg_cfg_nid); mutex_unlock(&the_lnet.ln_api_mutex); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index b4c7c8aa33a7..8019c59cc64e 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1132,48 +1132,44 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, static int lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, - struct lnet_msg *msg, lnet_nid_t rtr_nid, bool *lo_sent) + struct lnet_msg *msg, lnet_nid_t rtr_nid) { struct lnet_ni *best_ni = NULL; struct lnet_peer_ni *best_lpni = NULL; - struct lnet_peer_ni *net_gw = NULL; struct lnet_peer_ni *best_gw = NULL; struct lnet_peer_ni *lpni; - struct lnet_peer *peer = NULL; + struct lnet_peer *peer; struct lnet_peer_net *peer_net; struct lnet_net *local_net; - struct lnet_ni *ni = NULL; + struct lnet_ni *ni; + __u32 seq; int cpt, cpt2, rc; - bool routing = false; - bool ni_is_pref = false; - bool preferred = false; - int best_credits = 0; - u32 seq, seq2; - int best_lpni_credits = INT_MIN; - int md_cpt = 0; - unsigned int shortest_distance = UINT_MAX; - unsigned int distance = 0; - bool found_ir = false; + bool routing; + bool ni_is_pref; + bool preferred; + int best_credits; + int best_lpni_credits; + int md_cpt; + unsigned int shortest_distance; -again: /* * get an initial CPT to use for locking. The idea here is not to * serialize the calls to select_pathway, so that as many * operations can run concurrently as possible. To do that we use * the CPT where this call is being executed. Later on when we * determine the CPT to use in lnet_message_commit, we switch the - * lock and check if there was any configuration changes, if none, - * then we proceed, if there is, then we'll need to update the cpt - * and redo the operation. + * lock and check if there was any configuration change. If none, + * then we proceed, if there is, then we restart the operation. */ cpt = lnet_net_lock_current(); - +again: + best_ni = NULL; + best_lpni = NULL; best_gw = NULL; - routing = false; local_net = NULL; - best_ni = NULL; - shortest_distance = UINT_MAX; - found_ir = false; + routing = false; + + seq = lnet_get_dlc_seq_locked(); if (the_lnet.ln_shutdown) { lnet_net_unlock(cpt); @@ -1186,13 +1182,6 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, else md_cpt = CFS_CPT_ANY; - /* - * initialize the variables which could be reused if we go to - * again - */ - lpni = NULL; - seq = lnet_get_dlc_seq_locked(); - peer = lnet_find_or_create_peer_locked(dst_nid, cpt); if (IS_ERR(peer)) { lnet_net_unlock(cpt); @@ -1234,10 +1223,8 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, libcfs_nid2str(src_nid)); return -EINVAL; } - } - - if (best_ni) goto pick_peer; + } /* * Decide whether we need to route to peer_ni. @@ -1254,6 +1241,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, local_net = lnet_get_net_locked(peer_net->lpn_net_id); if (!local_net) { + struct lnet_peer_ni *net_gw; /* * go through each peer_ni on that peer_net and * determine the best possible gw to go through @@ -1307,8 +1295,12 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * 2. NI available credits * 3. Round Robin */ + shortest_distance = UINT_MAX; + best_credits = INT_MIN; + ni = NULL; while ((ni = lnet_get_next_ni_locked(local_net, ni))) { int ni_credits; + unsigned int distance; if (!lnet_is_ni_healthy_locked(ni)) continue; @@ -1316,7 +1308,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, ni_credits = atomic_read(&ni->ni_tx_credits); /* - * calculate the distance from the cpt on which + * calculate the distance from the CPT on which * the message memory is allocated to the CPT of * the NI's physical device */ @@ -1325,84 +1317,31 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, ni->dev_cpt); /* - * If we already have a closer NI within the NUMA - * range provided, then there is no need to - * consider the current NI. Move on to the next - * one. + * All distances smaller than the NUMA range + * are treated equally. */ - if (distance > shortest_distance && - distance > lnet_numa_range) - continue; + if (distance < lnet_numa_range) + distance = lnet_numa_range; - if (distance < shortest_distance && - distance > lnet_numa_range) { - /* - * The current NI is the closest one that we - * have found, even though it's not in the - * NUMA range specified. This occurs if - * the NUMA range is less than the least - * of the distances in the system. - * In effect NUMA range consideration is - * turned off. - */ + /* + * Select on shorter distance, then available + * credits, then round-robin. + */ + if (distance > shortest_distance) { + continue; + } else if (distance < shortest_distance) { shortest_distance = distance; - } else if ((distance <= shortest_distance && - distance < lnet_numa_range) || - distance == shortest_distance) { - /* - * This NI is either within range or it's - * equidistant. In both of these cases we - * would want to select the NI based on - * its available credits first, and then - * via Round Robin. - */ - if (distance <= shortest_distance && - distance < lnet_numa_range) { - /* - * If this is the first NI that's - * within range, then set the - * shortest distance to the range - * specified by the user. In - * effect we're saying that all - * NIs that fall within this NUMA - * range shall be dealt with as - * having equal NUMA weight. Which - * will mean that we should select - * through that set by their - * available credits first - * followed by Round Robin. - * - * And since this is the first NI - * in the range, let's just set it - * as our best_ni for now. The - * following NIs found in the - * range will be dealt with as - * mentioned previously. - */ - shortest_distance = lnet_numa_range; - if (!found_ir) { - found_ir = true; - goto set_ni; - } - } - /* - * This NI is NUMA equidistant let's - * select using credits followed by Round - * Robin. - */ - if (ni_credits < best_credits) { + } else if (ni_credits < best_credits) { + continue; + } else if (ni_credits == best_credits) { + if (best_ni && best_ni->ni_seq <= ni->ni_seq) continue; - } else if (ni_credits == best_credits) { - if (best_ni && - best_ni->ni_seq <= ni->ni_seq) - continue; - } } -set_ni: best_ni = ni; best_credits = ni_credits; } } + /* * if the peer is not MR capable, then we should always send to it * using the first NI in the NET we determined. @@ -1436,17 +1375,12 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); msg->msg_target.nid = best_ni->ni_nid; lnet_msg_commit(msg, cpt); - - lnet_net_unlock(cpt); msg->msg_txni = best_ni; - lnet_ni_send(best_ni, msg); + lnet_net_unlock(cpt); - *lo_sent = true; - return 0; + return LNET_CREDIT_OK; } - lpni = NULL; - if (msg->msg_type == LNET_MSG_REPLY || msg->msg_type == LNET_MSG_ACK) { /* @@ -1509,14 +1443,22 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, */ u32 net_id = peer_net->lpn_net_id; - lnet_net_unlock(cpt); - if (!best_lpni) - LCONSOLE_WARN("peer net %s unhealthy\n", - libcfs_net2str(net_id)); + LCONSOLE_WARN("peer net %s unhealthy\n", + libcfs_net2str(net_id)); goto again; } - best_lpni = NULL; + /* + * Look at the peer NIs for the destination peer that connect + * to the chosen net. If a peer_ni is preferred when using the + * best_ni to communicate, we use that one. If there is no + * preferred peer_ni, or there are multiple preferred peer_ni, + * the available transmit credits are used. If the transmit + * credits are equal, we round-robin over the peer_ni. + */ + lpni = NULL; + best_lpni_credits = INT_MIN; + preferred = false; while ((lpni = lnet_get_next_peer_ni_locked(peer, peer_net, lpni))) { /* * if this peer ni is not healthy just skip it, no point in @@ -1559,12 +1501,6 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, best_lpni_credits = lpni->lpni_txcredits; } - /* - * Increment sequence number of the peer selected so that we can - * pick the next one in Round Robin. - */ - best_lpni->lpni_seq++; - /* if we still can't find a peer ni then we can't reach it */ if (!best_lpni) { u32 net_id = peer_net ? peer_net->lpn_net_id : @@ -1577,6 +1513,25 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, } send: + /* + * Increment sequence number of the peer selected so that we + * pick the next one in Round Robin. + */ + best_lpni->lpni_seq++; + + /* + * When routing the best gateway found acts as the best peer + * NI to send to. + */ + if (routing) + best_lpni = best_gw; + + /* + * grab a reference on the peer_ni so it sticks around even if + * we need to drop and relock the lnet_net_lock below. + */ + lnet_peer_ni_addref_locked(best_lpni); + /* * Use lnet_cpt_of_nid() to determine the CPT used to commit the * message. This ensures that we get a CPT that is correct for @@ -1584,16 +1539,15 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * If the selected CPT differs from the one currently locked, we * must unlock and relock the lnet_net_lock(), and then check whether * the configuration has changed. We don't have a hold on the best_ni - * or best_peer_ni yet, and they may have vanished. + * yet, and it may have vanished. */ cpt2 = lnet_cpt_of_nid_locked(best_lpni->lpni_nid, best_ni); if (cpt != cpt2) { lnet_net_unlock(cpt); cpt = cpt2; lnet_net_lock(cpt); - seq2 = lnet_get_dlc_seq_locked(); - if (seq2 != seq) { - lnet_net_unlock(cpt); + if (seq != lnet_get_dlc_seq_locked()) { + lnet_peer_ni_decref_locked(best_lpni); goto again; } } @@ -1602,15 +1556,15 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * store the best_lpni in the message right away to avoid having * to do the same operation under different conditions */ - msg->msg_txpeer = (routing) ? best_gw : best_lpni; + msg->msg_txpeer = best_lpni; msg->msg_txni = best_ni; + /* * grab a reference for the best_ni since now it's in use in this * send. the reference will need to be dropped when the message is * finished in lnet_finalize() */ lnet_ni_addref_locked(msg->msg_txni, cpt); - lnet_peer_ni_addref_locked(msg->msg_txpeer); /* * set the destination nid in the message here because it's @@ -1659,7 +1613,6 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) { lnet_nid_t dst_nid = msg->msg_target.nid; int rc; - bool lo_sent = false; /* * NB: rtr_nid is set to LNET_NID_ANY for all current use-cases, @@ -1676,8 +1629,8 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) LASSERT(!msg->msg_tx_committed); - rc = lnet_select_pathway(src_nid, dst_nid, msg, rtr_nid, &lo_sent); - if (rc < 0 || lo_sent) + rc = lnet_select_pathway(src_nid, dst_nid, msg, rtr_nid); + if (rc < 0) return rc; if (rc == LNET_CREDIT_OK) From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 22/34] LU-7734 lnet: fix lnet_peer_table_cleanup_locked() In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763572.32103.17043305407995526499.stgit@noble> From: Olaf Weber In lnet_peer_table_cleanup_locked() we delete the entire peer if the lnet_peer_ni for the primary NID of the peer is deleted. If the next lnet_peer_ni in the list belongs to the peer being deleted, then the next pointer kept by list_for_each_entry_safe() ends up pointing at freed memory. Add a list_for_each_entry_from() loop to advance next to a peer_ni that does not belong to the peer being deleted and will therefore remain present in the list. Signed-off-by: Olaf Weber Change-Id: I92bf219dc93a79f7d90035ccfbb38cd251138c04 Reviewed-on: http://review.whamcloud.com/20824 Reviewed-by: Amir Shehata Tested-by: Amir Shehata Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/peer.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 3555e9bd1db1..11edf3632405 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -331,26 +331,32 @@ lnet_peer_table_cleanup_locked(struct lnet_net *net, struct lnet_peer_table *ptable) { int i; + struct lnet_peer_ni *next; struct lnet_peer_ni *lpni; - struct lnet_peer_ni *tmp; struct lnet_peer *peer; for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { - list_for_each_entry_safe(lpni, tmp, &ptable->pt_hash[i], + list_for_each_entry_safe(lpni, next, &ptable->pt_hash[i], lpni_hashlist) { if (net && net != lpni->lpni_net) continue; - /* - * check if by removing this peer ni we should be - * removing the entire peer. - */ peer = lpni->lpni_peer_net->lpn_peer; - - if (peer->lp_primary_nid == lpni->lpni_nid) - lnet_peer_del_locked(peer); - else + if (peer->lp_primary_nid != lpni->lpni_nid) { lnet_peer_ni_del_locked(lpni); + continue; + } + /* + * Removing the primary NID implies removing + * the entire peer. Advance next beyond any + * peer_ni that belongs to the same peer. + */ + list_for_each_entry_from(next, &ptable->pt_hash[i], + lpni_hashlist) { + if (next->lpni_peer_net->lpn_peer != peer) + break; + } + lnet_peer_del_locked(peer); } } } From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 23/34] LU-7734 lnet: configuration fixes In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763576.32103.3176502972388297285.stgit@noble> From: Amir Shehata Fix cpt configuration from DLC to configure the proper list of cpts in LNet. Check in LNet that no CPTs are outside the available CPTs in the system. Fix peer_rtr_credits name to peer_tx_credits to reflect the actual value. Signed-off-by: Amir Shehata Change-Id: Ic4a3985a470ed901be6166df4079205677921817 Reviewed-on: http://review.whamcloud.com/20862 Signed-off-by: NeilBrown --- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 4 +++- drivers/staging/lustre/lnet/lnet/api-ni.c | 9 +++++++-- drivers/staging/lustre/lnet/lnet/peer.c | 3 ++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index b31b69c25ef2..a5e94619d3f1 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -169,6 +169,7 @@ struct lnet_ioctl_config_ni { __u32 lic_tcp_bonding; __u32 lic_idx; __s32 lic_dev_cpt; + char pad[4]; char lic_bulk[0]; }; @@ -177,9 +178,10 @@ struct lnet_peer_ni_credit_info { __u32 cr_refcount; __s32 cr_ni_peer_tx_credits; __s32 cr_peer_tx_credits; + __s32 cr_peer_min_tx_credits; + __u32 cr_peer_tx_qnob; __s32 cr_peer_rtr_credits; __s32 cr_peer_min_rtr_credits; - __u32 cr_peer_tx_qnob; __u32 cr_ncpt; }; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ac6efcd746c5..60176d05d34a 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -2283,7 +2283,7 @@ int lnet_dyn_add_ni(struct lnet_ioctl_config_ni *conf) struct lnet_net *net; struct lnet_ni *ni; struct lnet_ioctl_config_lnd_tunables *tun = NULL; - int rc; + int rc, i; u32 net_id; /* get the tunables if they are available */ @@ -2303,6 +2303,11 @@ int lnet_dyn_add_ni(struct lnet_ioctl_config_ni *conf) if (!net) return -ENOMEM; + for (i = 0; i < conf->lic_ncpts; i++) { + if (conf->lic_cpts[i] >= LNET_CPT_NUMBER) + return -EINVAL; + } + ni = lnet_ni_alloc_w_cpt_array(net, conf->lic_cpts, conf->lic_ncpts, conf->lic_ni_intf[0]); if (!ni) @@ -2760,7 +2765,7 @@ LNetCtl(unsigned int cmd, void *arg) &peer_info->pr_lnd_u.pr_peer_credits.cr_ni_peer_tx_credits, &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_credits, &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_rtr_credits, - &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_min_rtr_credits, + &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_min_tx_credits, &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_qnob); mutex_unlock(&the_lnet.ln_api_mutex); return rc; diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 11edf3632405..6f6039189456 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -1127,7 +1127,8 @@ int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, lpni->lpni_net->net_tunables.lct_peer_tx_credits : 0; peer_ni_info->cr_peer_tx_credits = lpni->lpni_txcredits; peer_ni_info->cr_peer_rtr_credits = lpni->lpni_rtrcredits; - peer_ni_info->cr_peer_min_rtr_credits = lpni->lpni_mintxcredits; + peer_ni_info->cr_peer_min_rtr_credits = lpni->lpni_minrtrcredits; + peer_ni_info->cr_peer_min_tx_credits = lpni->lpni_mintxcredits; peer_ni_info->cr_peer_tx_qnob = lpni->lpni_txqnob; peer_ni_stats->send_count = atomic_read(&lpni->lpni_stats.send_count); From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 24/34] LU-7734 lnet: fix lnet_select_pathway() In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763579.32103.5954776193692454631.stgit@noble> From: Amir Shehata Fixed the selection algorithm to work properly with > 1 local networks. The behavior now is to iterate through all interfaces on all networks Also removed the health variable from struct lnet_peer_net since it's never used. Signed-off-by: Amir Shehata Change-Id: Ib91748e80446585b6a9e1bc0f3af6894599d8aaa Reviewed-on: http://review.whamcloud.com/20890 Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 3 --- drivers/staging/lustre/lnet/lnet/lib-move.c | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 90a5c6e40dea..0761fd533f8d 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -504,9 +504,6 @@ struct lnet_peer_net { /* Net ID */ __u32 lpn_net_id; - - /* health flag */ - bool lpn_healthy; }; /* peer hash size */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 8019c59cc64e..2f30ba0d89fb 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1235,6 +1235,8 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * b. Iterate through each of the peer_nets/nis to decide * the best peer/local_ni pair to use */ + shortest_distance = UINT_MAX; + best_credits = INT_MIN; list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_on_peer_list) { if (!lnet_is_peer_net_healthy_locked(peer_net)) continue; @@ -1295,8 +1297,6 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * 2. NI available credits * 3. Round Robin */ - shortest_distance = UINT_MAX; - best_credits = INT_MIN; ni = NULL; while ((ni = lnet_get_next_ni_locked(local_net, ni))) { int ni_credits; From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 25/34] LU-7734 lnet: Routing fixes part 1 In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763583.32103.2609293106875022233.stgit@noble> From: Amir Shehata This is the first part of a routing fix. - Fix crash in lnet_parse_get() - Resolve deadlock when adding a route. - Fix an issue with dynamically turning on routing - Set the final destination NID properly when routing a msg Signed-off-by: Amir Shehata Change-Id: I68d0e4d52192aa96e37c77952a1ebe75c1b770c5 Reviewed-on: http://review.whamcloud.com/21166 Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 drivers/staging/lustre/lnet/lnet/lib-move.c | 23 +++++-- drivers/staging/lustre/lnet/lnet/peer.c | 62 ++++++++++++++++---- drivers/staging/lustre/lnet/lnet/router.c | 2 - 4 files changed, 67 insertions(+), 21 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 55bcd17cd4dc..3a53d54b711d 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -649,6 +649,7 @@ struct lnet_peer_ni *lnet_get_next_peer_ni_locked(struct lnet_peer *peer, struct lnet_peer_ni *prev); struct lnet_peer *lnet_find_or_create_peer_locked(lnet_nid_t dst_nid, int cpt); struct lnet_peer_ni *lnet_nid2peerni_locked(lnet_nid_t nid, int cpt); +struct lnet_peer_ni *lnet_nid2peerni_ex(lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid); void lnet_peer_net_added(struct lnet_net *net); lnet_nid_t lnet_peer_primary_nid(lnet_nid_t nid); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 2f30ba0d89fb..58521b014ef3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1566,17 +1566,10 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, */ lnet_ni_addref_locked(msg->msg_txni, cpt); - /* - * set the destination nid in the message here because it's - * possible that we'd be sending to a different nid than the one - * originaly given. - */ - msg->msg_hdr.dest_nid = cpu_to_le64(msg->msg_txpeer->lpni_nid); - /* * Always set the target.nid to the best peer picked. Either the * nid will be one of the preconfigured NIDs, or the same NID as - * what was originaly set in the target or it will be the NID of + * what was originally set in the target or it will be the NID of * a router if this message should be routed */ msg->msg_target.nid = msg->msg_txpeer->lpni_nid; @@ -1599,6 +1592,19 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, if (routing) { msg->msg_target_is_router = 1; msg->msg_target.pid = LNET_PID_LUSTRE; + /* + * since we're routing we want to ensure that the + * msg_hdr.dest_nid is set to the final destination. When + * the router receives this message it knows how to route + * it. + */ + msg->msg_hdr.dest_nid = cpu_to_le64(dst_nid); + } else { + /* + * if we're not routing set the dest_nid to the best peer + * ni that we picked earlier in the algorithm. + */ + msg->msg_hdr.dest_nid = cpu_to_le64(msg->msg_txpeer->lpni_nid); } rc = lnet_post_send_locked(msg, 0); @@ -1757,6 +1763,7 @@ lnet_parse_get(struct lnet_ni *ni, struct lnet_msg *msg, int rdma_get) info.mi_rlength = hdr->msg.get.sink_length; info.mi_roffset = hdr->msg.get.src_offset; info.mi_mbits = hdr->msg.get.match_bits; + info.mi_cpt = lnet_cpt_of_nid(msg->msg_rxpeer->lpni_nid, ni); rc = lnet_ptl_match_md(&info, msg); if (rc == LNET_MATCHMD_DROP) { diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 6f6039189456..9cecfb49db87 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -954,36 +954,74 @@ lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lpni) kfree(lpni); } +struct lnet_peer_ni * +lnet_nid2peerni_ex(lnet_nid_t nid, int cpt) +{ + struct lnet_peer_ni *lpni = NULL; + int rc; + + if (the_lnet.ln_shutdown) /* it's shutting down */ + return ERR_PTR(-ESHUTDOWN); + + /* + * find if a peer_ni already exists. + * If so then just return that. + */ + lpni = lnet_find_peer_ni_locked(nid); + if (lpni) + return lpni; + + lnet_net_unlock(cpt); + + rc = lnet_peer_ni_traffic_add(nid); + if (rc) { + lpni = ERR_PTR(rc); + goto out_net_relock; + } + + lpni = lnet_find_peer_ni_locked(nid); + LASSERT(lpni); + +out_net_relock: + lnet_net_lock(cpt); + + return lpni; +} + struct lnet_peer_ni * lnet_nid2peerni_locked(lnet_nid_t nid, int cpt) { - struct lnet_peer_table *ptable; struct lnet_peer_ni *lpni = NULL; - int cpt2; int rc; if (the_lnet.ln_shutdown) /* it's shutting down */ return ERR_PTR(-ESHUTDOWN); /* - * calculate cpt2 with the standard hash function - * This cpt2 is the slot where we'll find or create the peer. + * find if a peer_ni already exists. + * If so then just return that. */ - cpt2 = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); - ptable = the_lnet.ln_peer_tables[cpt2]; - lpni = lnet_get_peer_ni_locked(ptable, nid); + lpni = lnet_find_peer_ni_locked(nid); if (lpni) return lpni; - /* Slow path: serialized using the ln_api_mutex. */ + /* + * Slow path: + * use the lnet_api_mutex to serialize the creation of the peer_ni + * and the creation/deletion of the local ni/net. When a local ni is + * created, if there exists a set of peer_nis on that network, + * they need to be traversed and updated. When a local NI is + * deleted, which could result in a network being deleted, then + * all peer nis on that network need to be removed as well. + * + * Creation through traffic should also be serialized with + * creation through DLC. + */ lnet_net_unlock(cpt); mutex_lock(&the_lnet.ln_api_mutex); /* * Shutdown is only set under the ln_api_lock, so a single * check here is sufficent. - * - * lnet_add_nid_to_peer() also handles the case where we've - * raced and a different thread added the NID. */ if (the_lnet.ln_shutdown) { lpni = ERR_PTR(-ESHUTDOWN); @@ -996,7 +1034,7 @@ lnet_nid2peerni_locked(lnet_nid_t nid, int cpt) goto out_mutex_unlock; } - lpni = lnet_get_peer_ni_locked(ptable, nid); + lpni = lnet_find_peer_ni_locked(nid); LASSERT(lpni); out_mutex_unlock: diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 6c50e8cc7833..a0483f970bd5 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -358,7 +358,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, lnet_net_lock(LNET_LOCK_EX); - lpni = lnet_nid2peerni_locked(gateway, LNET_LOCK_EX); + lpni = lnet_nid2peerni_ex(gateway, LNET_LOCK_EX); if (IS_ERR(lpni)) { lnet_net_unlock(LNET_LOCK_EX); From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 26/34] LU-7734 lnet: Routing fixes part 2 In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763587.32103.5037367646271689437.stgit@noble> From: Amir Shehata Fix lnet_select_pathway() to handle the routing cases correctly. The following general cases are handled: . Non-MR directly connected . Non-MR not directly connected . MR Directly connected . MR Not directly connected . No gateway . Gateway is non-mr . Gateway is mr Signed-off-by: Amir Shehata Change-Id: If2d16b797b94421e78a9f2a254a250a440f8b244 Reviewed-on: http://review.whamcloud.com/21167 Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/lib-move.c | 214 ++++++++++++++++++--------- drivers/staging/lustre/lnet/lnet/peer.c | 29 +++- 2 files changed, 167 insertions(+), 76 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 58521b014ef3..12bc80d060e9 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1145,6 +1145,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, __u32 seq; int cpt, cpt2, rc; bool routing; + bool routing2; bool ni_is_pref; bool preferred; int best_credits; @@ -1168,6 +1169,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, best_gw = NULL; local_net = NULL; routing = false; + routing2 = false; seq = lnet_get_dlc_seq_locked(); @@ -1201,7 +1203,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, } /* - * STEP 1: first jab at determineing best_ni + * STEP 1: first jab at determining best_ni * if src_nid is explicitly specified, then best_ni is already * pre-determiend for us. Otherwise we need to select the best * one to use later on @@ -1215,17 +1217,122 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, libcfs_nid2str(src_nid)); return -EINVAL; } + } + + if (msg->msg_type == LNET_MSG_REPLY || + msg->msg_type == LNET_MSG_ACK || + !peer->lp_multi_rail) { + /* + * for replies we want to respond on the same peer_ni we + * received the message on if possible. If not, then pick + * a peer_ni to send to + * + * if the peer is non-multi-rail then you want to send to + * the dst_nid provided as well. + * + * It is expected to find the lpni using dst_nid, since we + * created it earlier. + */ + best_lpni = lnet_find_peer_ni_locked(dst_nid); + if (best_lpni) + lnet_peer_ni_decref_locked(best_lpni); - if (best_ni->ni_net->net_id != LNET_NIDNET(dst_nid)) { + if (best_lpni && !lnet_get_net_locked(LNET_NIDNET(dst_nid))) { + /* + * this lpni is not on a local network so we need + * to route this reply. + */ + best_gw = lnet_find_route_locked(NULL, + best_lpni->lpni_nid, + rtr_nid); + if (best_gw) { + /* + * RULE: Each node considers only the next-hop + * + * We're going to route the message, + * so change the peer to the router. + */ + LASSERT(best_gw->lpni_peer_net); + LASSERT(best_gw->lpni_peer_net->lpn_peer); + peer = best_gw->lpni_peer_net->lpn_peer; + + /* + * if the router is not multi-rail + * then use the best_gw found to send + * the message to + */ + if (!peer->lp_multi_rail) + best_lpni = best_gw; + else + best_lpni = NULL; + + routing = true; + } else { + best_lpni = NULL; + } + } else if (!best_lpni) { lnet_net_unlock(cpt); - LCONSOLE_WARN("No route to %s via from %s\n", - libcfs_nid2str(dst_nid), - libcfs_nid2str(src_nid)); + CERROR("unable to send msg_type %d to originating %s. Destination NID not in DB\n", + msg->msg_type, libcfs_nid2str(dst_nid)); return -EINVAL; } - goto pick_peer; } + /* + * if the peer is not MR capable, then we should always send to it + * using the first NI in the NET we determined. + */ + if (!peer->lp_multi_rail) { + if (!best_lpni) { + lnet_net_unlock(cpt); + CERROR("no route to %s\n", + libcfs_nid2str(dst_nid)); + return -EHOSTUNREACH; + } + + /* best ni could be set because src_nid was provided */ + if (!best_ni) { + best_ni = lnet_net2ni_locked( + best_lpni->lpni_net->net_id, cpt); + if (!best_ni) { + lnet_net_unlock(cpt); + CERROR("no path to %s from net %s\n", + libcfs_nid2str(best_lpni->lpni_nid), + libcfs_net2str(best_lpni->lpni_net->net_id)); + return -EHOSTUNREACH; + } + } + } + + if (best_ni == the_lnet.ln_loni) { + /* No send credit hassles with LOLND */ + lnet_ni_addref_locked(best_ni, cpt); + msg->msg_hdr.dest_nid = cpu_to_le64(best_ni->ni_nid); + if (!msg->msg_routing) + msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); + msg->msg_target.nid = best_ni->ni_nid; + lnet_msg_commit(msg, cpt); + msg->msg_txni = best_ni; + lnet_net_unlock(cpt); + + return LNET_CREDIT_OK; + } + + /* + * if we already found a best_ni because src_nid is specified and + * best_lpni because we are replying to a message then just send + * the message + */ + if (best_ni && best_lpni) + goto send; + + /* + * If we already found a best_ni because src_nid is specified then + * pick the peer then send the message + */ + if (best_ni) + goto pick_peer; + /* * Decide whether we need to route to peer_ni. * Get the local net that I need to be on to be able to directly @@ -1242,7 +1349,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, continue; local_net = lnet_get_net_locked(peer_net->lpn_net_id); - if (!local_net) { + if (!local_net && !routing) { struct lnet_peer_ni *net_gw; /* * go through each peer_ni on that peer_net and @@ -1263,14 +1370,11 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, if (!best_gw) { best_gw = net_gw; - best_lpni = lpni; } else { rc = lnet_compare_peers(net_gw, best_gw); - if (rc > 0) { + if (rc > 0) best_gw = net_gw; - best_lpni = lpni; - } } } @@ -1279,9 +1383,9 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, local_net = lnet_get_net_locked (LNET_NIDNET(best_gw->lpni_nid)); - routing = true; + routing2 = true; } else { - routing = false; + routing2 = false; best_gw = NULL; } @@ -1342,12 +1446,17 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, } } - /* - * if the peer is not MR capable, then we should always send to it - * using the first NI in the NET we determined. - */ - if (!peer->lp_multi_rail && local_net) - best_ni = lnet_net2ni_locked(local_net->net_id, cpt); + if (routing2) { + /* + * RULE: Each node considers only the next-hop + * + * We're going to route the message, so change the peer to + * the router. + */ + LASSERT(best_gw->lpni_peer_net); + LASSERT(best_gw->lpni_peer_net->lpn_peer); + peer = best_gw->lpni_peer_net->lpn_peer; + } if (!best_ni) { lnet_net_unlock(cpt); @@ -1363,43 +1472,11 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, */ best_ni->ni_seq++; - if (routing) - goto send; - pick_peer: - if (best_ni == the_lnet.ln_loni) { - /* No send credit hassles with LOLND */ - lnet_ni_addref_locked(best_ni, cpt); - msg->msg_hdr.dest_nid = cpu_to_le64(best_ni->ni_nid); - if (!msg->msg_routing) - msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); - msg->msg_target.nid = best_ni->ni_nid; - lnet_msg_commit(msg, cpt); - msg->msg_txni = best_ni; - lnet_net_unlock(cpt); - - return LNET_CREDIT_OK; - } - - if (msg->msg_type == LNET_MSG_REPLY || - msg->msg_type == LNET_MSG_ACK) { - /* - * for replies we want to respond on the same peer_ni we - * received the message on if possible. If not, then pick - * a peer_ni to send to - */ - best_lpni = lnet_find_peer_ni_locked(dst_nid); - if (best_lpni) { - lnet_peer_ni_decref_locked(best_lpni); - goto send; - } else { - CDEBUG(D_NET, - "unable to send msg_type %d to originating %s\n", - msg->msg_type, - libcfs_nid2str(dst_nid)); - } - } - + /* + * At this point the best_ni is on a local network on which + * the peer has a peer_ni as well + */ peer_net = lnet_peer_get_net_locked(peer, best_ni->ni_net->net_id); /* @@ -1429,13 +1506,16 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, libcfs_nid2str(best_gw->lpni_nid), lnet_msgtyp2str(msg->msg_type), msg->msg_len); - best_lpni = lnet_find_peer_ni_locked(dst_nid); - LASSERT(best_lpni); - lnet_peer_ni_decref_locked(best_lpni); - - routing = true; - - goto send; + routing2 = true; + /* + * RULE: Each node considers only the next-hop + * + * We're going to route the message, so change the peer to + * the router. + */ + LASSERT(best_gw->lpni_peer_net); + LASSERT(best_gw->lpni_peer_net->lpn_peer); + peer = best_gw->lpni_peer_net->lpn_peer; } else if (!lnet_is_peer_net_healthy_locked(peer_net)) { /* * this peer_net is unhealthy but we still have an opportunity @@ -1459,6 +1539,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, lpni = NULL; best_lpni_credits = INT_MIN; preferred = false; + best_lpni = NULL; while ((lpni = lnet_get_next_peer_ni_locked(peer, peer_net, lpni))) { /* * if this peer ni is not healthy just skip it, no point in @@ -1513,19 +1594,14 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, } send: + routing = routing || routing2; + /* * Increment sequence number of the peer selected so that we * pick the next one in Round Robin. */ best_lpni->lpni_seq++; - /* - * When routing the best gateway found acts as the best peer - * NI to send to. - */ - if (routing) - best_lpni = best_gw; - /* * grab a reference on the peer_ni so it sticks around even if * we need to drop and relock the lnet_net_lock below. diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 9cecfb49db87..d757f4df1f39 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -225,11 +225,18 @@ lnet_try_destroy_peer_hierarchy_locked(struct lnet_peer_ni *lpni) } /* called with lnet_net_lock LNET_LOCK_EX held */ -static void +static int lnet_peer_ni_del_locked(struct lnet_peer_ni *lpni) { struct lnet_peer_table *ptable = NULL; + /* don't remove a peer_ni if it's also a gateway */ + if (lpni->lpni_rtr_refcount > 0) { + CERROR("Peer NI %s is a gateway. Can not delete it\n", + libcfs_nid2str(lpni->lpni_nid)); + return -EBUSY; + } + lnet_peer_remove_from_remote_list(lpni); /* remove peer ni from the hash list. */ @@ -260,6 +267,8 @@ lnet_peer_ni_del_locked(struct lnet_peer_ni *lpni) /* decrement reference on peer */ lnet_peer_ni_decref_locked(lpni); + + return 0; } void lnet_peer_uninit(void) @@ -313,17 +322,22 @@ lnet_peer_tables_create(void) return 0; } -static void +static int lnet_peer_del_locked(struct lnet_peer *peer) { struct lnet_peer_ni *lpni = NULL, *lpni2; + int rc = 0, rc2 = 0; lpni = lnet_get_next_peer_ni_locked(peer, NULL, lpni); while (lpni) { lpni2 = lnet_get_next_peer_ni_locked(peer, NULL, lpni); - lnet_peer_ni_del_locked(lpni); + rc = lnet_peer_ni_del_locked(lpni); + if (rc != 0) + rc2 = rc; lpni = lpni2; } + + return rc2; } static void @@ -899,6 +913,7 @@ lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid) lnet_nid_t local_nid; struct lnet_peer *peer; struct lnet_peer_ni *lpni; + int rc; if (key_nid == LNET_NID_ANY) return -EINVAL; @@ -919,17 +934,17 @@ lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid) * entire peer */ lnet_net_lock(LNET_LOCK_EX); - lnet_peer_del_locked(peer); + rc = lnet_peer_del_locked(peer); lnet_net_unlock(LNET_LOCK_EX); - return 0; + return rc; } lnet_net_lock(LNET_LOCK_EX); - lnet_peer_ni_del_locked(lpni); + rc = lnet_peer_ni_del_locked(lpni); lnet_net_unlock(LNET_LOCK_EX); - return 0; + return rc; } void From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 27/34] LU-7734 lnet: fix routing selection In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763590.32103.13916552051734764199.stgit@noble> From: Amir Shehata Always prefer locally connected networks over routed networks. If there are multiple routed networks and no connected networks pick the best gateway to use. If all gateways are equal then round robin through them. Renamed dev_cpt to ni_dev_cpt to maintain naming convention. Signed-off-by: Amir Shehata Change-Id: Ie6a3aaa7a9ec4f5474baf5e1ec0258d481418cb1 Reviewed-on: http://review.whamcloud.com/21326 Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 4 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 4 drivers/staging/lustre/lnet/lnet/api-ni.c | 2 drivers/staging/lustre/lnet/lnet/lib-move.c | 217 +++++++++++--------- 5 files changed, 131 insertions(+), 98 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 0761fd533f8d..2d73aa1a121c 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -361,7 +361,7 @@ struct lnet_ni { struct lnet_element_stats ni_stats; /* physical device CPT */ - int dev_cpt; + int ni_dev_cpt; /* sequence number used to round robin over nis within a net */ u32 ni_seq; @@ -464,6 +464,8 @@ struct lnet_peer_ni { int lpni_rtr_refcount; /* sequence number used to round robin over peer nis within a net */ u32 lpni_seq; + /* sequence number used to round robin over gateways */ + __u32 lpni_gw_seq; /* health flag */ bool lpni_healthy; /* returned RC ping features. Protected with lpni_lock */ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 71256500f245..0ed29177819a 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2891,7 +2891,7 @@ static int kiblnd_startup(struct lnet_ni *ni) goto failed; node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device); - ni->dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); + ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); net->ibn_dev = ibdev; ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index c14711804d7b..2ec84a73c522 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2798,10 +2798,10 @@ ksocknal_startup(struct lnet_ni *ni) net->ksnn_interfaces[0].ksni_name); if (net_dev) { node_id = dev_to_node(&net_dev->dev); - ni->dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); + ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); dev_put(net_dev); } else { - ni->dev_cpt = CFS_CPT_ANY; + ni->ni_dev_cpt = CFS_CPT_ANY; } /* call it before add it to ksocknal_data.ksnd_nets */ diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 60176d05d34a..f57200eab746 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1910,7 +1910,7 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_ni *cfg_ni, cfg_ni->lic_nid = ni->ni_nid; cfg_ni->lic_status = ni->ni_status->ns_status; cfg_ni->lic_tcp_bonding = use_tcp_bonding; - cfg_ni->lic_dev_cpt = ni->dev_cpt; + cfg_ni->lic_dev_cpt = ni->ni_dev_cpt; memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn)); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 12bc80d060e9..141983f0ef83 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1130,6 +1130,69 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, return lpni_best; } +static struct lnet_ni * +lnet_get_best_ni(struct lnet_net *local_net, struct lnet_ni *cur_ni, + int md_cpt) +{ + struct lnet_ni *ni = NULL, *best_ni = cur_ni; + unsigned int shortest_distance; + int best_credits; + + if (!best_ni) { + shortest_distance = UINT_MAX; + best_credits = INT_MIN; + } else { + shortest_distance = cfs_cpt_distance(lnet_cpt_table(), md_cpt, + best_ni->ni_dev_cpt); + best_credits = atomic_read(&best_ni->ni_tx_credits); + } + + while ((ni = lnet_get_next_ni_locked(local_net, ni))) { + unsigned int distance; + int ni_credits; + + if (!lnet_is_ni_healthy_locked(ni)) + continue; + + ni_credits = atomic_read(&ni->ni_tx_credits); + + /* + * calculate the distance from the CPT on which + * the message memory is allocated to the CPT of + * the NI's physical device + */ + distance = cfs_cpt_distance(lnet_cpt_table(), + md_cpt, + ni->ni_dev_cpt); + + /* + * All distances smaller than the NUMA range + * are treated equally. + */ + if (distance < lnet_numa_range) + distance = lnet_numa_range; + + /* + * Select on shorter distance, then available + * credits, then round-robin. + */ + if (distance > shortest_distance) { + continue; + } else if (distance < shortest_distance) { + shortest_distance = distance; + } else if (ni_credits < best_credits) { + continue; + } else if (ni_credits == best_credits) { + if (best_ni && (best_ni)->ni_seq <= ni->ni_seq) + continue; + } + best_ni = ni; + best_credits = ni_credits; + } + + return best_ni; +} + static int lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) @@ -1138,20 +1201,19 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, struct lnet_peer_ni *best_lpni = NULL; struct lnet_peer_ni *best_gw = NULL; struct lnet_peer_ni *lpni; + struct lnet_peer_ni *final_dst; struct lnet_peer *peer; struct lnet_peer_net *peer_net; struct lnet_net *local_net; - struct lnet_ni *ni; __u32 seq; int cpt, cpt2, rc; bool routing; bool routing2; bool ni_is_pref; bool preferred; - int best_credits; + bool local_found; int best_lpni_credits; int md_cpt; - unsigned int shortest_distance; /* * get an initial CPT to use for locking. The idea here is not to @@ -1167,9 +1229,11 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, best_ni = NULL; best_lpni = NULL; best_gw = NULL; + final_dst = NULL; local_net = NULL; routing = false; routing2 = false; + local_found = false; seq = lnet_get_dlc_seq_locked(); @@ -1334,62 +1398,68 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, goto pick_peer; /* - * Decide whether we need to route to peer_ni. - * Get the local net that I need to be on to be able to directly - * send to that peer. + * pick the best_ni by going through all the possible networks of + * that peer and see which local NI is best suited to talk to that + * peer. * - * a. Find the peer which the dst_nid belongs to. - * b. Iterate through each of the peer_nets/nis to decide - * the best peer/local_ni pair to use + * Locally connected networks will always be preferred over + * a routed network. If there are only routed paths to the peer, + * then the best route is chosen. If all routes are equal then + * they are used in round robin. */ - shortest_distance = UINT_MAX; - best_credits = INT_MIN; list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_on_peer_list) { if (!lnet_is_peer_net_healthy_locked(peer_net)) continue; local_net = lnet_get_net_locked(peer_net->lpn_net_id); - if (!local_net && !routing) { + if (!local_net && !routing && !local_found) { struct lnet_peer_ni *net_gw; - /* - * go through each peer_ni on that peer_net and - * determine the best possible gw to go through - */ - list_for_each_entry(lpni, &peer_net->lpn_peer_nis, - lpni_on_peer_net_list) { - net_gw = lnet_find_route_locked(NULL, - lpni->lpni_nid, - rtr_nid); + lpni = list_entry(peer_net->lpn_peer_nis.next, + struct lnet_peer_ni, + lpni_on_peer_net_list); + + net_gw = lnet_find_route_locked(NULL, + lpni->lpni_nid, + rtr_nid); + if (!net_gw) + continue; + + if (best_gw) { /* - * if no route is found for that network then - * move onto the next peer_ni in the peer + * lnet_find_route_locked() call + * will return the best_Gw on the + * lpni->lpni_nid network. + * However, best_gw and net_gw can + * be on different networks. + * Therefore need to compare them + * to pick the better of either. */ - if (!net_gw) + if (lnet_compare_peers(best_gw, net_gw) > 0) + continue; + if (best_gw->lpni_gw_seq <= net_gw->lpni_gw_seq) continue; - - if (!best_gw) { - best_gw = net_gw; - } else { - rc = lnet_compare_peers(net_gw, - best_gw); - if (rc > 0) - best_gw = net_gw; - } } + best_gw = net_gw; + final_dst = lpni; - if (!best_gw) - continue; - - local_net = lnet_get_net_locked - (LNET_NIDNET(best_gw->lpni_nid)); routing2 = true; } else { - routing2 = false; best_gw = NULL; + final_dst = NULL; + routing2 = false; + local_found = true; } - /* no routable net found go on to a different net */ + /* + * a gw on this network is found, but there could be + * other better gateways on other networks. So don't pick + * the best_ni until we determine the best_gw. + */ + if (best_gw) + continue; + + /* if no local_net found continue */ if (!local_net) continue; @@ -1401,70 +1471,30 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * 2. NI available credits * 3. Round Robin */ - ni = NULL; - while ((ni = lnet_get_next_ni_locked(local_net, ni))) { - int ni_credits; - unsigned int distance; - - if (!lnet_is_ni_healthy_locked(ni)) - continue; - - ni_credits = atomic_read(&ni->ni_tx_credits); - - /* - * calculate the distance from the CPT on which - * the message memory is allocated to the CPT of - * the NI's physical device - */ - distance = cfs_cpt_distance(lnet_cpt_table(), - md_cpt, - ni->dev_cpt); - - /* - * All distances smaller than the NUMA range - * are treated equally. - */ - if (distance < lnet_numa_range) - distance = lnet_numa_range; + best_ni = lnet_get_best_ni(local_net, best_ni, md_cpt); + } - /* - * Select on shorter distance, then available - * credits, then round-robin. - */ - if (distance > shortest_distance) { - continue; - } else if (distance < shortest_distance) { - shortest_distance = distance; - } else if (ni_credits < best_credits) { - continue; - } else if (ni_credits == best_credits) { - if (best_ni && best_ni->ni_seq <= ni->ni_seq) - continue; - } - best_ni = ni; - best_credits = ni_credits; - } + if (!best_ni && !best_gw) { + lnet_net_unlock(cpt); + LCONSOLE_WARN("No local ni found to send from to %s\n", + libcfs_nid2str(dst_nid)); + return -EINVAL; } - if (routing2) { + if (!best_ni) { + best_ni = lnet_get_best_ni(best_gw->lpni_net, best_ni, md_cpt); + LASSERT(best_gw && best_ni); + /* - * RULE: Each node considers only the next-hop - * * We're going to route the message, so change the peer to * the router. */ LASSERT(best_gw->lpni_peer_net); LASSERT(best_gw->lpni_peer_net->lpn_peer); + best_gw->lpni_gw_seq++; peer = best_gw->lpni_peer_net->lpn_peer; } - if (!best_ni) { - lnet_net_unlock(cpt); - LCONSOLE_WARN("No local ni found to send from to %s\n", - libcfs_nid2str(dst_nid)); - return -EINVAL; - } - /* * Now that we selected the NI to use increment its sequence * number so the Round Robin algorithm will detect that it has @@ -1674,7 +1704,8 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * the router receives this message it knows how to route * it. */ - msg->msg_hdr.dest_nid = cpu_to_le64(dst_nid); + msg->msg_hdr.dest_nid = + cpu_to_le64(final_dst ? final_dst->lpni_nid : dst_nid); } else { /* * if we're not routing set the dest_nid to the best peer From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 28/34] LU-7734 lnet: Fix crash in router_proc.c In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763594.32103.9029692452686853485.stgit@noble> From: Amir Shehata Fixed NULL access in the case when a peer is a remote peer. In that case lpni_net is NULL. Signed-off-by: Amir Shehata Change-Id: Ida234ff016b2bdc305acf74df0f99600d2555e27 Reviewed-on: http://review.whamcloud.com/21327 Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/router_proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index 977a937f261c..a887ca446d42 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -492,7 +492,8 @@ static int proc_lnet_peers(struct ctl_table *table, int write, int nrefs = atomic_read(&peer->lpni_refcount); time64_t lastalive = -1; char *aliveness = "NA"; - int maxcr = peer->lpni_net->net_tunables.lct_peer_tx_credits; + int maxcr = peer->lpni_net ? + peer->lpni_net->net_tunables.lct_peer_tx_credits : 0; int txcr = peer->lpni_txcredits; int mintxcr = peer->lpni_mintxcredits; int rtrcr = peer->lpni_rtrcredits; From neilb at suse.com Tue Sep 25 01:07:16 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:16 +1000 Subject: [lustre-devel] [PATCH 29/34] LU-7734 lnet: double free in lnet_add_net_common() In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763597.32103.14845230051684461634.stgit@noble> From: Olaf Weber lnet_startup_lndnet() always consumes its net parameter, so we should not free net after the function has been called. This fixes a double free triggered by adding a network twice. Eliminate the netl local variable. Signed-off-by: Olaf Weber Change-Id: I1cfc3494eada4660b792f6a1ebd96b5dc80d9945 Reviewed-on: http://review.whamcloud.com/21446 Reviewed-by: Amir Shehata Tested-by: Amir Shehata Signed-off-by: NeilBrown --- drivers/staging/lustre/lnet/lnet/api-ni.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index f57200eab746..ea27d38f78c5 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -2143,7 +2143,6 @@ lnet_get_ni_config(struct lnet_ioctl_config_ni *cfg_ni, static int lnet_add_net_common(struct lnet_net *net, struct lnet_ioctl_config_lnd_tunables *tun) { - struct lnet_net *netl = NULL; u32 net_id; struct lnet_ping_info *pinfo; struct lnet_handle_md md_handle; @@ -2162,8 +2161,8 @@ static int lnet_add_net_common(struct lnet_net *net, if (rnet) { CERROR("Adding net %s will invalidate routing configuration\n", libcfs_net2str(net->net_id)); - rc = -EUSERS; - goto failed1; + lnet_net_free(net); + return -EUSERS; } /* @@ -2180,8 +2179,11 @@ static int lnet_add_net_common(struct lnet_net *net, rc = lnet_ping_info_setup(&pinfo, &md_handle, net_ni_count + lnet_get_ni_count(), false); - if (rc < 0) - goto failed1; + if (rc < 0) { + lnet_net_free(net); + return rc; + } + if (tun) memcpy(&net->net_tunables, &tun->lt_cmn, sizeof(net->net_tunables)); @@ -2204,17 +2206,16 @@ static int lnet_add_net_common(struct lnet_net *net, goto failed; lnet_net_lock(LNET_LOCK_EX); - netl = lnet_get_net_locked(net_id); + net = lnet_get_net_locked(net_id); lnet_net_unlock(LNET_LOCK_EX); - LASSERT(netl); + LASSERT(net); /* * Start the acceptor thread if this is the first network * being added that requires the thread. */ - if (netl->net_lnd->lnd_accept && - num_acceptor_nets == 0) { + if (net->net_lnd->lnd_accept && num_acceptor_nets == 0) { rc = lnet_acceptor_start(); if (rc < 0) { /* shutdown the net that we just started */ @@ -2225,7 +2226,7 @@ static int lnet_add_net_common(struct lnet_net *net, } lnet_net_lock(LNET_LOCK_EX); - lnet_peer_net_added(netl); + lnet_peer_net_added(net); lnet_net_unlock(LNET_LOCK_EX); lnet_ping_target_update(pinfo, md_handle); @@ -2235,8 +2236,6 @@ static int lnet_add_net_common(struct lnet_net *net, failed: lnet_ping_md_unlink(pinfo, &md_handle); lnet_ping_info_free(pinfo); -failed1: - lnet_net_free(net); return rc; } From neilb at suse.com Tue Sep 25 01:07:16 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:16 +1000 Subject: [lustre-devel] [PATCH 30/34] LU-7734 lnet: set primary NID in ptlrpc_connection_get() In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763601.32103.9360668949112667310.stgit@noble> From: Olaf Weber Set the NID in ptlrpc_connection::c_peer to the primary NID of a peer. This ensures that regardless of the NID used to start a connection, we consistently use the same NID (the primary NID) to identify a peer. It also means that PtlRPC will not create multiple connections to a peer. The primary NID is obtained by calling LNetPrimaryNID(), an addition to the exported symbols of the LNet module. The name was chosen to match the existing naming pattern. Test-Parameters: trivial Signed-off-by: Olaf Weber Change-Id: Idc0605d17a58678b634db246221028cf81ad2407 Reviewed-on: http://review.whamcloud.com/21710 Tested-by: Maloo Reviewed-by: Amir Shehata Tested-by: Amir Shehata Signed-off-by: NeilBrown --- drivers/staging/lustre/include/linux/lnet/api.h | 1 + drivers/staging/lustre/lnet/lnet/peer.c | 25 +++++++++++++++++++++ drivers/staging/lustre/lustre/ptlrpc/connection.c | 1 + 3 files changed, 27 insertions(+) diff --git a/drivers/staging/lustre/include/linux/lnet/api.h b/drivers/staging/lustre/include/linux/lnet/api.h index 22429213c023..70c991990474 100644 --- a/drivers/staging/lustre/include/linux/lnet/api.h +++ b/drivers/staging/lustre/include/linux/lnet/api.h @@ -77,6 +77,7 @@ int LNetNIFini(void); */ int LNetGetId(unsigned int index, struct lnet_process_id *id); int LNetDist(lnet_nid_t nid, lnet_nid_t *srcnid, __u32 *order); +lnet_nid_t LNetPrimaryNID(lnet_nid_t nid); /** @} lnet_addr */ diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index d757f4df1f39..747a4fc8d39f 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -610,6 +610,31 @@ lnet_peer_primary_nid(lnet_nid_t nid) return primary_nid; } +lnet_nid_t +LNetPrimaryNID(lnet_nid_t nid) +{ + struct lnet_peer_ni *lpni; + lnet_nid_t primary_nid = nid; + int rc = 0; + int cpt; + + cpt = lnet_net_lock_current(); + lpni = lnet_nid2peerni_locked(nid, cpt); + if (IS_ERR(lpni)) { + rc = PTR_ERR(lpni); + goto out_unlock; + } + primary_nid = lpni->lpni_peer_net->lpn_peer->lp_primary_nid; + lnet_peer_ni_decref_locked(lpni); +out_unlock: + lnet_net_unlock(cpt); + + CDEBUG(D_NET, "NID %s primary NID %s rc %d\n", libcfs_nid2str(nid), + libcfs_nid2str(primary_nid), rc); + return primary_nid; +} +EXPORT_SYMBOL(LNetPrimaryNID); + struct lnet_peer_net * lnet_peer_get_net_locked(struct lnet_peer *peer, u32 net_id) { diff --git a/drivers/staging/lustre/lustre/ptlrpc/connection.c b/drivers/staging/lustre/lustre/ptlrpc/connection.c index fb35a89ca6c6..ca9b4caf44b3 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/connection.c +++ b/drivers/staging/lustre/lustre/ptlrpc/connection.c @@ -80,6 +80,7 @@ ptlrpc_connection_get(struct lnet_process_id peer, lnet_nid_t self, { struct ptlrpc_connection *conn, *conn2; + peer.nid = LNetPrimaryNID(peer.nid); conn = rhashtable_lookup_fast(&conn_hash, &peer, conn_hash_params); if (conn) { ptlrpc_connection_addref(conn); From neilb at suse.com Tue Sep 25 01:07:16 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:16 +1000 Subject: [lustre-devel] [PATCH 31/34] LU-7734 lnet: fix NULL access in lnet_peer_aliveness_enabled In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763604.32103.1694406227193499062.stgit@noble> From: Amir Shehata When a peer is not on a local network, lpni->lpni_net is NULL. The lpni_net is access in lnet_peer_aliveness_enabled() without checking if it's NULL. Fixed. Test-Parameters: trivial Signed-off-by: Amir Shehata Change-Id: If328728e2bda2a19b273140a20c04b22bdda6bc4 Reviewed-on: http://review.whamcloud.com/22183 Tested-by: Maloo Reviewed-by: Olaf Weber Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 2d73aa1a121c..f811f125dfcb 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -534,6 +534,7 @@ struct lnet_peer_table { */ #define lnet_peer_aliveness_enabled(lp) \ (the_lnet.ln_routing && \ + (lp)->lpni_net && \ (lp)->lpni_net->net_tunables.lct_peer_timeout > 0) struct lnet_route { From neilb at suse.com Tue Sep 25 01:07:16 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:16 +1000 Subject: [lustre-devel] [PATCH 32/34] LU-7734 lnet: rename peer key_nid to prim_nid In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763608.32103.13444702792250303421.stgit@noble> From: Amir Shehata To make the interface clear, renamed key_nid to prim_nid to indicate that this parameter refers to the peer's primary nid. Signed-off-by: Amir Shehata Change-Id: I74bd17cdd55ba8d2c52bc28557db149d23ecbfb5 Reviewed-on: http://review.whamcloud.com/23460 Tested-by: Maloo Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Signed-off-by: NeilBrown --- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 2 - drivers/staging/lustre/lnet/lnet/api-ni.c | 6 +-- drivers/staging/lustre/lnet/lnet/peer.c | 42 ++++++++++---------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index a5e94619d3f1..d1e2911ab342 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -216,7 +216,7 @@ struct lnet_ioctl_dbg { struct lnet_ioctl_peer_cfg { struct libcfs_ioctl_hdr prcfg_hdr; - lnet_nid_t prcfg_key_nid; + lnet_nid_t prcfg_prim_nid; lnet_nid_t prcfg_cfg_nid; __u32 prcfg_idx; bool prcfg_mr; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index ea27d38f78c5..9a09927c346a 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -2728,7 +2728,7 @@ LNetCtl(unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&the_lnet.ln_api_mutex); - rc = lnet_add_peer_ni_to_peer(cfg->prcfg_key_nid, + rc = lnet_add_peer_ni_to_peer(cfg->prcfg_prim_nid, cfg->prcfg_cfg_nid, cfg->prcfg_mr); mutex_unlock(&the_lnet.ln_api_mutex); @@ -2742,7 +2742,7 @@ LNetCtl(unsigned int cmd, void *arg) return -EINVAL; mutex_lock(&the_lnet.ln_api_mutex); - rc = lnet_del_peer_ni_from_peer(cfg->prcfg_key_nid, + rc = lnet_del_peer_ni_from_peer(cfg->prcfg_prim_nid, cfg->prcfg_cfg_nid); mutex_unlock(&the_lnet.ln_api_mutex); return rc; @@ -2785,7 +2785,7 @@ LNetCtl(unsigned int cmd, void *arg) (cfg->prcfg_bulk + sizeof(*lpni_cri)); mutex_lock(&the_lnet.ln_api_mutex); - rc = lnet_get_peer_info(cfg->prcfg_idx, &cfg->prcfg_key_nid, + rc = lnet_get_peer_info(cfg->prcfg_idx, &cfg->prcfg_prim_nid, &cfg->prcfg_cfg_nid, &cfg->prcfg_mr, lpni_cri, lpni_stats); mutex_unlock(&the_lnet.ln_api_mutex); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 747a4fc8d39f..3a5f9dbf5c96 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -781,18 +781,18 @@ lnet_add_prim_lpni(lnet_nid_t nid) } static int -lnet_add_peer_ni_to_prim_lpni(lnet_nid_t key_nid, lnet_nid_t nid) +lnet_add_peer_ni_to_prim_lpni(lnet_nid_t prim_nid, lnet_nid_t nid) { struct lnet_peer *peer, *primary_peer; struct lnet_peer_ni *lpni = NULL, *klpni = NULL; - LASSERT(key_nid != LNET_NID_ANY && nid != LNET_NID_ANY); + LASSERT(prim_nid != LNET_NID_ANY && nid != LNET_NID_ANY); /* * key nid must be created by this point. If not then this * operation is not permitted */ - klpni = lnet_find_peer_ni_locked(key_nid); + klpni = lnet_find_peer_ni_locked(prim_nid); if (!klpni) return -ENOENT; @@ -809,13 +809,13 @@ lnet_add_peer_ni_to_prim_lpni(lnet_nid_t key_nid, lnet_nid_t nid) * lpni already exists in the system but it belongs to * a different peer. We can't re-added it */ - if (peer->lp_primary_nid != key_nid && peer->lp_multi_rail) { + if (peer->lp_primary_nid != prim_nid && peer->lp_multi_rail) { CERROR("Cannot add NID %s owned by peer %s to peer %s\n", libcfs_nid2str(lpni->lpni_nid), libcfs_nid2str(peer->lp_primary_nid), - libcfs_nid2str(key_nid)); + libcfs_nid2str(prim_nid)); return -EEXIST; - } else if (peer->lp_primary_nid == key_nid) { + } else if (peer->lp_primary_nid == prim_nid) { /* * found a peer_ni that is already part of the * peer. This is a no-op operation. @@ -824,7 +824,7 @@ lnet_add_peer_ni_to_prim_lpni(lnet_nid_t key_nid, lnet_nid_t nid) } /* - * TODO: else if (peer->lp_primary_nid != key_nid && + * TODO: else if (peer->lp_primary_nid != prim_nid && * !peer->lp_multi_rail) * peer is not an MR peer and it will be moved in the next * step to klpni, so update its flags accordingly. @@ -895,55 +895,55 @@ lnet_peer_ni_add_non_mr(lnet_nid_t nid) /* * This API handles the following combinations: - * Create a primary NI if only the key_nid is provided + * Create a primary NI if only the prim_nid is provided * Create or add an lpni to a primary NI. Primary NI must've already * been created * Create a non-MR peer. */ int -lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr) +lnet_add_peer_ni_to_peer(lnet_nid_t prim_nid, lnet_nid_t nid, bool mr) { /* * Caller trying to setup an MR like peer hierarchy but * specifying it to be non-MR. This is not allowed. */ - if (key_nid != LNET_NID_ANY && + if (prim_nid != LNET_NID_ANY && nid != LNET_NID_ANY && !mr) return -EPERM; /* Add the primary NID of a peer */ - if (key_nid != LNET_NID_ANY && + if (prim_nid != LNET_NID_ANY && nid == LNET_NID_ANY && mr) - return lnet_add_prim_lpni(key_nid); + return lnet_add_prim_lpni(prim_nid); /* Add a NID to an existing peer */ - if (key_nid != LNET_NID_ANY && + if (prim_nid != LNET_NID_ANY && nid != LNET_NID_ANY && mr) - return lnet_add_peer_ni_to_prim_lpni(key_nid, nid); + return lnet_add_peer_ni_to_prim_lpni(prim_nid, nid); /* Add a non-MR peer NI */ - if (((key_nid != LNET_NID_ANY && + if (((prim_nid != LNET_NID_ANY && nid == LNET_NID_ANY) || - (key_nid == LNET_NID_ANY && + (prim_nid == LNET_NID_ANY && nid != LNET_NID_ANY)) && !mr) - return lnet_peer_ni_add_non_mr(key_nid != LNET_NID_ANY ? - key_nid : nid); + return lnet_peer_ni_add_non_mr(prim_nid != LNET_NID_ANY ? + prim_nid : nid); return 0; } int -lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid) +lnet_del_peer_ni_from_peer(lnet_nid_t prim_nid, lnet_nid_t nid) { lnet_nid_t local_nid; struct lnet_peer *peer; struct lnet_peer_ni *lpni; int rc; - if (key_nid == LNET_NID_ANY) + if (prim_nid == LNET_NID_ANY) return -EINVAL; - local_nid = (nid != LNET_NID_ANY) ? nid : key_nid; + local_nid = (nid != LNET_NID_ANY) ? nid : prim_nid; lpni = lnet_find_peer_ni_locked(local_nid); if (!lpni) From neilb at suse.com Tue Sep 25 01:07:16 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:16 +1000 Subject: [lustre-devel] [PATCH 33/34] lnet: use BIT() macro for LNET_MD_* flags In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763611.32103.14845537928418369718.stgit@noble> As these are bit flags, it aids clarity to use the BIT() macro. Signed-off-by: NeilBrown --- .../lustre/include/uapi/linux/lnet/lnet-types.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h index e80ef4182e5d..62f062c0d1bf 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h @@ -483,22 +483,22 @@ struct lnet_md { /** * Options for the MD structure. See lnet_md::options. */ -#define LNET_MD_OP_PUT (1 << 0) +#define LNET_MD_OP_PUT BIT(0) /** See lnet_md::options. */ -#define LNET_MD_OP_GET (1 << 1) +#define LNET_MD_OP_GET BIT(1) /** See lnet_md::options. */ -#define LNET_MD_MANAGE_REMOTE (1 << 2) -/* unused (1 << 3) */ +#define LNET_MD_MANAGE_REMOTE BIT(2) +/* unused BIT(3) */ /** See lnet_md::options. */ -#define LNET_MD_TRUNCATE (1 << 4) +#define LNET_MD_TRUNCATE BIT(4) /** See lnet_md::options. */ -#define LNET_MD_ACK_DISABLE (1 << 5) +#define LNET_MD_ACK_DISABLE BIT(5) /** See lnet_md::options. */ -#define LNET_MD_IOVEC (1 << 6) +#define LNET_MD_IOVEC BIT(6) /** See lnet_md::options. */ -#define LNET_MD_MAX_SIZE (1 << 7) +#define LNET_MD_MAX_SIZE BIT(7) /** See lnet_md::options. */ -#define LNET_MD_KIOV (1 << 8) +#define LNET_MD_KIOV BIT(8) /* For compatibility with Cray Portals */ #define LNET_MD_PHYS 0 From neilb at suse.com Tue Sep 25 01:07:16 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:16 +1000 Subject: [lustre-devel] [PATCH 34/34] LU-7734 lnet: cpt locking In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763614.32103.8503784699321046646.stgit@noble> From: Amir Shehata When source nid is specified it is necessary to also use the destination nid. Otherwise bulk transfer will end up on a different interface than the nearest interface to the memory. This has significant performance impact on NUMA systems such as the SGI UV. The CPT which the MD describing the bulk buffers belongs to is not the same CPT of the actual pages of memory. Therefore, it is necessary to communicate the CPT of the pages to LNet, in order for LNet to select the nearest interface. The MD which describes the pages of memory gets attached to an ME, to be matched later on. The MD which describes the message to be sent is different and this patch adds the handle of the bulk MD into the MD which ends up being accessible by lnet_select_pathway(). In that function a new API, lnet_cpt_of_md_page(), is called which returns the CPT of the buffers used for the bulk transfer. lnet_select_pathway() proceeds to use this CPT to select the nearest interface. Signed-off-by: Amir Shehata Change-Id: I4117ef912835f16dcdcaafb70703f92d74053b9b Reviewed-on: https://review.whamcloud.com/24085 Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + .../staging/lustre/include/linux/lnet/lib-types.h | 1 + .../lustre/include/uapi/linux/lnet/lnet-types.h | 12 ++++++++ drivers/staging/lustre/lnet/lnet/lib-md.c | 31 ++++++++++++++++++++ drivers/staging/lustre/lnet/lnet/lib-move.c | 20 ++++++++----- drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 26 +++++++++++++---- 6 files changed, 78 insertions(+), 13 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 3a53d54b711d..aedc88c69977 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -595,6 +595,7 @@ void lnet_me_unlink(struct lnet_me *me); void lnet_md_unlink(struct lnet_libmd *md); void lnet_md_deconstruct(struct lnet_libmd *lmd, struct lnet_md *umd); +int lnet_cpt_of_md(struct lnet_libmd *md); void lnet_register_lnd(struct lnet_lnd *lnd); void lnet_unregister_lnd(struct lnet_lnd *lnd); diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index f811f125dfcb..18e2665ad74d 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -161,6 +161,7 @@ struct lnet_libmd { void *md_user_ptr; struct lnet_eq *md_eq; unsigned int md_niov; /* # frags */ + struct lnet_handle_md md_bulk_handle; union { struct kvec iov[LNET_MAX_IOV]; struct bio_vec kiov[LNET_MAX_IOV]; diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h index 62f062c0d1bf..837e5fe25ac1 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h @@ -444,6 +444,7 @@ struct lnet_md { * - LNET_MD_IOVEC: The start and length fields specify an array of * struct iovec. * - LNET_MD_MAX_SIZE: The max_size field is valid. + * - LNET_MD_BULK_HANDLE: The bulk_handle field is valid. * * Note: * - LNET_MD_KIOV or LNET_MD_IOVEC allows for a scatter/gather @@ -467,6 +468,15 @@ struct lnet_md { * descriptor are not logged. */ struct lnet_handle_eq eq_handle; + /** + * The bulk MD handle which was registered to describe the buffers + * either to be used to transfer data to the peer or receive data + * from the peer. This allows LNet to properly determine the NUMA + * node on which the memory was allocated and use that to select the + * nearest local network interface. This value is only used + * if the LNET_MD_BULK_HANDLE option is set. + */ + struct lnet_handle_md bulk_handle; }; /* @@ -499,6 +509,8 @@ struct lnet_md { #define LNET_MD_MAX_SIZE BIT(7) /** See lnet_md::options. */ #define LNET_MD_KIOV BIT(8) +/** See lnet_md::options. */ +#define LNET_MD_BULK_HANDLE BIT(9) /* For compatibility with Cray Portals */ #define LNET_MD_PHYS 0 diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c index 8a22514aaf71..9e26911cd319 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-md.c +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c @@ -84,6 +84,36 @@ lnet_md_unlink(struct lnet_libmd *md) kfree(md); } +int +lnet_cpt_of_md(struct lnet_libmd *md) +{ + int cpt = CFS_CPT_ANY; + + if (!md) + return CFS_CPT_ANY; + + if ((md->md_options & LNET_MD_BULK_HANDLE) != 0 && + md->md_bulk_handle.cookie != LNET_WIRE_HANDLE_COOKIE_NONE) { + md = lnet_handle2md(&md->md_bulk_handle); + + if (!md) + return CFS_CPT_ANY; + } + + if ((md->md_options & LNET_MD_KIOV) != 0) { + if (md->md_iov.kiov[0].bv_page) + cpt = cfs_cpt_of_node( + lnet_cpt_table(), + page_to_nid(md->md_iov.kiov[0].bv_page)); + } else if (md->md_iov.iov[0].iov_base) { + cpt = cfs_cpt_of_node( + lnet_cpt_table(), + page_to_nid(virt_to_page(md->md_iov.iov[0].iov_base))); + } + + return cpt; +} + static int lnet_md_build(struct lnet_libmd *lmd, struct lnet_md *umd, int unlink) { @@ -101,6 +131,7 @@ lnet_md_build(struct lnet_libmd *lmd, struct lnet_md *umd, int unlink) lmd->md_threshold = umd->threshold; lmd->md_refcount = 0; lmd->md_flags = (unlink == LNET_UNLINK) ? LNET_MD_FLAG_AUTO_UNLINK : 0; + lmd->md_bulk_handle = umd->bulk_handle; if (umd->options & LNET_MD_IOVEC) { if (umd->options & LNET_MD_KIOV) /* Can't specify both */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 141983f0ef83..d39331fcf932 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1225,6 +1225,11 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * then we proceed, if there is, then we restart the operation. */ cpt = lnet_net_lock_current(); + + md_cpt = lnet_cpt_of_md(msg->msg_md); + if (md_cpt == CFS_CPT_ANY) + md_cpt = cpt; + again: best_ni = NULL; best_lpni = NULL; @@ -1242,12 +1247,6 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, return -ESHUTDOWN; } - if (msg->msg_md) - /* get the cpt of the MD, used during NUMA based selection */ - md_cpt = lnet_cpt_of_cookie(msg->msg_md->md_lh.lh_cookie); - else - md_cpt = CFS_CPT_ANY; - peer = lnet_find_or_create_peer_locked(dst_nid, cpt); if (IS_ERR(peer)) { lnet_net_unlock(cpt); @@ -1285,7 +1284,8 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, if (msg->msg_type == LNET_MSG_REPLY || msg->msg_type == LNET_MSG_ACK || - !peer->lp_multi_rail) { + !peer->lp_multi_rail || + best_ni) { /* * for replies we want to respond on the same peer_ni we * received the message on if possible. If not, then pick @@ -1294,6 +1294,12 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, * if the peer is non-multi-rail then you want to send to * the dst_nid provided as well. * + * If the best_ni has already been determined, IE the + * src_nid has been specified, then use the + * destination_nid provided as well, since we're + * continuing a series of related messages for the same + * RPC. + * * It is expected to find the lpni using dst_nid, since we * created it earlier. */ diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c index d0bcd8827f8a..415450d3c8c1 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c +++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c @@ -48,7 +48,8 @@ static int ptl_send_buf(struct lnet_handle_md *mdh, void *base, int len, enum lnet_ack_req ack, struct ptlrpc_cb_id *cbid, lnet_nid_t self, struct lnet_process_id peer_id, - int portal, __u64 xid, unsigned int offset) + int portal, __u64 xid, unsigned int offset, + struct lnet_handle_md *bulk_cookie) { int rc; struct lnet_md md; @@ -61,13 +62,17 @@ static int ptl_send_buf(struct lnet_handle_md *mdh, void *base, int len, md.options = PTLRPC_MD_OPTIONS; md.user_ptr = cbid; md.eq_handle = ptlrpc_eq_h; + md.bulk_handle.cookie = LNET_WIRE_HANDLE_COOKIE_NONE; + + if (bulk_cookie) { + md.bulk_handle = *bulk_cookie; + md.options |= LNET_MD_BULK_HANDLE; + } if (unlikely(ack == LNET_ACK_REQ && - OBD_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_ACK, - OBD_FAIL_ONCE))) { + OBD_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_ACK, OBD_FAIL_ONCE))) /* don't ask for the ack to simulate failing client */ ack = LNET_NOACK_REQ; - } rc = LNetMDBind(md, LNET_UNLINK, mdh); if (unlikely(rc != 0)) { @@ -417,7 +422,7 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags) LNET_ACK_REQ : LNET_NOACK_REQ, &rs->rs_cb_id, req->rq_self, req->rq_source, ptlrpc_req2svc(req)->srv_rep_portal, - req->rq_xid, req->rq_reply_off); + req->rq_xid, req->rq_reply_off, NULL); out: if (unlikely(rc != 0)) ptlrpc_req_drop_rs(req); @@ -474,12 +479,15 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) int rc; int rc2; unsigned int mpflag = 0; + struct lnet_handle_md bulk_cookie; struct ptlrpc_connection *connection; struct lnet_handle_me reply_me_h; struct lnet_md reply_md; struct obd_import *imp = request->rq_import; struct obd_device *obd = imp->imp_obd; + bulk_cookie.cookie = LNET_WIRE_HANDLE_COOKIE_NONE; + if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DROP_RPC)) return 0; @@ -577,6 +585,12 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) rc = ptlrpc_register_bulk(request); if (rc != 0) goto out; + /* + * All the mds in the request will have the same cpt + * encoded in the cookie. So we can just get the first + * one. + */ + bulk_cookie = request->rq_bulk->bd_mds[0]; } if (!noreply) { @@ -685,7 +699,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) LNET_NOACK_REQ, &request->rq_req_cbid, LNET_NID_ANY, connection->c_peer, request->rq_request_portal, - request->rq_xid, 0); + request->rq_xid, 0, &bulk_cookie); if (likely(rc == 0)) goto out; From jsimmons at infradead.org Tue Sep 25 03:37:30 2018 From: jsimmons at infradead.org (James Simmons) Date: Mon, 24 Sep 2018 23:37:30 -0400 Subject: [lustre-devel] [PATCH] lustre: lnet: copy the correct amountof cpts to lnet_cpts Message-ID: <1537846650-8490-1-git-send-email-jsimmons@infradead.org> The incorrect size was used in the memory copy of the requested cpts to net->lnet_cpts. This lead to the following in testing RIP: 0010:lnet_match2mt.isra.8+0x2b/0x40 [lnet] lnet_mt_of_attach+0x72/0x1b0 [lnet] LNetMEAttach+0x60/0x1f0 [lnet] ptl_send_rpc+0x26f/0xbb0 [ptlrpc] libcfs_debug_msg+0x57/0x80 [libcfs] ptlrpc_send_new_req+0x4c9/0x860 [ptlrpc] ptlrpc_check_set.part.21+0x855/0x18b0 [ptlrpc] ? try_to_del_timer_sync+0x4d/0x80 ? del_timer_sync+0x35/0x40 ptlrpcd_check+0x3ae/0x3f0 [ptlrpc] ptlrpcd+0x2be/0x320 [ptlrpc] ? wait_woken+0x80/0x80 Changing the size from ncpts to ncpts * sizeof(*net->net_cpts) Signed-off-by: James Simmons WC-bug-id: https://jira.whamcloud.com/browse/LU-11424 Reviewed-on: https://review.whamcloud.com/33229 --- drivers/staging/lustre/lnet/lnet/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index c11821a..4c22416 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -174,7 +174,7 @@ struct lnet_text_buf { /* tmp struct for parsing routes */ GFP_KERNEL); if (!net->net_cpts) return -ENOMEM; - memcpy(net->net_cpts, cpts, ncpts); + memcpy(net->net_cpts, cpts, ncpts * sizeof(*net->net_cpts)); net->net_ncpts = ncpts; return 0; } -- 1.8.3.1 From neilb at suse.com Tue Sep 25 01:07:15 2018 From: neilb at suse.com (NeilBrown) Date: Tue, 25 Sep 2018 11:07:15 +1000 Subject: [lustre-devel] [PATCH 16/34] LU-7734 lnet: rename LND peer to peer_ni In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: <153783763547.32103.18087278859321916658.stgit@noble> From: Amir Shehata Patch to rename LND peers to peer_ni to reflect the fact that these constructs reflect an actual connection between a local NI and remote peer NI. Signed-off-by: Amir Shehata Change-Id: I1c25a12eae61d8822a8c4ada2e077a5b2011ba22 Reviewed-on: http://review.whamcloud.com/19307 Reviewed-by: Doug Oucharek Tested-by: Doug Oucharek Signed-off-by: NeilBrown --- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 232 ++++--- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 118 ++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 512 ++++++++------- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 662 ++++++++++---------- .../staging/lustre/lnet/klnds/socklnd/socklnd.h | 66 +- .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 207 +++--- .../lustre/lnet/klnds/socklnd/socklnd_lib.c | 4 .../lustre/lnet/klnds/socklnd/socklnd_proto.c | 14 8 files changed, 928 insertions(+), 887 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 64df49146413..71256500f245 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -258,7 +258,7 @@ int kiblnd_unpack_msg(struct kib_msg *msg, int nob) msg->ibm_cksum = msg_cksum; if (flip) { - /* leave magic unflipped as a clue to peer endianness */ + /* leave magic unflipped as a clue to peer_ni endianness */ msg->ibm_version = version; BUILD_BUG_ON(sizeof(msg->ibm_type) != 1); BUILD_BUG_ON(sizeof(msg->ibm_credits) != 1); @@ -315,10 +315,10 @@ int kiblnd_unpack_msg(struct kib_msg *msg, int nob) return 0; } -int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, +int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer_ni **peerp, lnet_nid_t nid) { - struct kib_peer *peer; + struct kib_peer_ni *peer_ni; struct kib_net *net = ni->ni_data; int cpt = lnet_cpt_of_nid(nid, ni); unsigned long flags; @@ -326,23 +326,23 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, LASSERT(net); LASSERT(nid != LNET_NID_ANY); - peer = kzalloc_cpt(sizeof(*peer), GFP_NOFS, cpt); - if (!peer) { - CERROR("Cannot allocate peer\n"); + peer_ni = kzalloc_cpt(sizeof(*peer_ni), GFP_NOFS, cpt); + if (!peer_ni) { + CERROR("Cannot allocate peer_ni\n"); return -ENOMEM; } - peer->ibp_ni = ni; - peer->ibp_nid = nid; - peer->ibp_error = 0; - peer->ibp_last_alive = 0; - peer->ibp_max_frags = kiblnd_cfg_rdma_frags(peer->ibp_ni); - peer->ibp_queue_depth = ni->ni_net->net_tunables.lct_peer_tx_credits; - atomic_set(&peer->ibp_refcount, 1); /* 1 ref for caller */ + peer_ni->ibp_ni = ni; + peer_ni->ibp_nid = nid; + peer_ni->ibp_error = 0; + peer_ni->ibp_last_alive = 0; + peer_ni->ibp_max_frags = kiblnd_cfg_rdma_frags(peer_ni->ibp_ni); + peer_ni->ibp_queue_depth = ni->ni_net->net_tunables.lct_peer_tx_credits; + atomic_set(&peer_ni->ibp_refcount, 1); /* 1 ref for caller */ - INIT_LIST_HEAD(&peer->ibp_list); /* not in the peer table yet */ - INIT_LIST_HEAD(&peer->ibp_conns); - INIT_LIST_HEAD(&peer->ibp_tx_queue); + INIT_LIST_HEAD(&peer_ni->ibp_list); + INIT_LIST_HEAD(&peer_ni->ibp_conns); + INIT_LIST_HEAD(&peer_ni->ibp_tx_queue); write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); @@ -354,93 +354,94 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); - *peerp = peer; + *peerp = peer_ni; return 0; } -void kiblnd_destroy_peer(struct kib_peer *peer) +void kiblnd_destroy_peer(struct kib_peer_ni *peer_ni) { - struct kib_net *net = peer->ibp_ni->ni_data; + struct kib_net *net = peer_ni->ibp_ni->ni_data; LASSERT(net); - LASSERT(!atomic_read(&peer->ibp_refcount)); - LASSERT(!kiblnd_peer_active(peer)); - LASSERT(kiblnd_peer_idle(peer)); - LASSERT(list_empty(&peer->ibp_tx_queue)); + LASSERT(!atomic_read(&peer_ni->ibp_refcount)); + LASSERT(!kiblnd_peer_active(peer_ni)); + LASSERT(kiblnd_peer_idle(peer_ni)); + LASSERT(list_empty(&peer_ni->ibp_tx_queue)); - kfree(peer); + kfree(peer_ni); /* - * NB a peer's connections keep a reference on their peer until + * NB a peer_ni's connections keep a reference on their peer_ni until * they are destroyed, so we can be assured that _all_ state to do - * with this peer has been cleaned up when its refcount drops to + * with this peer_ni has been cleaned up when its refcount drops to * zero. */ atomic_dec(&net->ibn_npeers); } -struct kib_peer *kiblnd_find_peer_locked(struct lnet_ni *ni, lnet_nid_t nid) +struct kib_peer_ni *kiblnd_find_peer_locked(struct lnet_ni *ni, lnet_nid_t nid) { /* * the caller is responsible for accounting the additional reference * that this creates */ struct list_head *peer_list = kiblnd_nid2peerlist(nid); - struct kib_peer *peer; + struct kib_peer_ni *peer_ni; - list_for_each_entry(peer, peer_list, ibp_list) { - LASSERT(!kiblnd_peer_idle(peer)); + list_for_each_entry(peer_ni, peer_list, ibp_list) { + LASSERT(!kiblnd_peer_idle(peer_ni)); /* - * Match a peer if its NID and the NID of the local NI it + * Match a peer_ni if its NID and the NID of the local NI it * communicates over are the same. Otherwise don't match - * the peer, which will result in a new lnd peer being + * the peer_ni, which will result in a new lnd peer_ni being * created. */ - if (peer->ibp_nid != nid || - peer->ibp_ni->ni_nid != ni->ni_nid) + if (peer_ni->ibp_nid != nid || + peer_ni->ibp_ni->ni_nid != ni->ni_nid) continue; - CDEBUG(D_NET, "got peer [%p] -> %s (%d) version: %x\n", - peer, libcfs_nid2str(nid), - atomic_read(&peer->ibp_refcount), - peer->ibp_version); - return peer; + CDEBUG(D_NET, "got peer_ni [%p] -> %s (%d) version: %x\n", + peer_ni, libcfs_nid2str(nid), + atomic_read(&peer_ni->ibp_refcount), + peer_ni->ibp_version); + return peer_ni; } return NULL; } -void kiblnd_unlink_peer_locked(struct kib_peer *peer) +void kiblnd_unlink_peer_locked(struct kib_peer_ni *peer_ni) { - LASSERT(list_empty(&peer->ibp_conns)); + LASSERT(list_empty(&peer_ni->ibp_conns)); - LASSERT(kiblnd_peer_active(peer)); - list_del_init(&peer->ibp_list); + LASSERT(kiblnd_peer_active(peer_ni)); + list_del_init(&peer_ni->ibp_list); /* lose peerlist's ref */ - kiblnd_peer_decref(peer); + kiblnd_peer_decref(peer_ni); } static int kiblnd_get_peer_info(struct lnet_ni *ni, int index, lnet_nid_t *nidp, int *count) { - struct kib_peer *peer; + struct kib_peer_ni *peer_ni; int i; unsigned long flags; read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) { - list_for_each_entry(peer, &kiblnd_data.kib_peers[i], ibp_list) { - LASSERT(!kiblnd_peer_idle(peer)); + list_for_each_entry(peer_ni, &kiblnd_data.kib_peers[i], + ibp_list) { + LASSERT(!kiblnd_peer_idle(peer_ni)); - if (peer->ibp_ni != ni) + if (peer_ni->ibp_ni != ni) continue; if (index-- > 0) continue; - *nidp = peer->ibp_nid; - *count = atomic_read(&peer->ibp_refcount); + *nidp = peer_ni->ibp_nid; + *count = atomic_read(&peer_ni->ibp_refcount); read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); @@ -452,34 +453,33 @@ static int kiblnd_get_peer_info(struct lnet_ni *ni, int index, return -ENOENT; } -static void kiblnd_del_peer_locked(struct kib_peer *peer) +static void kiblnd_del_peer_locked(struct kib_peer_ni *peer_ni) { struct list_head *ctmp; struct list_head *cnxt; struct kib_conn *conn; - if (list_empty(&peer->ibp_conns)) { - kiblnd_unlink_peer_locked(peer); + if (list_empty(&peer_ni->ibp_conns)) { + kiblnd_unlink_peer_locked(peer_ni); } else { - list_for_each_safe(ctmp, cnxt, &peer->ibp_conns) { + list_for_each_safe(ctmp, cnxt, &peer_ni->ibp_conns) { conn = list_entry(ctmp, struct kib_conn, ibc_list); kiblnd_close_conn_locked(conn, 0); } - /* NB closing peer's last conn unlinked it. */ + /* NB closing peer_ni's last conn unlinked it. */ } /* - * NB peer now unlinked; might even be freed if the peer table had the - * last ref on it. + * NB peer_ni now unlinked; might even be freed if the peer_ni + * table had the last ref on it. */ } static int kiblnd_del_peer(struct lnet_ni *ni, lnet_nid_t nid) { LIST_HEAD(zombies); - struct list_head *ptmp; - struct list_head *pnxt; - struct kib_peer *peer; + struct kib_peer_ni *pnxt; + struct kib_peer_ni *peer_ni; int lo; int hi; int i; @@ -497,24 +497,24 @@ static int kiblnd_del_peer(struct lnet_ni *ni, lnet_nid_t nid) } for (i = lo; i <= hi; i++) { - list_for_each_safe(ptmp, pnxt, &kiblnd_data.kib_peers[i]) { - peer = list_entry(ptmp, struct kib_peer, ibp_list); - LASSERT(!kiblnd_peer_idle(peer)); + list_for_each_entry_safe(peer_ni, pnxt, + &kiblnd_data.kib_peers[i], ibp_list) { + LASSERT(!kiblnd_peer_idle(peer_ni)); - if (peer->ibp_ni != ni) + if (peer_ni->ibp_ni != ni) continue; - if (!(nid == LNET_NID_ANY || peer->ibp_nid == nid)) + if (!(nid == LNET_NID_ANY || peer_ni->ibp_nid == nid)) continue; - if (!list_empty(&peer->ibp_tx_queue)) { - LASSERT(list_empty(&peer->ibp_conns)); + if (!list_empty(&peer_ni->ibp_tx_queue)) { + LASSERT(list_empty(&peer_ni->ibp_conns)); - list_splice_init(&peer->ibp_tx_queue, + list_splice_init(&peer_ni->ibp_tx_queue, &zombies); } - kiblnd_del_peer_locked(peer); + kiblnd_del_peer_locked(peer_ni); rc = 0; /* matched something */ } } @@ -528,7 +528,7 @@ static int kiblnd_del_peer(struct lnet_ni *ni, lnet_nid_t nid) static struct kib_conn *kiblnd_get_conn_by_idx(struct lnet_ni *ni, int index) { - struct kib_peer *peer; + struct kib_peer_ni *peer_ni; struct kib_conn *conn; int i; unsigned long flags; @@ -536,13 +536,15 @@ static struct kib_conn *kiblnd_get_conn_by_idx(struct lnet_ni *ni, int index) read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) { - list_for_each_entry(peer, &kiblnd_data.kib_peers[i], ibp_list) { - LASSERT(!kiblnd_peer_idle(peer)); + list_for_each_entry(peer_ni, &kiblnd_data.kib_peers[i], + ibp_list) { + LASSERT(!kiblnd_peer_idle(peer_ni)); - if (peer->ibp_ni != ni) + if (peer_ni->ibp_ni != ni) continue; - list_for_each_entry(conn, &peer->ibp_conns, ibc_list) { + list_for_each_entry(conn, &peer_ni->ibp_conns, + ibc_list) { if (index-- > 0) continue; @@ -620,20 +622,23 @@ static int kiblnd_get_completion_vector(struct kib_conn *conn, int cpt) return 1; } -struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cmid, +struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, + struct rdma_cm_id *cmid, int state, int version) { /* * CAVEAT EMPTOR: - * If the new conn is created successfully it takes over the caller's - * ref on 'peer'. It also "owns" 'cmid' and destroys it when it itself - * is destroyed. On failure, the caller's ref on 'peer' remains and - * she must dispose of 'cmid'. (Actually I'd block forever if I tried - * to destroy 'cmid' here since I'm called from the CM which still has + * + * If the new conn is created successfully it takes over the + * caller's ref on 'peer_ni'. It also "owns" 'cmid' and + * destroys it when it itself is destroyed. On failure, the + * caller's ref on 'peer_ni' remains and she must dispose of + * 'cmid'. (Actually I'd block forever if I tried to destroy + * 'cmid' here since I'm called from the CM which still has * its ref on 'cmid'). */ rwlock_t *glock = &kiblnd_data.kib_global_lock; - struct kib_net *net = peer->ibp_ni->ni_data; + struct kib_net *net = peer_ni->ibp_ni->ni_data; struct kib_dev *dev; struct ib_qp_init_attr *init_qp_attr; struct kib_sched_info *sched; @@ -650,7 +655,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm dev = net->ibn_dev; - cpt = lnet_cpt_of_nid(peer->ibp_nid, peer->ibp_ni); + cpt = lnet_cpt_of_nid(peer_ni->ibp_nid, peer_ni->ibp_ni); sched = kiblnd_data.kib_scheds[cpt]; LASSERT(sched->ibs_nthreads > 0); @@ -658,24 +663,24 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm init_qp_attr = kzalloc_cpt(sizeof(*init_qp_attr), GFP_NOFS, cpt); if (!init_qp_attr) { CERROR("Can't allocate qp_attr for %s\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); goto failed_0; } conn = kzalloc_cpt(sizeof(*conn), GFP_NOFS, cpt); if (!conn) { CERROR("Can't allocate connection for %s\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); goto failed_1; } conn->ibc_state = IBLND_CONN_INIT; conn->ibc_version = version; - conn->ibc_peer = peer; /* I take the caller's ref */ + conn->ibc_peer = peer_ni; /* I take the caller's ref */ cmid->context = conn; /* for future CM callbacks */ conn->ibc_cmid = cmid; - conn->ibc_max_frags = peer->ibp_max_frags; - conn->ibc_queue_depth = peer->ibp_queue_depth; + conn->ibc_max_frags = peer_ni->ibp_max_frags; + conn->ibc_queue_depth = peer_ni->ibp_queue_depth; INIT_LIST_HEAD(&conn->ibc_early_rxs); INIT_LIST_HEAD(&conn->ibc_tx_noops); @@ -834,7 +839,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm void kiblnd_destroy_conn(struct kib_conn *conn) { struct rdma_cm_id *cmid = conn->ibc_cmid; - struct kib_peer *peer = conn->ibc_peer; + struct kib_peer_ni *peer_ni = conn->ibc_peer; int rc; LASSERT(!in_interrupt()); @@ -883,26 +888,26 @@ void kiblnd_destroy_conn(struct kib_conn *conn) /* See CAVEAT EMPTOR above in kiblnd_create_conn */ if (conn->ibc_state != IBLND_CONN_INIT) { - struct kib_net *net = peer->ibp_ni->ni_data; + struct kib_net *net = peer_ni->ibp_ni->ni_data; - kiblnd_peer_decref(peer); + kiblnd_peer_decref(peer_ni); rdma_destroy_id(cmid); atomic_dec(&net->ibn_nconns); } } -int kiblnd_close_peer_conns_locked(struct kib_peer *peer, int why) +int kiblnd_close_peer_conns_locked(struct kib_peer_ni *peer_ni, int why) { struct kib_conn *conn; struct list_head *ctmp; struct list_head *cnxt; int count = 0; - list_for_each_safe(ctmp, cnxt, &peer->ibp_conns) { + list_for_each_safe(ctmp, cnxt, &peer_ni->ibp_conns) { conn = list_entry(ctmp, struct kib_conn, ibc_list); CDEBUG(D_NET, "Closing conn -> %s, version: %x, reason: %d\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), conn->ibc_version, why); kiblnd_close_conn_locked(conn, why); @@ -912,7 +917,7 @@ int kiblnd_close_peer_conns_locked(struct kib_peer *peer, int why) return count; } -int kiblnd_close_stale_conns_locked(struct kib_peer *peer, +int kiblnd_close_stale_conns_locked(struct kib_peer_ni *peer_ni, int version, __u64 incarnation) { struct kib_conn *conn; @@ -920,7 +925,7 @@ int kiblnd_close_stale_conns_locked(struct kib_peer *peer, struct list_head *cnxt; int count = 0; - list_for_each_safe(ctmp, cnxt, &peer->ibp_conns) { + list_for_each_safe(ctmp, cnxt, &peer_ni->ibp_conns) { conn = list_entry(ctmp, struct kib_conn, ibc_list); if (conn->ibc_version == version && @@ -929,7 +934,7 @@ int kiblnd_close_stale_conns_locked(struct kib_peer *peer, CDEBUG(D_NET, "Closing stale conn -> %s version: %x, incarnation:%#llx(%x, %#llx)\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), conn->ibc_version, conn->ibc_incarnation, version, incarnation); @@ -942,9 +947,8 @@ int kiblnd_close_stale_conns_locked(struct kib_peer *peer, static int kiblnd_close_matching_conns(struct lnet_ni *ni, lnet_nid_t nid) { - struct kib_peer *peer; - struct list_head *ptmp; - struct list_head *pnxt; + struct kib_peer_ni *peer_ni; + struct kib_peer_ni *pnxt; int lo; int hi; int i; @@ -962,17 +966,17 @@ static int kiblnd_close_matching_conns(struct lnet_ni *ni, lnet_nid_t nid) } for (i = lo; i <= hi; i++) { - list_for_each_safe(ptmp, pnxt, &kiblnd_data.kib_peers[i]) { - peer = list_entry(ptmp, struct kib_peer, ibp_list); - LASSERT(!kiblnd_peer_idle(peer)); + list_for_each_entry_safe(peer_ni, pnxt, + &kiblnd_data.kib_peers[i], ibp_list) { + LASSERT(!kiblnd_peer_idle(peer_ni)); - if (peer->ibp_ni != ni) + if (peer_ni->ibp_ni != ni) continue; - if (!(nid == LNET_NID_ANY || nid == peer->ibp_nid)) + if (!(nid == LNET_NID_ANY || nid == peer_ni->ibp_nid)) continue; - count += kiblnd_close_peer_conns_locked(peer, 0); + count += kiblnd_close_peer_conns_locked(peer_ni, 0); } } @@ -1043,14 +1047,14 @@ static void kiblnd_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when) time64_t last_alive = 0; time64_t now = ktime_get_seconds(); rwlock_t *glock = &kiblnd_data.kib_global_lock; - struct kib_peer *peer; + struct kib_peer_ni *peer_ni; unsigned long flags; read_lock_irqsave(glock, flags); - peer = kiblnd_find_peer_locked(ni, nid); - if (peer) - last_alive = peer->ibp_last_alive; + peer_ni = kiblnd_find_peer_locked(ni, nid); + if (peer_ni) + last_alive = peer_ni->ibp_last_alive; read_unlock_irqrestore(glock, flags); @@ -1058,14 +1062,14 @@ static void kiblnd_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when) *when = last_alive; /* - * peer is not persistent in hash, trigger peer creation + * peer_ni is not persistent in hash, trigger peer_ni creation * and connection establishment with a NULL tx */ - if (!peer) + if (!peer_ni) kiblnd_launch_tx(ni, NULL, nid); - CDEBUG(D_NET, "Peer %s %p, alive %lld secs ago\n", - libcfs_nid2str(nid), peer, + CDEBUG(D_NET, "peer_ni %s %p, alive %lld secs ago\n", + libcfs_nid2str(nid), peer_ni, last_alive ? now - last_alive : -1); } @@ -2595,7 +2599,7 @@ static void kiblnd_shutdown(struct lnet_ni *ni) /* nuke all existing peers within this net */ kiblnd_del_peer(ni, LNET_NID_ANY); - /* Wait for all peer state to clean up */ + /* Wait for all peer_ni state to clean up */ i = 2; while (atomic_read(&net->ibn_npeers)) { i++; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 520f586015f4..b1851b529ef8 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -66,7 +66,7 @@ #include -#define IBLND_PEER_HASH_SIZE 101 /* # peer lists */ +#define IBLND_PEER_HASH_SIZE 101 /* # peer_ni lists */ /* # scheduler loops before reschedule */ #define IBLND_RESCHED 100 @@ -96,8 +96,9 @@ extern struct kib_tunables kiblnd_tunables; #define IBLND_MSG_QUEUE_SIZE_V1 8 /* V1 only : # messages/RDMAs in-flight */ #define IBLND_CREDIT_HIGHWATER_V1 7 /* V1 only : when eagerly to return credits */ -#define IBLND_CREDITS_DEFAULT 8 /* default # of peer credits */ -#define IBLND_CREDITS_MAX ((typeof(((struct kib_msg *)0)->ibm_credits)) - 1) /* Max # of peer credits */ +#define IBLND_CREDITS_DEFAULT 8 /* default # of peer_ni credits */ +/* Max # of peer_ni credits */ +#define IBLND_CREDITS_MAX ((typeof(((struct kib_msg *)0)->ibm_credits)) - 1) /* when eagerly to return credits */ #define IBLND_CREDITS_HIGHWATER(t, v) ((v) == IBLND_MSG_VERSION_1 ? \ @@ -324,7 +325,7 @@ struct kib_data { struct list_head kib_failed_devs; /* list head of failed devices */ wait_queue_head_t kib_failover_waitq; /* schedulers sleep here */ atomic_t kib_nthreads; /* # live threads */ - rwlock_t kib_global_lock; /* stabilize net/dev/peer/conn ops */ + rwlock_t kib_global_lock; /* stabilize net/dev/peer_ni/conn ops */ struct list_head *kib_peers; /* hash table of all my known peers */ int kib_peer_hash_size; /* size of kib_peers */ void *kib_connd; /* the connd task (serialisation assertions) */ @@ -445,7 +446,7 @@ struct kib_rej { __u16 ibr_version; /* sender's version */ __u8 ibr_why; /* reject reason */ __u8 ibr_padding; /* padding */ - __u64 ibr_incarnation; /* incarnation of peer */ + __u64 ibr_incarnation; /* incarnation of peer_ni */ struct kib_connparams ibr_cp; /* connection parameters */ } __packed; @@ -453,11 +454,11 @@ struct kib_rej { #define IBLND_REJECT_CONN_RACE 1 /* You lost connection race */ #define IBLND_REJECT_NO_RESOURCES 2 /* Out of memory/conns etc */ #define IBLND_REJECT_FATAL 3 /* Anything else */ -#define IBLND_REJECT_CONN_UNCOMPAT 4 /* incompatible version peer */ -#define IBLND_REJECT_CONN_STALE 5 /* stale peer */ -/* peer's rdma frags doesn't match mine */ +#define IBLND_REJECT_CONN_UNCOMPAT 4 /* incompatible version peer_ni */ +#define IBLND_REJECT_CONN_STALE 5 /* stale peer_ni */ +/* peer_ni's rdma frags doesn't match mine */ #define IBLND_REJECT_RDMA_FRAGS 6 -/* peer's msg queue size doesn't match mine */ +/* peer_ni's msg queue size doesn't match mine */ #define IBLND_REJECT_MSG_QUEUE_SIZE 7 /***********************************************************************/ @@ -476,7 +477,7 @@ struct kib_rx { /* receive message */ #define IBLND_POSTRX_DONT_POST 0 /* don't post */ #define IBLND_POSTRX_NO_CREDIT 1 /* post: no credits */ -#define IBLND_POSTRX_PEER_CREDIT 2 /* post: give peer back 1 credit */ +#define IBLND_POSTRX_PEER_CREDIT 2 /* post: give peer_ni back 1 credit */ #define IBLND_POSTRX_RSRVD_CREDIT 3 /* post: give self back 1 reserved credit */ struct kib_tx { /* transmit message */ @@ -485,7 +486,7 @@ struct kib_tx { /* transmit message */ struct kib_conn *tx_conn; /* owning conn */ short tx_sending; /* # tx callbacks outstanding */ short tx_queued; /* queued for sending */ - short tx_waiting; /* waiting for peer */ + short tx_waiting; /* waiting for peer_ni */ int tx_status; /* LNET completion status */ ktime_t tx_deadline; /* completion deadline */ __u64 tx_cookie; /* completion cookie */ @@ -510,14 +511,14 @@ struct kib_connvars { struct kib_conn { struct kib_sched_info *ibc_sched; /* scheduler information */ - struct kib_peer *ibc_peer; /* owning peer */ + struct kib_peer_ni *ibc_peer; /* owning peer_ni */ struct kib_hca_dev *ibc_hdev; /* HCA bound on */ - struct list_head ibc_list; /* stash on peer's conn list */ + struct list_head ibc_list; /* stash on peer_ni's conn list */ struct list_head ibc_sched_list; /* schedule for attention */ __u16 ibc_version; /* version of connection */ /* reconnect later */ __u16 ibc_reconnect:1; - __u64 ibc_incarnation; /* which instance of the peer */ + __u64 ibc_incarnation; /* which instance of the peer_ni */ atomic_t ibc_refcount; /* # users */ int ibc_state; /* what's happening */ int ibc_nsends_posted; /* # uncompleted sends */ @@ -562,32 +563,32 @@ struct kib_conn { #define IBLND_CONN_CLOSING 4 /* being closed */ #define IBLND_CONN_DISCONNECTED 5 /* disconnected */ -struct kib_peer { - struct list_head ibp_list; /* stash on global peer list */ +struct kib_peer_ni { + struct list_head ibp_list; /* stash on global peer_ni list */ lnet_nid_t ibp_nid; /* who's on the other end(s) */ struct lnet_ni *ibp_ni; /* LNet interface */ struct list_head ibp_conns; /* all active connections */ struct kib_conn *ibp_next_conn; /* next connection to send on for * round robin */ struct list_head ibp_tx_queue; /* msgs waiting for a conn */ - __u64 ibp_incarnation; /* incarnation of peer */ + __u64 ibp_incarnation; /* incarnation of peer_ni */ /* when (in seconds) I was last alive */ time64_t ibp_last_alive; /* # users */ atomic_t ibp_refcount; - /* version of peer */ + /* version of peer_ni */ __u16 ibp_version; /* current passive connection attempts */ unsigned short ibp_accepting; /* current active connection attempts */ unsigned short ibp_connecting; - /* reconnect this peer later */ + /* reconnect this peer_ni later */ unsigned char ibp_reconnecting; /* counter of how many times we triggered a conn race */ unsigned char ibp_races; - /* # consecutive reconnection attempts to this peer */ + /* # consecutive reconnection attempts to this peer_ni */ unsigned int ibp_reconnected; - /* errno on closing this peer */ + /* errno on closing this peer_ni */ int ibp_error; /* max map_on_demand */ __u16 ibp_max_frags; @@ -694,36 +695,37 @@ do { \ } \ } while (0) -#define kiblnd_peer_addref(peer) \ +#define kiblnd_peer_addref(peer_ni) \ do { \ - CDEBUG(D_NET, "peer[%p] -> %s (%d)++\n", \ - (peer), libcfs_nid2str((peer)->ibp_nid), \ - atomic_read(&(peer)->ibp_refcount)); \ - atomic_inc(&(peer)->ibp_refcount); \ + CDEBUG(D_NET, "peer_ni[%p] -> %s (%d)++\n", \ + (peer_ni), libcfs_nid2str((peer_ni)->ibp_nid), \ + atomic_read(&(peer_ni)->ibp_refcount)); \ + atomic_inc(&(peer_ni)->ibp_refcount); \ } while (0) -#define kiblnd_peer_decref(peer) \ +#define kiblnd_peer_decref(peer_ni) \ do { \ - CDEBUG(D_NET, "peer[%p] -> %s (%d)--\n", \ - (peer), libcfs_nid2str((peer)->ibp_nid), \ - atomic_read(&(peer)->ibp_refcount)); \ - LASSERT_ATOMIC_POS(&(peer)->ibp_refcount); \ - if (atomic_dec_and_test(&(peer)->ibp_refcount)) \ - kiblnd_destroy_peer(peer); \ + CDEBUG(D_NET, "peer_ni[%p] -> %s (%d)--\n", \ + (peer_ni), libcfs_nid2str((peer_ni)->ibp_nid), \ + atomic_read(&(peer_ni)->ibp_refcount)); \ + LASSERT_ATOMIC_POS(&(peer_ni)->ibp_refcount); \ + if (atomic_dec_and_test(&(peer_ni)->ibp_refcount)) \ + kiblnd_destroy_peer(peer_ni); \ } while (0) static inline bool -kiblnd_peer_connecting(struct kib_peer *peer) +kiblnd_peer_connecting(struct kib_peer_ni *peer_ni) { - return peer->ibp_connecting || - peer->ibp_reconnecting || - peer->ibp_accepting; + return peer_ni->ibp_connecting || + peer_ni->ibp_reconnecting || + peer_ni->ibp_accepting; } static inline bool -kiblnd_peer_idle(struct kib_peer *peer) +kiblnd_peer_idle(struct kib_peer_ni *peer_ni) { - return !kiblnd_peer_connecting(peer) && list_empty(&peer->ibp_conns); + return !kiblnd_peer_connecting(peer_ni) && + list_empty(&peer_ni->ibp_conns); } static inline struct list_head * @@ -736,28 +738,28 @@ kiblnd_nid2peerlist(lnet_nid_t nid) } static inline int -kiblnd_peer_active(struct kib_peer *peer) +kiblnd_peer_active(struct kib_peer_ni *peer_ni) { - /* Am I in the peer hash table? */ - return !list_empty(&peer->ibp_list); + /* Am I in the peer_ni hash table? */ + return !list_empty(&peer_ni->ibp_list); } static inline struct kib_conn * -kiblnd_get_conn_locked(struct kib_peer *peer) +kiblnd_get_conn_locked(struct kib_peer_ni *peer_ni) { struct list_head *next; - LASSERT(!list_empty(&peer->ibp_conns)); + LASSERT(!list_empty(&peer_ni->ibp_conns)); /* Advance to next connection, be sure to skip the head node */ - if (!peer->ibp_next_conn || - peer->ibp_next_conn->ibc_list.next == &peer->ibp_conns) - next = peer->ibp_conns.next; + if (!peer_ni->ibp_next_conn || + peer_ni->ibp_next_conn->ibc_list.next == &peer_ni->ibp_conns) + next = peer_ni->ibp_conns.next; else - next = peer->ibp_next_conn->ibc_list.next; - peer->ibp_next_conn = list_entry(next, struct kib_conn, ibc_list); + next = peer_ni->ibp_next_conn->ibc_list.next; + peer_ni->ibp_next_conn = list_entry(next, struct kib_conn, ibc_list); - return peer->ibp_next_conn; + return peer_ni->ibp_next_conn; } static inline int @@ -1013,18 +1015,18 @@ int kiblnd_cm_callback(struct rdma_cm_id *cmid, int kiblnd_translate_mtu(int value); int kiblnd_dev_failover(struct kib_dev *dev); -int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, +int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer_ni **peerp, lnet_nid_t nid); -void kiblnd_destroy_peer(struct kib_peer *peer); -bool kiblnd_reconnect_peer(struct kib_peer *peer); +void kiblnd_destroy_peer(struct kib_peer_ni *peer_ni); +bool kiblnd_reconnect_peer(struct kib_peer_ni *peer_ni); void kiblnd_destroy_dev(struct kib_dev *dev); -void kiblnd_unlink_peer_locked(struct kib_peer *peer); -struct kib_peer *kiblnd_find_peer_locked(struct lnet_ni *ni, lnet_nid_t nid); -int kiblnd_close_stale_conns_locked(struct kib_peer *peer, +void kiblnd_unlink_peer_locked(struct kib_peer_ni *peer_ni); +struct kib_peer_ni *kiblnd_find_peer_locked(struct lnet_ni *ni, lnet_nid_t nid); +int kiblnd_close_stale_conns_locked(struct kib_peer_ni *peer_ni, int version, __u64 incarnation); -int kiblnd_close_peer_conns_locked(struct kib_peer *peer, int why); +int kiblnd_close_peer_conns_locked(struct kib_peer_ni *peer_ni, int why); -struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, +struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, struct rdma_cm_id *cmid, int state, int version); void kiblnd_destroy_conn(struct kib_conn *conn); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index f4b76347e1c6..cb752dcd35d9 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -40,8 +40,9 @@ #define MAX_CONN_RACES_BEFORE_ABORT 20 -static void kiblnd_peer_alive(struct kib_peer *peer); -static void kiblnd_peer_connect_failed(struct kib_peer *peer, int active, int error); +static void kiblnd_peer_alive(struct kib_peer_ni *peer_ni); +static void kiblnd_peer_connect_failed(struct kib_peer_ni *peer_ni, int active, + int error); static void kiblnd_init_tx_msg(struct lnet_ni *ni, struct kib_tx *tx, int type, int body_nob); static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, @@ -62,9 +63,9 @@ kiblnd_tx_done(struct lnet_ni *ni, struct kib_tx *tx) LASSERT(net); LASSERT(!in_interrupt()); - LASSERT(!tx->tx_queued); /* mustn't be queued for sending */ - LASSERT(!tx->tx_sending); /* mustn't be awaiting sent callback */ - LASSERT(!tx->tx_waiting); /* mustn't be awaiting peer response */ + LASSERT(!tx->tx_queued); /* mustn't be queued for sending */ + LASSERT(!tx->tx_sending); /* mustn't be awaiting sent callback */ + LASSERT(!tx->tx_waiting); /* mustn't be awaiting peer_ni response */ LASSERT(tx->tx_pool); kiblnd_unmap_tx(tx); @@ -414,7 +415,7 @@ kiblnd_handle_rx(struct kib_rx *rx) LASSERT(tx->tx_waiting); /* * CAVEAT EMPTOR: I could be racing with tx_complete, but... - * (a) I can overwrite tx_msg since my peer has received it! + * (a) I can overwrite tx_msg since my peer_ni has received it! * (b) tx_waiting set tells tx_complete() it's not done. */ tx->tx_nwrq = 0; /* overwrite PUT_REQ */ @@ -579,8 +580,8 @@ kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, struct kib_rdma_desc * } /* - * If rd is not tx_rd, it's going to get sent to a peer, who will need - * the rkey + * If rd is not tx_rd, it's going to get sent to a peer_ni, + * who will need the rkey */ rd->rd_key = tx->fmr.fmr_key; rd->rd_frags[0].rf_addr &= ~hdev->ibh_page_mask; @@ -611,7 +612,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, int i; /* - * If rd is not tx_rd, it's going to get sent to a peer and I'm the + * If rd is not tx_rd, it's going to get sent to a peer_ni and I'm the * RDMA sink */ tx->tx_dmadir = (rd != tx->tx_rd) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; @@ -742,8 +743,8 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit) __must_hold(&conn->ibc_lock) { struct kib_msg *msg = tx->tx_msg; - struct kib_peer *peer = conn->ibc_peer; - struct lnet_ni *ni = peer->ibp_ni; + struct kib_peer_ni *peer_ni = conn->ibc_peer; + struct lnet_ni *ni = peer_ni->ibp_ni; int ver = conn->ibc_version; int rc; int done; @@ -761,13 +762,13 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit) if (conn->ibc_nsends_posted == kiblnd_concurrent_sends(ver, ni)) { /* tx completions outstanding... */ CDEBUG(D_NET, "%s: posted enough\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); return -EAGAIN; } if (credit && !conn->ibc_credits) { /* no credits */ CDEBUG(D_NET, "%s: no credits\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); return -EAGAIN; } @@ -775,7 +776,7 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit) conn->ibc_credits == 1 && /* last credit reserved */ msg->ibm_type != IBLND_MSG_NOOP) { /* for NOOP */ CDEBUG(D_NET, "%s: not using last credit\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); return -EAGAIN; } @@ -793,16 +794,17 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit) * posted NOOPs complete */ spin_unlock(&conn->ibc_lock); - kiblnd_tx_done(peer->ibp_ni, tx); + kiblnd_tx_done(peer_ni->ibp_ni, tx); spin_lock(&conn->ibc_lock); CDEBUG(D_NET, "%s(%d): redundant or enough NOOP\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), conn->ibc_noops_posted); return 0; } - kiblnd_pack_msg(peer->ibp_ni, msg, ver, conn->ibc_outstanding_credits, - peer->ibp_nid, conn->ibc_incarnation); + kiblnd_pack_msg(peer_ni->ibp_ni, msg, ver, + conn->ibc_outstanding_credits, + peer_ni->ibp_nid, conn->ibc_incarnation); conn->ibc_credits -= credit; conn->ibc_outstanding_credits = 0; @@ -844,7 +846,7 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit) } LASSERTF(bad->wr_id == kiblnd_ptr2wreqid(tx, IBLND_WID_TX), - "bad wr_id %llx, opc %d, flags %d, peer: %s\n", + "bad wr_id %llx, opc %d, flags %d, peer_ni: %s\n", bad->wr_id, bad->opcode, bad->send_flags, libcfs_nid2str(conn->ibc_peer->ibp_nid)); bad = NULL; @@ -878,15 +880,15 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit) if (conn->ibc_state == IBLND_CONN_ESTABLISHED) CERROR("Error %d posting transmit to %s\n", - rc, libcfs_nid2str(peer->ibp_nid)); + rc, libcfs_nid2str(peer_ni->ibp_nid)); else CDEBUG(D_NET, "Error %d posting transmit to %s\n", - rc, libcfs_nid2str(peer->ibp_nid)); + rc, libcfs_nid2str(peer_ni->ibp_nid)); kiblnd_close_conn(conn, rc); if (done) - kiblnd_tx_done(peer->ibp_ni, tx); + kiblnd_tx_done(peer_ni->ibp_ni, tx); spin_lock(&conn->ibc_lock); @@ -991,12 +993,12 @@ kiblnd_tx_complete(struct kib_tx *tx, int status) conn->ibc_noops_posted--; if (failed) { - tx->tx_waiting = 0; /* don't wait for peer */ + tx->tx_waiting = 0; /* don't wait for peer_ni */ tx->tx_status = -EIO; } idle = !tx->tx_sending && /* This is the final callback */ - !tx->tx_waiting && /* Not waiting for peer */ + !tx->tx_waiting && /* Not waiting for peer_ni */ !tx->tx_queued; /* Not re-queued (PUT_DONE) */ if (idle) list_del(&tx->tx_list); @@ -1058,7 +1060,7 @@ kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, type == IBLND_MSG_PUT_DONE); if (kiblnd_rd_size(srcrd) > conn->ibc_max_frags << PAGE_SHIFT) { - CERROR("RDMA is too large for peer %s (%d), src size: %d dst size: %d\n", + CERROR("RDMA is too large for peer_ni %s (%d), src size: %d dst size: %d\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), conn->ibc_max_frags << PAGE_SHIFT, kiblnd_rd_size(srcrd), kiblnd_rd_size(dstrd)); @@ -1080,7 +1082,7 @@ kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, } if (tx->tx_nwrq >= IBLND_MAX_RDMA_FRAGS) { - CERROR("RDMA has too many fragments for peer %s (%d), src idx/frags: %d/%d dst idx/frags: %d/%d\n", + CERROR("RDMA has too many fragments for peer_ni %s (%d), src idx/frags: %d/%d dst idx/frags: %d/%d\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), IBLND_MAX_RDMA_FRAGS, srcidx, srcrd->rd_nfrags, @@ -1234,24 +1236,24 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, } static void -kiblnd_connect_peer(struct kib_peer *peer) +kiblnd_connect_peer(struct kib_peer_ni *peer_ni) { struct rdma_cm_id *cmid; struct kib_dev *dev; - struct kib_net *net = peer->ibp_ni->ni_data; + struct kib_net *net = peer_ni->ibp_ni->ni_data; struct sockaddr_in srcaddr; struct sockaddr_in dstaddr; int rc; LASSERT(net); - LASSERT(peer->ibp_connecting > 0); + LASSERT(peer_ni->ibp_connecting > 0); - cmid = kiblnd_rdma_create_id(kiblnd_cm_callback, peer, RDMA_PS_TCP, + cmid = kiblnd_rdma_create_id(kiblnd_cm_callback, peer_ni, RDMA_PS_TCP, IB_QPT_RC); if (IS_ERR(cmid)) { CERROR("Can't create CMID for %s: %ld\n", - libcfs_nid2str(peer->ibp_nid), PTR_ERR(cmid)); + libcfs_nid2str(peer_ni->ibp_nid), PTR_ERR(cmid)); rc = PTR_ERR(cmid); goto failed; } @@ -1264,9 +1266,9 @@ kiblnd_connect_peer(struct kib_peer *peer) memset(&dstaddr, 0, sizeof(dstaddr)); dstaddr.sin_family = AF_INET; dstaddr.sin_port = htons(*kiblnd_tunables.kib_service); - dstaddr.sin_addr.s_addr = htonl(LNET_NIDADDR(peer->ibp_nid)); + dstaddr.sin_addr.s_addr = htonl(LNET_NIDADDR(peer_ni->ibp_nid)); - kiblnd_peer_addref(peer); /* cmid's ref */ + kiblnd_peer_addref(peer_ni); /* cmid's ref */ if (*kiblnd_tunables.kib_use_priv_port) { rc = kiblnd_resolve_addr(cmid, &srcaddr, &dstaddr, @@ -1280,23 +1282,23 @@ kiblnd_connect_peer(struct kib_peer *peer) if (rc) { /* Can't initiate address resolution: */ CERROR("Can't resolve addr for %s: %d\n", - libcfs_nid2str(peer->ibp_nid), rc); + libcfs_nid2str(peer_ni->ibp_nid), rc); goto failed2; } return; failed2: - kiblnd_peer_connect_failed(peer, 1, rc); - kiblnd_peer_decref(peer); /* cmid's ref */ + kiblnd_peer_connect_failed(peer_ni, 1, rc); + kiblnd_peer_decref(peer_ni); /* cmid's ref */ rdma_destroy_id(cmid); return; failed: - kiblnd_peer_connect_failed(peer, 1, rc); + kiblnd_peer_connect_failed(peer_ni, 1, rc); } bool -kiblnd_reconnect_peer(struct kib_peer *peer) +kiblnd_reconnect_peer(struct kib_peer_ni *peer_ni) { rwlock_t *glock = &kiblnd_data.kib_global_lock; char *reason = NULL; @@ -1306,12 +1308,12 @@ kiblnd_reconnect_peer(struct kib_peer *peer) INIT_LIST_HEAD(&txs); write_lock_irqsave(glock, flags); - if (!peer->ibp_reconnecting) { - if (peer->ibp_accepting) + if (!peer_ni->ibp_reconnecting) { + if (peer_ni->ibp_accepting) reason = "accepting"; - else if (peer->ibp_connecting) + else if (peer_ni->ibp_connecting) reason = "connecting"; - else if (!list_empty(&peer->ibp_conns)) + else if (!list_empty(&peer_ni->ibp_conns)) reason = "connected"; else /* connected then closed */ reason = "closed"; @@ -1319,37 +1321,37 @@ kiblnd_reconnect_peer(struct kib_peer *peer) goto no_reconnect; } - LASSERT(!peer->ibp_accepting && !peer->ibp_connecting && - list_empty(&peer->ibp_conns)); - peer->ibp_reconnecting--; + LASSERT(!peer_ni->ibp_accepting && !peer_ni->ibp_connecting && + list_empty(&peer_ni->ibp_conns)); + peer_ni->ibp_reconnecting--; - if (!kiblnd_peer_active(peer)) { - list_splice_init(&peer->ibp_tx_queue, &txs); + if (!kiblnd_peer_active(peer_ni)) { + list_splice_init(&peer_ni->ibp_tx_queue, &txs); reason = "unlinked"; goto no_reconnect; } - peer->ibp_connecting++; - peer->ibp_reconnected++; + peer_ni->ibp_connecting++; + peer_ni->ibp_reconnected++; write_unlock_irqrestore(glock, flags); - kiblnd_connect_peer(peer); + kiblnd_connect_peer(peer_ni); return true; no_reconnect: write_unlock_irqrestore(glock, flags); CWARN("Abort reconnection of %s: %s\n", - libcfs_nid2str(peer->ibp_nid), reason); - kiblnd_txlist_done(peer->ibp_ni, &txs, -ECONNABORTED); + libcfs_nid2str(peer_ni->ibp_nid), reason); + kiblnd_txlist_done(peer_ni->ibp_ni, &txs, -ECONNABORTED); return false; } void kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) { - struct kib_peer *peer; - struct kib_peer *peer2; + struct kib_peer_ni *peer_ni; + struct kib_peer_ni *peer2; struct kib_conn *conn; rwlock_t *g_lock = &kiblnd_data.kib_global_lock; unsigned long flags; @@ -1370,10 +1372,10 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) */ read_lock_irqsave(g_lock, flags); - peer = kiblnd_find_peer_locked(ni, nid); - if (peer && !list_empty(&peer->ibp_conns)) { - /* Found a peer with an established connection */ - conn = kiblnd_get_conn_locked(peer); + peer_ni = kiblnd_find_peer_locked(ni, nid); + if (peer_ni && !list_empty(&peer_ni->ibp_conns)) { + /* Found a peer_ni with an established connection */ + conn = kiblnd_get_conn_locked(peer_ni); kiblnd_conn_addref(conn); /* 1 ref for me... */ read_unlock_irqrestore(g_lock, flags); @@ -1388,17 +1390,17 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) /* Re-try with a write lock */ write_lock(g_lock); - peer = kiblnd_find_peer_locked(ni, nid); - if (peer) { - if (list_empty(&peer->ibp_conns)) { - /* found a peer, but it's still connecting... */ - LASSERT(kiblnd_peer_connecting(peer)); + peer_ni = kiblnd_find_peer_locked(ni, nid); + if (peer_ni) { + if (list_empty(&peer_ni->ibp_conns)) { + /* found a peer_ni, but it's still connecting... */ + LASSERT(kiblnd_peer_connecting(peer_ni)); if (tx) list_add_tail(&tx->tx_list, - &peer->ibp_tx_queue); + &peer_ni->ibp_tx_queue); write_unlock_irqrestore(g_lock, flags); } else { - conn = kiblnd_get_conn_locked(peer); + conn = kiblnd_get_conn_locked(peer_ni); kiblnd_conn_addref(conn); /* 1 ref for me... */ write_unlock_irqrestore(g_lock, flags); @@ -1412,10 +1414,10 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) write_unlock_irqrestore(g_lock, flags); - /* Allocate a peer ready to add to the peer table and retry */ - rc = kiblnd_create_peer(ni, &peer, nid); + /* Allocate a peer_ni ready to add to the peer_ni table and retry */ + rc = kiblnd_create_peer(ni, &peer_ni, nid); if (rc) { - CERROR("Can't create peer %s\n", libcfs_nid2str(nid)); + CERROR("Can't create peer_ni %s\n", libcfs_nid2str(nid)); if (tx) { tx->tx_status = -EHOSTUNREACH; tx->tx_waiting = 0; @@ -1429,7 +1431,7 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) peer2 = kiblnd_find_peer_locked(ni, nid); if (peer2) { if (list_empty(&peer2->ibp_conns)) { - /* found a peer, but it's still connecting... */ + /* found a peer_ni, but it's still connecting... */ LASSERT(kiblnd_peer_connecting(peer2)); if (tx) list_add_tail(&tx->tx_list, @@ -1446,29 +1448,29 @@ kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid) kiblnd_conn_decref(conn); /* ...to here */ } - kiblnd_peer_decref(peer); + kiblnd_peer_decref(peer_ni); return; } - /* Brand new peer */ - LASSERT(!peer->ibp_connecting); - tunables = &peer->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; - peer->ibp_connecting = tunables->lnd_conns_per_peer; + /* Brand new peer_ni */ + LASSERT(!peer_ni->ibp_connecting); + tunables = &peer_ni->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; + peer_ni->ibp_connecting = tunables->lnd_conns_per_peer; /* always called with a ref on ni, which prevents ni being shutdown */ LASSERT(!((struct kib_net *)ni->ni_data)->ibn_shutdown); if (tx) - list_add_tail(&tx->tx_list, &peer->ibp_tx_queue); + list_add_tail(&tx->tx_list, &peer_ni->ibp_tx_queue); - kiblnd_peer_addref(peer); - list_add_tail(&peer->ibp_list, kiblnd_nid2peerlist(nid)); + kiblnd_peer_addref(peer_ni); + list_add_tail(&peer_ni->ibp_list, kiblnd_nid2peerlist(nid)); write_unlock_irqrestore(g_lock, flags); for (i = 0; i < tunables->lnd_conns_per_peer; i++) - kiblnd_connect_peer(peer); - kiblnd_peer_decref(peer); + kiblnd_connect_peer(peer_ni); + kiblnd_peer_decref(peer_ni); } int @@ -1787,7 +1789,7 @@ kiblnd_recv(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg, CERROR("Can't setup PUT sink for %s: %d\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); kiblnd_tx_done(ni, tx); - /* tell peer it's over */ + /* tell peer_ni it's over */ kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, rc, rxmsg->ibm_u.putreq.ibprm_cookie); break; @@ -1844,15 +1846,15 @@ kiblnd_thread_fini(void) } static void -kiblnd_peer_alive(struct kib_peer *peer) +kiblnd_peer_alive(struct kib_peer_ni *peer_ni) { /* This is racy, but everyone's only writing ktime_get_seconds() */ - peer->ibp_last_alive = ktime_get_seconds(); + peer_ni->ibp_last_alive = ktime_get_seconds(); mb(); } static void -kiblnd_peer_notify(struct kib_peer *peer) +kiblnd_peer_notify(struct kib_peer_ni *peer_ni) { int error = 0; time64_t last_alive = 0; @@ -1860,18 +1862,18 @@ kiblnd_peer_notify(struct kib_peer *peer) read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); - if (kiblnd_peer_idle(peer) && peer->ibp_error) { - error = peer->ibp_error; - peer->ibp_error = 0; + if (kiblnd_peer_idle(peer_ni) && peer_ni->ibp_error) { + error = peer_ni->ibp_error; + peer_ni->ibp_error = 0; - last_alive = peer->ibp_last_alive; + last_alive = peer_ni->ibp_last_alive; } read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); if (error) - lnet_notify(peer->ibp_ni, - peer->ibp_nid, 0, last_alive); + lnet_notify(peer_ni->ibp_ni, + peer_ni->ibp_nid, 0, last_alive); } void @@ -1885,7 +1887,7 @@ kiblnd_close_conn_locked(struct kib_conn *conn, int error) * already dealing with it (either to set it up or tear it down). * Caller holds kib_global_lock exclusively in irq context */ - struct kib_peer *peer = conn->ibc_peer; + struct kib_peer_ni *peer_ni = conn->ibc_peer; struct kib_dev *dev; unsigned long flags; @@ -1904,10 +1906,10 @@ kiblnd_close_conn_locked(struct kib_conn *conn, int error) list_empty(&conn->ibc_tx_queue_nocred) && list_empty(&conn->ibc_active_txs)) { CDEBUG(D_NET, "closing conn to %s\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); } else { CNETERR("Closing conn to %s: error %d%s%s%s%s%s\n", - libcfs_nid2str(peer->ibp_nid), error, + libcfs_nid2str(peer_ni->ibp_nid), error, list_empty(&conn->ibc_tx_queue) ? "" : "(sending)", list_empty(&conn->ibc_tx_noops) ? "" : "(sending_noops)", list_empty(&conn->ibc_tx_queue_rsrvd) ? "" : "(sending_rsrvd)", @@ -1915,19 +1917,19 @@ kiblnd_close_conn_locked(struct kib_conn *conn, int error) list_empty(&conn->ibc_active_txs) ? "" : "(waiting)"); } - dev = ((struct kib_net *)peer->ibp_ni->ni_data)->ibn_dev; - if (peer->ibp_next_conn == conn) + dev = ((struct kib_net *)peer_ni->ibp_ni->ni_data)->ibn_dev; + if (peer_ni->ibp_next_conn == conn) /* clear next_conn so it won't be used */ - peer->ibp_next_conn = NULL; + peer_ni->ibp_next_conn = NULL; list_del(&conn->ibc_list); /* connd (see below) takes over ibc_list's ref */ - if (list_empty(&peer->ibp_conns) && /* no more conns */ - kiblnd_peer_active(peer)) { /* still in peer table */ - kiblnd_unlink_peer_locked(peer); + if (list_empty(&peer_ni->ibp_conns) && /* no more conns */ + kiblnd_peer_active(peer_ni)) { /* still in peer_ni table */ + kiblnd_unlink_peer_locked(peer_ni); /* set/clear error on last conn */ - peer->ibp_error = conn->ibc_comms_error; + peer_ni->ibp_error = conn->ibc_comms_error; } kiblnd_set_conn_state(conn, IBLND_CONN_CLOSING); @@ -2046,7 +2048,7 @@ kiblnd_finalise_conn(struct kib_conn *conn) } static void -kiblnd_peer_connect_failed(struct kib_peer *peer, int active, int error) +kiblnd_peer_connect_failed(struct kib_peer_ni *peer_ni, int active, int error) { LIST_HEAD(zombies); unsigned long flags; @@ -2057,52 +2059,52 @@ kiblnd_peer_connect_failed(struct kib_peer *peer, int active, int error) write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); if (active) { - LASSERT(peer->ibp_connecting > 0); - peer->ibp_connecting--; + LASSERT(peer_ni->ibp_connecting > 0); + peer_ni->ibp_connecting--; } else { - LASSERT(peer->ibp_accepting > 0); - peer->ibp_accepting--; + LASSERT(peer_ni->ibp_accepting > 0); + peer_ni->ibp_accepting--; } - if (kiblnd_peer_connecting(peer)) { + if (kiblnd_peer_connecting(peer_ni)) { /* another connection attempt under way... */ write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); return; } - peer->ibp_reconnected = 0; - if (list_empty(&peer->ibp_conns)) { - /* Take peer's blocked transmits to complete with error */ - list_add(&zombies, &peer->ibp_tx_queue); - list_del_init(&peer->ibp_tx_queue); + peer_ni->ibp_reconnected = 0; + if (list_empty(&peer_ni->ibp_conns)) { + /* Take peer_ni's blocked transmits to complete with error */ + list_add(&zombies, &peer_ni->ibp_tx_queue); + list_del_init(&peer_ni->ibp_tx_queue); - if (kiblnd_peer_active(peer)) - kiblnd_unlink_peer_locked(peer); + if (kiblnd_peer_active(peer_ni)) + kiblnd_unlink_peer_locked(peer_ni); - peer->ibp_error = error; + peer_ni->ibp_error = error; } else { /* Can't have blocked transmits if there are connections */ - LASSERT(list_empty(&peer->ibp_tx_queue)); + LASSERT(list_empty(&peer_ni->ibp_tx_queue)); } write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); - kiblnd_peer_notify(peer); + kiblnd_peer_notify(peer_ni); if (list_empty(&zombies)) return; CNETERR("Deleting messages for %s: connection failed\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); - kiblnd_txlist_done(peer->ibp_ni, &zombies, -EHOSTUNREACH); + kiblnd_txlist_done(peer_ni->ibp_ni, &zombies, -EHOSTUNREACH); } static void kiblnd_connreq_done(struct kib_conn *conn, int status) { - struct kib_peer *peer = conn->ibc_peer; + struct kib_peer_ni *peer_ni = conn->ibc_peer; struct kib_tx *tx; struct list_head txs; unsigned long flags; @@ -2111,21 +2113,21 @@ kiblnd_connreq_done(struct kib_conn *conn, int status) active = (conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT); CDEBUG(D_NET, "%s: active(%d), version(%x), status(%d)\n", - libcfs_nid2str(peer->ibp_nid), active, + libcfs_nid2str(peer_ni->ibp_nid), active, conn->ibc_version, status); LASSERT(!in_interrupt()); LASSERT((conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT && - peer->ibp_connecting > 0) || + peer_ni->ibp_connecting > 0) || (conn->ibc_state == IBLND_CONN_PASSIVE_WAIT && - peer->ibp_accepting > 0)); + peer_ni->ibp_accepting > 0)); kfree(conn->ibc_connvars); conn->ibc_connvars = NULL; if (status) { /* failed to establish connection */ - kiblnd_peer_connect_failed(peer, active, status); + kiblnd_peer_connect_failed(peer_ni, active, status); kiblnd_finalise_conn(conn); return; } @@ -2135,40 +2137,40 @@ kiblnd_connreq_done(struct kib_conn *conn, int status) conn->ibc_last_send = ktime_get(); kiblnd_set_conn_state(conn, IBLND_CONN_ESTABLISHED); - kiblnd_peer_alive(peer); + kiblnd_peer_alive(peer_ni); /* - * Add conn to peer's list and nuke any dangling conns from a different - * peer instance... + * Add conn to peer_ni's list and nuke any dangling conns from + * a different peer_ni instance... */ kiblnd_conn_addref(conn); /* +1 ref for ibc_list */ - list_add(&conn->ibc_list, &peer->ibp_conns); - peer->ibp_reconnected = 0; + list_add(&conn->ibc_list, &peer_ni->ibp_conns); + peer_ni->ibp_reconnected = 0; if (active) - peer->ibp_connecting--; + peer_ni->ibp_connecting--; else - peer->ibp_accepting--; + peer_ni->ibp_accepting--; - if (!peer->ibp_version) { - peer->ibp_version = conn->ibc_version; - peer->ibp_incarnation = conn->ibc_incarnation; + if (!peer_ni->ibp_version) { + peer_ni->ibp_version = conn->ibc_version; + peer_ni->ibp_incarnation = conn->ibc_incarnation; } - if (peer->ibp_version != conn->ibc_version || - peer->ibp_incarnation != conn->ibc_incarnation) { - kiblnd_close_stale_conns_locked(peer, conn->ibc_version, + if (peer_ni->ibp_version != conn->ibc_version || + peer_ni->ibp_incarnation != conn->ibc_incarnation) { + kiblnd_close_stale_conns_locked(peer_ni, conn->ibc_version, conn->ibc_incarnation); - peer->ibp_version = conn->ibc_version; - peer->ibp_incarnation = conn->ibc_incarnation; + peer_ni->ibp_version = conn->ibc_version; + peer_ni->ibp_incarnation = conn->ibc_incarnation; } /* grab pending txs while I have the lock */ - list_add(&txs, &peer->ibp_tx_queue); - list_del_init(&peer->ibp_tx_queue); + list_add(&txs, &peer_ni->ibp_tx_queue); + list_del_init(&peer_ni->ibp_tx_queue); - if (!kiblnd_peer_active(peer) || /* peer has been deleted */ + if (!kiblnd_peer_active(peer_ni) || /* peer_ni has been deleted */ conn->ibc_comms_error) { /* error has happened already */ - struct lnet_ni *ni = peer->ibp_ni; + struct lnet_ni *ni = peer_ni->ibp_ni; /* start to shut down connection */ kiblnd_close_conn_locked(conn, -ECONNABORTED); @@ -2181,7 +2183,7 @@ kiblnd_connreq_done(struct kib_conn *conn, int status) /* * +1 ref for myself, this connection is visible to other threads - * now, refcount of peer:ibp_conns can be released by connection + * now, refcount of peer_ni:ibp_conns can be released by connection * close from either a different thread, or the calling of * kiblnd_check_sends_locked() below. See bz21911 for details. */ @@ -2227,8 +2229,8 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) struct kib_msg *reqmsg = priv; struct kib_msg *ackmsg; struct kib_dev *ibdev; - struct kib_peer *peer; - struct kib_peer *peer2; + struct kib_peer_ni *peer_ni; + struct kib_peer_ni *peer2; struct kib_conn *conn; struct lnet_ni *ni = NULL; struct kib_net *net = NULL; @@ -2257,7 +2259,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) ntohs(peer_addr->sin_port) >= PROT_SOCK) { __u32 ip = ntohl(peer_addr->sin_addr.s_addr); - CERROR("Peer's port (%pI4h:%hu) is not privileged\n", + CERROR("peer_ni's port (%pI4h:%hu) is not privileged\n", &ip, ntohs(peer_addr->sin_port)); goto failed; } @@ -2272,7 +2274,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) * o2iblnd-specific protocol changes, or when LNET unifies * protocols over all LNDs, the initial connection will * negotiate a protocol version. I trap this here to avoid - * console errors; the reject tells the peer which protocol I + * console errors; the reject tells the peer_ni which protocol I * speak. */ if (reqmsg->ibm_magic == LNET_PROTO_MAGIC || @@ -2322,7 +2324,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) goto failed; } - /* I can accept peer's version */ + /* I can accept peer_ni's version */ version = reqmsg->ibm_version; if (reqmsg->ibm_type != IBLND_MSG_CONNREQ) { @@ -2374,17 +2376,17 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) goto failed; } - /* assume 'nid' is a new peer; create */ - rc = kiblnd_create_peer(ni, &peer, nid); + /* assume 'nid' is a new peer_ni; create */ + rc = kiblnd_create_peer(ni, &peer_ni, nid); if (rc) { - CERROR("Can't create peer for %s\n", libcfs_nid2str(nid)); + CERROR("Can't create peer_ni for %s\n", libcfs_nid2str(nid)); rej.ibr_why = IBLND_REJECT_NO_RESOURCES; goto failed; } - /* We have validated the peer's parameters so use those */ - peer->ibp_max_frags = max_frags; - peer->ibp_queue_depth = reqmsg->ibm_u.connparams.ibcp_queue_depth; + /* We have validated the peer_ni's parameters so use those */ + peer_ni->ibp_max_frags = max_frags; + peer_ni->ibp_queue_depth = reqmsg->ibm_u.connparams.ibcp_queue_depth; write_lock_irqsave(g_lock, flags); @@ -2410,7 +2412,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) libcfs_nid2str(nid), peer2->ibp_version, version, peer2->ibp_incarnation, reqmsg->ibm_srcstamp); - kiblnd_peer_decref(peer); + kiblnd_peer_decref(peer_ni); rej.ibr_why = IBLND_REJECT_CONN_STALE; goto failed; } @@ -2432,7 +2434,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) CDEBUG(D_NET, "Conn race %s\n", libcfs_nid2str(peer2->ibp_nid)); - kiblnd_peer_decref(peer); + kiblnd_peer_decref(peer_ni); rej.ibr_why = IBLND_REJECT_CONN_RACE; goto failed; } @@ -2440,9 +2442,9 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) CNETERR("Conn race %s: unresolved after %d attempts, letting lower NID win\n", libcfs_nid2str(peer2->ibp_nid), MAX_CONN_RACES_BEFORE_ABORT); - /** - * passive connection is allowed even this peer is waiting for - * reconnection. + /* + * passive connection is allowed even this peer_ni is + * waiting for reconnection. */ peer2->ibp_reconnecting = 0; peer2->ibp_races = 0; @@ -2452,38 +2454,38 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob) /** * Race with kiblnd_launch_tx (active connect) to create peer * so copy validated parameters since we now know what the - * peer's limits are + * peer_ni's limits are */ - peer2->ibp_max_frags = peer->ibp_max_frags; - peer2->ibp_queue_depth = peer->ibp_queue_depth; + peer2->ibp_max_frags = peer_ni->ibp_max_frags; + peer2->ibp_queue_depth = peer_ni->ibp_queue_depth; write_unlock_irqrestore(g_lock, flags); - kiblnd_peer_decref(peer); - peer = peer2; + kiblnd_peer_decref(peer_ni); + peer_ni = peer2; } else { - /* Brand new peer */ - LASSERT(!peer->ibp_accepting); - LASSERT(!peer->ibp_version && - !peer->ibp_incarnation); + /* Brand new peer_ni */ + LASSERT(!peer_ni->ibp_accepting); + LASSERT(!peer_ni->ibp_version && + !peer_ni->ibp_incarnation); - peer->ibp_accepting = 1; - peer->ibp_version = version; - peer->ibp_incarnation = reqmsg->ibm_srcstamp; + peer_ni->ibp_accepting = 1; + peer_ni->ibp_version = version; + peer_ni->ibp_incarnation = reqmsg->ibm_srcstamp; /* I have a ref on ni that prevents it being shutdown */ LASSERT(!net->ibn_shutdown); - kiblnd_peer_addref(peer); - list_add_tail(&peer->ibp_list, kiblnd_nid2peerlist(nid)); + kiblnd_peer_addref(peer_ni); + list_add_tail(&peer_ni->ibp_list, kiblnd_nid2peerlist(nid)); write_unlock_irqrestore(g_lock, flags); } - conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_PASSIVE_WAIT, + conn = kiblnd_create_conn(peer_ni, cmid, IBLND_CONN_PASSIVE_WAIT, version); if (!conn) { - kiblnd_peer_connect_failed(peer, 0, -ENOMEM); - kiblnd_peer_decref(peer); + kiblnd_peer_connect_failed(peer_ni, 0, -ENOMEM); + kiblnd_peer_decref(peer_ni); rej.ibr_why = IBLND_REJECT_NO_RESOURCES; goto failed; } @@ -2552,7 +2554,7 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, __u64 incarnation, int why, struct kib_connparams *cp) { rwlock_t *glock = &kiblnd_data.kib_global_lock; - struct kib_peer *peer = conn->ibc_peer; + struct kib_peer_ni *peer_ni = conn->ibc_peer; char *reason; int msg_size = IBLND_MSG_SIZE; int frag_num = -1; @@ -2561,7 +2563,7 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, unsigned long flags; LASSERT(conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT); - LASSERT(peer->ibp_connecting > 0); /* 'conn' at least */ + LASSERT(peer_ni->ibp_connecting > 0); /* 'conn' at least */ if (cp) { msg_size = cp->ibcp_max_msg_size; @@ -2577,10 +2579,10 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, * empty if ibp_version != version because reconnect may be * initiated by kiblnd_query() */ - reconnect = (!list_empty(&peer->ibp_tx_queue) || - peer->ibp_version != version) && - peer->ibp_connecting && - !peer->ibp_accepting; + reconnect = (!list_empty(&peer_ni->ibp_tx_queue) || + peer_ni->ibp_version != version) && + peer_ni->ibp_connecting && + !peer_ni->ibp_accepting; if (!reconnect) { reason = "no need"; goto out; @@ -2598,7 +2600,7 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, reason = "can't negotiate max frags"; goto out; } - tunables = &peer->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; + tunables = &peer_ni->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; if (!tunables->lnd_map_on_demand) { reason = "map_on_demand must be enabled"; goto out; @@ -2608,7 +2610,7 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, goto out; } - peer->ibp_max_frags = frag_num; + peer_ni->ibp_max_frags = frag_num; reason = "rdma fragments"; break; } @@ -2622,7 +2624,7 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, goto out; } - peer->ibp_queue_depth = queue_dep; + peer_ni->ibp_queue_depth = queue_dep; reason = "queue depth"; break; @@ -2640,15 +2642,15 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, } conn->ibc_reconnect = 1; - peer->ibp_reconnecting++; - peer->ibp_version = version; + peer_ni->ibp_reconnecting++; + peer_ni->ibp_version = version; if (incarnation) - peer->ibp_incarnation = incarnation; + peer_ni->ibp_incarnation = incarnation; out: write_unlock_irqrestore(glock, flags); CNETERR("%s: %s (%s), %x, %x, msg_size: %d, queue_depth: %d/%d, max_frags: %d/%d\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), reconnect ? "reconnect" : "don't reconnect", reason, IBLND_MSG_VERSION, version, msg_size, conn->ibc_queue_depth, queue_dep, @@ -2662,7 +2664,7 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version, static void kiblnd_rejected(struct kib_conn *conn, int reason, void *priv, int priv_nob) { - struct kib_peer *peer = conn->ibc_peer; + struct kib_peer_ni *peer_ni = conn->ibc_peer; LASSERT(!in_interrupt()); LASSERT(conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT); @@ -2675,7 +2677,7 @@ kiblnd_rejected(struct kib_conn *conn, int reason, void *priv, int priv_nob) case IB_CM_REJ_INVALID_SERVICE_ID: CNETERR("%s rejected: no listener at %d\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), *kiblnd_tunables.kib_service); break; @@ -2691,7 +2693,7 @@ kiblnd_rejected(struct kib_conn *conn, int reason, void *priv, int priv_nob) * b) V2 will provide incarnation while rejecting me, * -1 will be overwrote. * - * if I try to connect to a V1 peer with V2 protocol, + * if I try to connect to a V1 peer_ni with V2 protocol, * it rejected me then upgrade to V2, I have no idea * about the upgrading and try to reconnect with V1, * in this case upgraded V2 can find out I'm trying to @@ -2727,22 +2729,24 @@ kiblnd_rejected(struct kib_conn *conn, int reason, void *priv, int priv_nob) if (rej->ibr_magic != IBLND_MSG_MAGIC && rej->ibr_magic != LNET_PROTO_MAGIC) { CERROR("%s rejected: consumer defined fatal error\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); break; } if (rej->ibr_version != IBLND_MSG_VERSION && rej->ibr_version != IBLND_MSG_VERSION_1) { CERROR("%s rejected: o2iblnd version %x error\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), rej->ibr_version); break; } if (rej->ibr_why == IBLND_REJECT_FATAL && rej->ibr_version == IBLND_MSG_VERSION_1) { - CDEBUG(D_NET, "rejected by old version peer %s: %x\n", - libcfs_nid2str(peer->ibp_nid), rej->ibr_version); + CDEBUG(D_NET, + "rejected by old version peer_ni %s: %x\n", + libcfs_nid2str(peer_ni->ibp_nid), + rej->ibr_version); if (conn->ibc_version != IBLND_MSG_VERSION_1) rej->ibr_why = IBLND_REJECT_CONN_UNCOMPAT; @@ -2761,17 +2765,17 @@ kiblnd_rejected(struct kib_conn *conn, int reason, void *priv, int priv_nob) case IBLND_REJECT_NO_RESOURCES: CERROR("%s rejected: o2iblnd no resources\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); break; case IBLND_REJECT_FATAL: CERROR("%s rejected: o2iblnd fatal error\n", - libcfs_nid2str(peer->ibp_nid)); + libcfs_nid2str(peer_ni->ibp_nid)); break; default: CERROR("%s rejected: o2iblnd reason %d\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), rej->ibr_why); break; } @@ -2780,7 +2784,7 @@ kiblnd_rejected(struct kib_conn *conn, int reason, void *priv, int priv_nob) /* fall through */ default: CNETERR("%s rejected: reason %d, size %d\n", - libcfs_nid2str(peer->ibp_nid), reason, priv_nob); + libcfs_nid2str(peer_ni->ibp_nid), reason, priv_nob); break; } @@ -2790,8 +2794,8 @@ kiblnd_rejected(struct kib_conn *conn, int reason, void *priv, int priv_nob) static void kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob) { - struct kib_peer *peer = conn->ibc_peer; - struct lnet_ni *ni = peer->ibp_ni; + struct kib_peer_ni *peer_ni = conn->ibc_peer; + struct lnet_ni *ni = peer_ni->ibp_ni; struct kib_net *net = ni->ni_data; struct kib_msg *msg = priv; int ver = conn->ibc_version; @@ -2802,20 +2806,20 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob) if (rc) { CERROR("Can't unpack connack from %s: %d\n", - libcfs_nid2str(peer->ibp_nid), rc); + libcfs_nid2str(peer_ni->ibp_nid), rc); goto failed; } if (msg->ibm_type != IBLND_MSG_CONNACK) { CERROR("Unexpected message %d from %s\n", - msg->ibm_type, libcfs_nid2str(peer->ibp_nid)); + msg->ibm_type, libcfs_nid2str(peer_ni->ibp_nid)); rc = -EPROTO; goto failed; } if (ver != msg->ibm_version) { CERROR("%s replied version %x is different with requested version %x\n", - libcfs_nid2str(peer->ibp_nid), msg->ibm_version, ver); + libcfs_nid2str(peer_ni->ibp_nid), msg->ibm_version, ver); rc = -EPROTO; goto failed; } @@ -2823,7 +2827,7 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob) if (msg->ibm_u.connparams.ibcp_queue_depth > conn->ibc_queue_depth) { CERROR("%s has incompatible queue depth %d (<=%d wanted)\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), msg->ibm_u.connparams.ibcp_queue_depth, conn->ibc_queue_depth); rc = -EPROTO; @@ -2833,7 +2837,7 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob) if ((msg->ibm_u.connparams.ibcp_max_frags >> IBLND_FRAG_SHIFT) > conn->ibc_max_frags) { CERROR("%s has incompatible max_frags %d (<=%d wanted)\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), msg->ibm_u.connparams.ibcp_max_frags >> IBLND_FRAG_SHIFT, conn->ibc_max_frags); rc = -EPROTO; @@ -2842,7 +2846,7 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob) if (msg->ibm_u.connparams.ibcp_max_msg_size > IBLND_MSG_SIZE) { CERROR("%s max message size %d too big (%d max)\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), msg->ibm_u.connparams.ibcp_max_msg_size, IBLND_MSG_SIZE); rc = -EPROTO; @@ -2859,7 +2863,7 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob) if (rc) { CERROR("Bad connection reply from %s, rc = %d, version: %x max_frags: %d\n", - libcfs_nid2str(peer->ibp_nid), rc, + libcfs_nid2str(peer_ni->ibp_nid), rc, msg->ibm_version, msg->ibm_u.connparams.ibcp_max_frags); goto failed; } @@ -2890,7 +2894,7 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob) static int kiblnd_active_connect(struct rdma_cm_id *cmid) { - struct kib_peer *peer = (struct kib_peer *)cmid->context; + struct kib_peer_ni *peer_ni = (struct kib_peer_ni *)cmid->context; struct kib_conn *conn; struct kib_msg *msg; struct rdma_conn_param cp; @@ -2901,17 +2905,17 @@ kiblnd_active_connect(struct rdma_cm_id *cmid) read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); - incarnation = peer->ibp_incarnation; - version = !peer->ibp_version ? IBLND_MSG_VERSION : - peer->ibp_version; + incarnation = peer_ni->ibp_incarnation; + version = !peer_ni->ibp_version ? IBLND_MSG_VERSION : + peer_ni->ibp_version; read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); - conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_ACTIVE_CONNECT, + conn = kiblnd_create_conn(peer_ni, cmid, IBLND_CONN_ACTIVE_CONNECT, version); if (!conn) { - kiblnd_peer_connect_failed(peer, 1, -ENOMEM); - kiblnd_peer_decref(peer); /* lose cmid's ref */ + kiblnd_peer_connect_failed(peer_ni, 1, -ENOMEM); + kiblnd_peer_decref(peer_ni); /* lose cmid's ref */ return -ENOMEM; } @@ -2928,8 +2932,8 @@ kiblnd_active_connect(struct rdma_cm_id *cmid) msg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags << IBLND_FRAG_SHIFT; msg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE; - kiblnd_pack_msg(peer->ibp_ni, msg, version, - 0, peer->ibp_nid, incarnation); + kiblnd_pack_msg(peer_ni->ibp_ni, msg, version, + 0, peer_ni->ibp_nid, incarnation); memset(&cp, 0, sizeof(cp)); cp.private_data = msg; @@ -2946,7 +2950,7 @@ kiblnd_active_connect(struct rdma_cm_id *cmid) rc = rdma_connect(cmid, &cp); if (rc) { CERROR("Can't connect to %s: %d\n", - libcfs_nid2str(peer->ibp_nid), rc); + libcfs_nid2str(peer_ni->ibp_nid), rc); kiblnd_connreq_done(conn, rc); kiblnd_conn_decref(conn); } @@ -2957,7 +2961,7 @@ kiblnd_active_connect(struct rdma_cm_id *cmid) int kiblnd_cm_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event) { - struct kib_peer *peer; + struct kib_peer_ni *peer_ni; struct kib_conn *conn; int rc; @@ -2976,33 +2980,34 @@ kiblnd_cm_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event) return rc; case RDMA_CM_EVENT_ADDR_ERROR: - peer = (struct kib_peer *)cmid->context; + peer_ni = (struct kib_peer_ni *)cmid->context; CNETERR("%s: ADDR ERROR %d\n", - libcfs_nid2str(peer->ibp_nid), event->status); - kiblnd_peer_connect_failed(peer, 1, -EHOSTUNREACH); - kiblnd_peer_decref(peer); + libcfs_nid2str(peer_ni->ibp_nid), event->status); + kiblnd_peer_connect_failed(peer_ni, 1, -EHOSTUNREACH); + kiblnd_peer_decref(peer_ni); return -EHOSTUNREACH; /* rc destroys cmid */ case RDMA_CM_EVENT_ADDR_RESOLVED: - peer = (struct kib_peer *)cmid->context; + peer_ni = (struct kib_peer_ni *)cmid->context; CDEBUG(D_NET, "%s Addr resolved: %d\n", - libcfs_nid2str(peer->ibp_nid), event->status); + libcfs_nid2str(peer_ni->ibp_nid), event->status); if (event->status) { CNETERR("Can't resolve address for %s: %d\n", - libcfs_nid2str(peer->ibp_nid), event->status); + libcfs_nid2str(peer_ni->ibp_nid), + event->status); rc = event->status; } else { rc = rdma_resolve_route( cmid, *kiblnd_tunables.kib_timeout * 1000); if (!rc) { - struct kib_net *net = peer->ibp_ni->ni_data; + struct kib_net *net = peer_ni->ibp_ni->ni_data; struct kib_dev *dev = net->ibn_dev; CDEBUG(D_NET, "%s: connection bound to "\ "%s:%pI4h:%s\n", - libcfs_nid2str(peer->ibp_nid), + libcfs_nid2str(peer_ni->ibp_nid), dev->ibd_ifname, &dev->ibd_ifip, cmid->device->name); @@ -3011,32 +3016,32 @@ kiblnd_cm_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event) /* Can't initiate route resolution */ CERROR("Can't resolve route for %s: %d\n", - libcfs_nid2str(peer->ibp_nid), rc); + libcfs_nid2str(peer_ni->ibp_nid), rc); } - kiblnd_peer_connect_failed(peer, 1, rc); - kiblnd_peer_decref(peer); + kiblnd_peer_connect_failed(peer_ni, 1, rc); + kiblnd_peer_decref(peer_ni); return rc; /* rc destroys cmid */ case RDMA_CM_EVENT_ROUTE_ERROR: - peer = (struct kib_peer *)cmid->context; + peer_ni = (struct kib_peer_ni *)cmid->context; CNETERR("%s: ROUTE ERROR %d\n", - libcfs_nid2str(peer->ibp_nid), event->status); - kiblnd_peer_connect_failed(peer, 1, -EHOSTUNREACH); - kiblnd_peer_decref(peer); + libcfs_nid2str(peer_ni->ibp_nid), event->status); + kiblnd_peer_connect_failed(peer_ni, 1, -EHOSTUNREACH); + kiblnd_peer_decref(peer_ni); return -EHOSTUNREACH; /* rc destroys cmid */ case RDMA_CM_EVENT_ROUTE_RESOLVED: - peer = (struct kib_peer *)cmid->context; + peer_ni = (struct kib_peer_ni *)cmid->context; CDEBUG(D_NET, "%s Route resolved: %d\n", - libcfs_nid2str(peer->ibp_nid), event->status); + libcfs_nid2str(peer_ni->ibp_nid), event->status); if (!event->status) return kiblnd_active_connect(cmid); CNETERR("Can't resolve route for %s: %d\n", - libcfs_nid2str(peer->ibp_nid), event->status); - kiblnd_peer_connect_failed(peer, 1, event->status); - kiblnd_peer_decref(peer); + libcfs_nid2str(peer_ni->ibp_nid), event->status); + kiblnd_peer_connect_failed(peer_ni, 1, event->status); + kiblnd_peer_decref(peer_ni); return event->status; /* rc destroys cmid */ case RDMA_CM_EVENT_UNREACHABLE: @@ -3177,7 +3182,7 @@ kiblnd_check_conns(int idx) LIST_HEAD(closes); LIST_HEAD(checksends); struct list_head *peers = &kiblnd_data.kib_peers[idx]; - struct kib_peer *peer; + struct kib_peer_ni *peer_ni; struct kib_conn *conn; unsigned long flags; @@ -3188,9 +3193,9 @@ kiblnd_check_conns(int idx) */ read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); - list_for_each_entry(peer, peers, ibp_list) { + list_for_each_entry(peer_ni, peers, ibp_list) { - list_for_each_entry(conn, &peer->ibp_conns, ibc_list) { + list_for_each_entry(conn, &peer_ni->ibp_conns, ibc_list) { int timedout; int sendnoop; @@ -3207,8 +3212,9 @@ kiblnd_check_conns(int idx) if (timedout) { CERROR("Timed out RDMA with %s (%lld): c: %u, oc: %u, rc: %u\n", - libcfs_nid2str(peer->ibp_nid), - ktime_get_seconds() - peer->ibp_last_alive, + libcfs_nid2str(peer_ni->ibp_nid), + (ktime_get_seconds() - + peer_ni->ibp_last_alive), conn->ibc_credits, conn->ibc_outstanding_credits, conn->ibc_reserved_credits); @@ -3268,7 +3274,7 @@ kiblnd_disconnect_conn(struct kib_conn *conn) } /** - * High-water for reconnection to the same peer, reconnection attempt should + * High-water for reconnection to the same peer_ni, reconnection attempt should * be delayed after trying more than KIB_RECONN_HIGH_RACE. */ #define KIB_RECONN_HIGH_RACE 10 @@ -3302,14 +3308,14 @@ kiblnd_connd(void *arg) dropped_lock = 0; if (!list_empty(&kiblnd_data.kib_connd_zombies)) { - struct kib_peer *peer = NULL; + struct kib_peer_ni *peer_ni = NULL; conn = list_entry(kiblnd_data.kib_connd_zombies.next, struct kib_conn, ibc_list); list_del(&conn->ibc_list); if (conn->ibc_reconnect) { - peer = conn->ibc_peer; - kiblnd_peer_addref(peer); + peer_ni = conn->ibc_peer; + kiblnd_peer_addref(peer_ni); } spin_unlock_irqrestore(lock, flags); @@ -3318,13 +3324,13 @@ kiblnd_connd(void *arg) kiblnd_destroy_conn(conn); spin_lock_irqsave(lock, flags); - if (!peer) { + if (!peer_ni) { kfree(conn); continue; } - conn->ibc_peer = peer; - if (peer->ibp_reconnected < KIB_RECONN_HIGH_RACE) + conn->ibc_peer = peer_ni; + if (peer_ni->ibp_reconnected < KIB_RECONN_HIGH_RACE) list_add_tail(&conn->ibc_list, &kiblnd_data.kib_reconn_list); else @@ -3384,7 +3390,7 @@ kiblnd_connd(void *arg) /* * Time to check for RDMA timeouts on a few more * peers: I do checks every 'p' seconds on a - * proportion of the peer table and I need to check + * proportion of the peer_ni table and I need to check * every connection 'n' times within a timeout * interval, to ensure I detect a timeout on any * connection within (n+1)/n times the timeout diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index ba1ec35a017a..c14711804d7b 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -104,38 +104,38 @@ ksocknal_create_peer(struct ksock_peer **peerp, struct lnet_ni *ni, { int cpt = lnet_cpt_of_nid(id.nid, ni); struct ksock_net *net = ni->ni_data; - struct ksock_peer *peer; + struct ksock_peer *peer_ni; LASSERT(id.nid != LNET_NID_ANY); LASSERT(id.pid != LNET_PID_ANY); LASSERT(!in_interrupt()); - peer = kzalloc_cpt(sizeof(*peer), GFP_NOFS, cpt); - if (!peer) + peer_ni = kzalloc_cpt(sizeof(*peer_ni), GFP_NOFS, cpt); + if (!peer_ni) return -ENOMEM; - peer->ksnp_ni = ni; - peer->ksnp_id = id; - atomic_set(&peer->ksnp_refcount, 1); /* 1 ref for caller */ - peer->ksnp_closing = 0; - peer->ksnp_accepting = 0; - peer->ksnp_proto = NULL; - peer->ksnp_last_alive = 0; - peer->ksnp_zc_next_cookie = SOCKNAL_KEEPALIVE_PING + 1; - - INIT_LIST_HEAD(&peer->ksnp_conns); - INIT_LIST_HEAD(&peer->ksnp_routes); - INIT_LIST_HEAD(&peer->ksnp_tx_queue); - INIT_LIST_HEAD(&peer->ksnp_zc_req_list); - spin_lock_init(&peer->ksnp_lock); + peer_ni->ksnp_ni = ni; + peer_ni->ksnp_id = id; + atomic_set(&peer_ni->ksnp_refcount, 1); /* 1 ref for caller */ + peer_ni->ksnp_closing = 0; + peer_ni->ksnp_accepting = 0; + peer_ni->ksnp_proto = NULL; + peer_ni->ksnp_last_alive = 0; + peer_ni->ksnp_zc_next_cookie = SOCKNAL_KEEPALIVE_PING + 1; + + INIT_LIST_HEAD(&peer_ni->ksnp_conns); + INIT_LIST_HEAD(&peer_ni->ksnp_routes); + INIT_LIST_HEAD(&peer_ni->ksnp_tx_queue); + INIT_LIST_HEAD(&peer_ni->ksnp_zc_req_list); + spin_lock_init(&peer_ni->ksnp_lock); spin_lock_bh(&net->ksnn_lock); if (net->ksnn_shutdown) { spin_unlock_bh(&net->ksnn_lock); - kfree(peer); - CERROR("Can't create peer: network shutdown\n"); + kfree(peer_ni); + CERROR("Can't create peer_ni: network shutdown\n"); return -ESHUTDOWN; } @@ -143,31 +143,31 @@ ksocknal_create_peer(struct ksock_peer **peerp, struct lnet_ni *ni, spin_unlock_bh(&net->ksnn_lock); - *peerp = peer; + *peerp = peer_ni; return 0; } void -ksocknal_destroy_peer(struct ksock_peer *peer) +ksocknal_destroy_peer(struct ksock_peer *peer_ni) { - struct ksock_net *net = peer->ksnp_ni->ni_data; + struct ksock_net *net = peer_ni->ksnp_ni->ni_data; - CDEBUG(D_NET, "peer %s %p deleted\n", - libcfs_id2str(peer->ksnp_id), peer); + CDEBUG(D_NET, "peer_ni %s %p deleted\n", + libcfs_id2str(peer_ni->ksnp_id), peer_ni); - LASSERT(!atomic_read(&peer->ksnp_refcount)); - LASSERT(!peer->ksnp_accepting); - LASSERT(list_empty(&peer->ksnp_conns)); - LASSERT(list_empty(&peer->ksnp_routes)); - LASSERT(list_empty(&peer->ksnp_tx_queue)); - LASSERT(list_empty(&peer->ksnp_zc_req_list)); + LASSERT(!atomic_read(&peer_ni->ksnp_refcount)); + LASSERT(!peer_ni->ksnp_accepting); + LASSERT(list_empty(&peer_ni->ksnp_conns)); + LASSERT(list_empty(&peer_ni->ksnp_routes)); + LASSERT(list_empty(&peer_ni->ksnp_tx_queue)); + LASSERT(list_empty(&peer_ni->ksnp_zc_req_list)); - kfree(peer); + kfree(peer_ni); /* - * NB a peer's connections and routes keep a reference on their peer + * NB a peer_ni's connections and routes keep a reference on their peer * until they are destroyed, so we can be assured that _all_ state to - * do with this peer has been cleaned up when its refcount drops to + * do with this peer_ni has been cleaned up when its refcount drops to * zero. */ spin_lock_bh(&net->ksnn_lock); @@ -179,22 +179,22 @@ struct ksock_peer * ksocknal_find_peer_locked(struct lnet_ni *ni, struct lnet_process_id id) { struct list_head *peer_list = ksocknal_nid2peerlist(id.nid); - struct ksock_peer *peer; + struct ksock_peer *peer_ni; - list_for_each_entry(peer, peer_list, ksnp_list) { - LASSERT(!peer->ksnp_closing); + list_for_each_entry(peer_ni, peer_list, ksnp_list) { + LASSERT(!peer_ni->ksnp_closing); - if (peer->ksnp_ni != ni) + if (peer_ni->ksnp_ni != ni) continue; - if (peer->ksnp_id.nid != id.nid || - peer->ksnp_id.pid != id.pid) + if (peer_ni->ksnp_id.nid != id.nid || + peer_ni->ksnp_id.pid != id.pid) continue; - CDEBUG(D_NET, "got peer [%p] -> %s (%d)\n", - peer, libcfs_id2str(id), - atomic_read(&peer->ksnp_refcount)); - return peer; + CDEBUG(D_NET, "got peer_ni [%p] -> %s (%d)\n", + peer_ni, libcfs_id2str(id), + atomic_read(&peer_ni->ksnp_refcount)); + return peer_ni; } return NULL; } @@ -202,47 +202,47 @@ ksocknal_find_peer_locked(struct lnet_ni *ni, struct lnet_process_id id) struct ksock_peer * ksocknal_find_peer(struct lnet_ni *ni, struct lnet_process_id id) { - struct ksock_peer *peer; + struct ksock_peer *peer_ni; read_lock(&ksocknal_data.ksnd_global_lock); - peer = ksocknal_find_peer_locked(ni, id); - if (peer) /* +1 ref for caller? */ - ksocknal_peer_addref(peer); + peer_ni = ksocknal_find_peer_locked(ni, id); + if (peer_ni) /* +1 ref for caller? */ + ksocknal_peer_addref(peer_ni); read_unlock(&ksocknal_data.ksnd_global_lock); - return peer; + return peer_ni; } static void -ksocknal_unlink_peer_locked(struct ksock_peer *peer) +ksocknal_unlink_peer_locked(struct ksock_peer *peer_ni) { int i; __u32 ip; struct ksock_interface *iface; - for (i = 0; i < peer->ksnp_n_passive_ips; i++) { + for (i = 0; i < peer_ni->ksnp_n_passive_ips; i++) { LASSERT(i < LNET_MAX_INTERFACES); - ip = peer->ksnp_passive_ips[i]; + ip = peer_ni->ksnp_passive_ips[i]; - iface = ksocknal_ip2iface(peer->ksnp_ni, ip); + iface = ksocknal_ip2iface(peer_ni->ksnp_ni, ip); /* - * All IPs in peer->ksnp_passive_ips[] come from the + * All IPs in peer_ni->ksnp_passive_ips[] come from the * interface list, therefore the call must succeed. */ LASSERT(iface); - CDEBUG(D_NET, "peer=%p iface=%p ksni_nroutes=%d\n", - peer, iface, iface->ksni_nroutes); + CDEBUG(D_NET, "peer_ni=%p iface=%p ksni_nroutes=%d\n", + peer_ni, iface, iface->ksni_nroutes); iface->ksni_npeers--; } - LASSERT(list_empty(&peer->ksnp_conns)); - LASSERT(list_empty(&peer->ksnp_routes)); - LASSERT(!peer->ksnp_closing); - peer->ksnp_closing = 1; - list_del(&peer->ksnp_list); + LASSERT(list_empty(&peer_ni->ksnp_conns)); + LASSERT(list_empty(&peer_ni->ksnp_routes)); + LASSERT(!peer_ni->ksnp_closing); + peer_ni->ksnp_closing = 1; + list_del(&peer_ni->ksnp_list); /* lose peerlist's ref */ - ksocknal_peer_decref(peer); + ksocknal_peer_decref(peer_ni); } static int @@ -250,7 +250,7 @@ ksocknal_get_peer_info(struct lnet_ni *ni, int index, struct lnet_process_id *id, __u32 *myip, __u32 *peer_ip, int *port, int *conn_count, int *share_count) { - struct ksock_peer *peer; + struct ksock_peer *peer_ni; struct ksock_route *route; int i; int j; @@ -259,17 +259,17 @@ ksocknal_get_peer_info(struct lnet_ni *ni, int index, read_lock(&ksocknal_data.ksnd_global_lock); for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) { - list_for_each_entry(peer, &ksocknal_data.ksnd_peers[i], ksnp_list) { - - if (peer->ksnp_ni != ni) + list_for_each_entry(peer_ni, &ksocknal_data.ksnd_peers[i], + ksnp_list) { + if (peer_ni->ksnp_ni != ni) continue; - if (!peer->ksnp_n_passive_ips && - list_empty(&peer->ksnp_routes)) { + if (!peer_ni->ksnp_n_passive_ips && + list_empty(&peer_ni->ksnp_routes)) { if (index-- > 0) continue; - *id = peer->ksnp_id; + *id = peer_ni->ksnp_id; *myip = 0; *peer_ip = 0; *port = 0; @@ -279,12 +279,12 @@ ksocknal_get_peer_info(struct lnet_ni *ni, int index, goto out; } - for (j = 0; j < peer->ksnp_n_passive_ips; j++) { + for (j = 0; j < peer_ni->ksnp_n_passive_ips; j++) { if (index-- > 0) continue; - *id = peer->ksnp_id; - *myip = peer->ksnp_passive_ips[j]; + *id = peer_ni->ksnp_id; + *myip = peer_ni->ksnp_passive_ips[j]; *peer_ip = 0; *port = 0; *conn_count = 0; @@ -293,12 +293,12 @@ ksocknal_get_peer_info(struct lnet_ni *ni, int index, goto out; } - list_for_each_entry(route, &peer->ksnp_routes, + list_for_each_entry(route, &peer_ni->ksnp_routes, ksnr_list) { if (index-- > 0) continue; - *id = peer->ksnp_id; + *id = peer_ni->ksnp_id; *myip = route->ksnr_myipaddr; *peer_ip = route->ksnr_ipaddr; *port = route->ksnr_port; @@ -318,7 +318,7 @@ static void ksocknal_associate_route_conn_locked(struct ksock_route *route, struct ksock_conn *conn) { - struct ksock_peer *peer = route->ksnr_peer; + struct ksock_peer *peer_ni = route->ksnr_peer; int type = conn->ksnc_type; struct ksock_interface *iface; @@ -329,12 +329,12 @@ ksocknal_associate_route_conn_locked(struct ksock_route *route, if (!route->ksnr_myipaddr) { /* route wasn't bound locally yet (the initial route) */ CDEBUG(D_NET, "Binding %s %pI4h to %pI4h\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &route->ksnr_ipaddr, &conn->ksnc_myipaddr); } else { CDEBUG(D_NET, "Rebinding %s %pI4h from %pI4h to %pI4h\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &route->ksnr_ipaddr, &route->ksnr_myipaddr, &conn->ksnc_myipaddr); @@ -362,33 +362,33 @@ ksocknal_associate_route_conn_locked(struct ksock_route *route, } static void -ksocknal_add_route_locked(struct ksock_peer *peer, struct ksock_route *route) +ksocknal_add_route_locked(struct ksock_peer *peer_ni, struct ksock_route *route) { struct ksock_conn *conn; struct ksock_route *route2; - LASSERT(!peer->ksnp_closing); + LASSERT(!peer_ni->ksnp_closing); LASSERT(!route->ksnr_peer); LASSERT(!route->ksnr_scheduled); LASSERT(!route->ksnr_connecting); LASSERT(!route->ksnr_connected); /* LASSERT(unique) */ - list_for_each_entry(route2, &peer->ksnp_routes, ksnr_list) { + list_for_each_entry(route2, &peer_ni->ksnp_routes, ksnr_list) { if (route2->ksnr_ipaddr == route->ksnr_ipaddr) { CERROR("Duplicate route %s %pI4h\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &route->ksnr_ipaddr); LBUG(); } } - route->ksnr_peer = peer; - ksocknal_peer_addref(peer); - /* peer's routelist takes over my ref on 'route' */ - list_add_tail(&route->ksnr_list, &peer->ksnp_routes); + route->ksnr_peer = peer_ni; + ksocknal_peer_addref(peer_ni); + /* peer_ni's routelist takes over my ref on 'route' */ + list_add_tail(&route->ksnr_list, &peer_ni->ksnp_routes); - list_for_each_entry(conn, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn, &peer_ni->ksnp_conns, ksnc_list) { if (conn->ksnc_ipaddr != route->ksnr_ipaddr) continue; @@ -400,7 +400,7 @@ ksocknal_add_route_locked(struct ksock_peer *peer, struct ksock_route *route) static void ksocknal_del_route_locked(struct ksock_route *route) { - struct ksock_peer *peer = route->ksnr_peer; + struct ksock_peer *peer_ni = route->ksnr_peer; struct ksock_interface *iface; struct ksock_conn *conn; struct list_head *ctmp; @@ -409,7 +409,7 @@ ksocknal_del_route_locked(struct ksock_route *route) LASSERT(!route->ksnr_deleted); /* Close associated conns */ - list_for_each_safe(ctmp, cnxt, &peer->ksnp_conns) { + list_for_each_safe(ctmp, cnxt, &peer_ni->ksnp_conns) { conn = list_entry(ctmp, struct ksock_conn, ksnc_list); if (conn->ksnc_route != route) @@ -427,15 +427,15 @@ ksocknal_del_route_locked(struct ksock_route *route) route->ksnr_deleted = 1; list_del(&route->ksnr_list); - ksocknal_route_decref(route); /* drop peer's ref */ + ksocknal_route_decref(route); /* drop peer_ni's ref */ - if (list_empty(&peer->ksnp_routes) && - list_empty(&peer->ksnp_conns)) { + if (list_empty(&peer_ni->ksnp_routes) && + list_empty(&peer_ni->ksnp_conns)) { /* - * I've just removed the last route to a peer with no active + * I've just removed the last route to a peer_ni with no active * connections */ - ksocknal_unlink_peer_locked(peer); + ksocknal_unlink_peer_locked(peer_ni); } } @@ -443,7 +443,7 @@ int ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, int port) { - struct ksock_peer *peer; + struct ksock_peer *peer_ni; struct ksock_peer *peer2; struct ksock_route *route; struct ksock_route *route2; @@ -453,14 +453,14 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, id.pid == LNET_PID_ANY) return -EINVAL; - /* Have a brand new peer ready... */ - rc = ksocknal_create_peer(&peer, ni, id); + /* Have a brand new peer_ni ready... */ + rc = ksocknal_create_peer(&peer_ni, ni, id); if (rc) return rc; route = ksocknal_create_route(ipaddr, port); if (!route) { - ksocknal_peer_decref(peer); + ksocknal_peer_decref(peer_ni); return -ENOMEM; } @@ -471,15 +471,15 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, peer2 = ksocknal_find_peer_locked(ni, id); if (peer2) { - ksocknal_peer_decref(peer); - peer = peer2; + ksocknal_peer_decref(peer_ni); + peer_ni = peer2; } else { - /* peer table takes my ref on peer */ - list_add_tail(&peer->ksnp_list, + /* peer_ni table takes my ref on peer_ni */ + list_add_tail(&peer_ni->ksnp_list, ksocknal_nid2peerlist(id.nid)); } - list_for_each_entry(route2, &peer->ksnp_routes, ksnr_list) { + list_for_each_entry(route2, &peer_ni->ksnp_routes, ksnr_list) { if (route2->ksnr_ipaddr == ipaddr) { /* Route already exists, use the old one */ ksocknal_route_decref(route); @@ -488,7 +488,7 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, } } /* Route doesn't already exist, add the new one */ - ksocknal_add_route_locked(peer, route); + ksocknal_add_route_locked(peer_ni, route); route->ksnr_share_count++; out: write_unlock_bh(&ksocknal_data.ksnd_global_lock); @@ -497,7 +497,7 @@ ksocknal_add_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ipaddr, } static void -ksocknal_del_peer_locked(struct ksock_peer *peer, __u32 ip) +ksocknal_del_peer_locked(struct ksock_peer *peer_ni, __u32 ip) { struct ksock_conn *conn; struct ksock_route *route; @@ -505,12 +505,12 @@ ksocknal_del_peer_locked(struct ksock_peer *peer, __u32 ip) struct list_head *nxt; int nshared; - LASSERT(!peer->ksnp_closing); + LASSERT(!peer_ni->ksnp_closing); - /* Extra ref prevents peer disappearing until I'm done with it */ - ksocknal_peer_addref(peer); + /* Extra ref prevents peer_ni disappearing until I'm done with it */ + ksocknal_peer_addref(peer_ni); - list_for_each_safe(tmp, nxt, &peer->ksnp_routes) { + list_for_each_safe(tmp, nxt, &peer_ni->ksnp_routes) { route = list_entry(tmp, struct ksock_route, ksnr_list); /* no match */ @@ -523,7 +523,7 @@ ksocknal_del_peer_locked(struct ksock_peer *peer, __u32 ip) } nshared = 0; - list_for_each_safe(tmp, nxt, &peer->ksnp_routes) { + list_for_each_safe(tmp, nxt, &peer_ni->ksnp_routes) { route = list_entry(tmp, struct ksock_route, ksnr_list); nshared += route->ksnr_share_count; } @@ -533,7 +533,7 @@ ksocknal_del_peer_locked(struct ksock_peer *peer, __u32 ip) * remove everything else if there are no explicit entries * left */ - list_for_each_safe(tmp, nxt, &peer->ksnp_routes) { + list_for_each_safe(tmp, nxt, &peer_ni->ksnp_routes) { route = list_entry(tmp, struct ksock_route, ksnr_list); /* we should only be removing auto-entries */ @@ -541,24 +541,23 @@ ksocknal_del_peer_locked(struct ksock_peer *peer, __u32 ip) ksocknal_del_route_locked(route); } - list_for_each_safe(tmp, nxt, &peer->ksnp_conns) { + list_for_each_safe(tmp, nxt, &peer_ni->ksnp_conns) { conn = list_entry(tmp, struct ksock_conn, ksnc_list); ksocknal_close_conn_locked(conn, 0); } } - ksocknal_peer_decref(peer); - /* NB peer unlinks itself when last conn/route is removed */ + ksocknal_peer_decref(peer_ni); + /* NB peer_ni unlinks itself when last conn/route is removed */ } static int ksocknal_del_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ip) { LIST_HEAD(zombies); - struct list_head *ptmp; - struct list_head *pnxt; - struct ksock_peer *peer; + struct ksock_peer *pnxt; + struct ksock_peer *peer_ni; int lo; int hi; int i; @@ -575,30 +574,32 @@ ksocknal_del_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ip) } for (i = lo; i <= hi; i++) { - list_for_each_safe(ptmp, pnxt, &ksocknal_data.ksnd_peers[i]) { - peer = list_entry(ptmp, struct ksock_peer, ksnp_list); - - if (peer->ksnp_ni != ni) + list_for_each_entry_safe(peer_ni, pnxt, + &ksocknal_data.ksnd_peers[i], + ksnp_list) { + if (peer_ni->ksnp_ni != ni) continue; - if (!((id.nid == LNET_NID_ANY || peer->ksnp_id.nid == id.nid) && - (id.pid == LNET_PID_ANY || peer->ksnp_id.pid == id.pid))) + if (!((id.nid == LNET_NID_ANY || + peer_ni->ksnp_id.nid == id.nid) && + (id.pid == LNET_PID_ANY || + peer_ni->ksnp_id.pid == id.pid))) continue; - ksocknal_peer_addref(peer); /* a ref for me... */ + ksocknal_peer_addref(peer_ni); /* a ref for me... */ - ksocknal_del_peer_locked(peer, ip); + ksocknal_del_peer_locked(peer_ni, ip); - if (peer->ksnp_closing && - !list_empty(&peer->ksnp_tx_queue)) { - LASSERT(list_empty(&peer->ksnp_conns)); - LASSERT(list_empty(&peer->ksnp_routes)); + if (peer_ni->ksnp_closing && + !list_empty(&peer_ni->ksnp_tx_queue)) { + LASSERT(list_empty(&peer_ni->ksnp_conns)); + LASSERT(list_empty(&peer_ni->ksnp_routes)); - list_splice_init(&peer->ksnp_tx_queue, + list_splice_init(&peer_ni->ksnp_tx_queue, &zombies); } - ksocknal_peer_decref(peer); /* ...till here */ + ksocknal_peer_decref(peer_ni); /* ...till here */ rc = 0; /* matched! */ } @@ -614,20 +615,22 @@ ksocknal_del_peer(struct lnet_ni *ni, struct lnet_process_id id, __u32 ip) static struct ksock_conn * ksocknal_get_conn_by_idx(struct lnet_ni *ni, int index) { - struct ksock_peer *peer; + struct ksock_peer *peer_ni; struct ksock_conn *conn; int i; read_lock(&ksocknal_data.ksnd_global_lock); for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) { - list_for_each_entry(peer, &ksocknal_data.ksnd_peers[i], ksnp_list) { - LASSERT(!peer->ksnp_closing); + list_for_each_entry(peer_ni, &ksocknal_data.ksnd_peers[i], + ksnp_list) { + LASSERT(!peer_ni->ksnp_closing); - if (peer->ksnp_ni != ni) + if (peer_ni->ksnp_ni != ni) continue; - list_for_each_entry(conn, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn, &peer_ni->ksnp_conns, + ksnc_list) { if (index-- > 0) continue; @@ -728,10 +731,10 @@ ksocknal_match_peerip(struct ksock_interface *iface, __u32 *ips, int nips) } static int -ksocknal_select_ips(struct ksock_peer *peer, __u32 *peerips, int n_peerips) +ksocknal_select_ips(struct ksock_peer *peer_ni, __u32 *peerips, int n_peerips) { rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; - struct ksock_net *net = peer->ksnp_ni->ni_data; + struct ksock_net *net = peer_ni->ksnp_ni->ni_data; struct ksock_interface *iface; struct ksock_interface *best_iface; int n_ips; @@ -766,26 +769,26 @@ ksocknal_select_ips(struct ksock_peer *peer, __u32 *peerips, int n_peerips) n_ips = (net->ksnn_ninterfaces < 2) ? 0 : min(n_peerips, net->ksnn_ninterfaces); - for (i = 0; peer->ksnp_n_passive_ips < n_ips; i++) { + for (i = 0; peer_ni->ksnp_n_passive_ips < n_ips; i++) { /* ^ yes really... */ /* * If we have any new interfaces, first tick off all the - * peer IPs that match old interfaces, then choose new - * interfaces to match the remaining peer IPS. + * peer_ni IPs that match old interfaces, then choose new + * interfaces to match the remaining peer_ni IPS. * We don't forget interfaces we've stopped using; we might * start using them again... */ - if (i < peer->ksnp_n_passive_ips) { + if (i < peer_ni->ksnp_n_passive_ips) { /* Old interface. */ - ip = peer->ksnp_passive_ips[i]; - best_iface = ksocknal_ip2iface(peer->ksnp_ni, ip); + ip = peer_ni->ksnp_passive_ips[i]; + best_iface = ksocknal_ip2iface(peer_ni->ksnp_ni, ip); - /* peer passive ips are kept up to date */ + /* peer_ni passive ips are kept up to date */ LASSERT(best_iface); } else { /* choose a new interface */ - LASSERT(i == peer->ksnp_n_passive_ips); + LASSERT(i == peer_ni->ksnp_n_passive_ips); best_iface = NULL; best_netmatch = 0; @@ -795,11 +798,14 @@ ksocknal_select_ips(struct ksock_peer *peer, __u32 *peerips, int n_peerips) iface = &net->ksnn_interfaces[j]; ip = iface->ksni_ipaddr; - for (k = 0; k < peer->ksnp_n_passive_ips; k++) - if (peer->ksnp_passive_ips[k] == ip) + for (k = 0; + k < peer_ni->ksnp_n_passive_ips; + k++) + if (peer_ni->ksnp_passive_ips[k] == ip) break; - if (k < peer->ksnp_n_passive_ips) /* using it already */ + if (k < peer_ni->ksnp_n_passive_ips) + /* using it already */ continue; k = ksocknal_match_peerip(iface, peerips, @@ -822,17 +828,17 @@ ksocknal_select_ips(struct ksock_peer *peer, __u32 *peerips, int n_peerips) best_iface->ksni_npeers++; ip = best_iface->ksni_ipaddr; - peer->ksnp_passive_ips[i] = ip; - peer->ksnp_n_passive_ips = i + 1; + peer_ni->ksnp_passive_ips[i] = ip; + peer_ni->ksnp_n_passive_ips = i + 1; } - /* mark the best matching peer IP used */ + /* mark the best matching peer_ni IP used */ j = ksocknal_match_peerip(best_iface, peerips, n_peerips); peerips[j] = 0; } - /* Overwrite input peer IP addresses */ - memcpy(peerips, peer->ksnp_passive_ips, n_ips * sizeof(*peerips)); + /* Overwrite input peer_ni IP addresses */ + memcpy(peerips, peer_ni->ksnp_passive_ips, n_ips * sizeof(*peerips)); write_unlock_bh(global_lock); @@ -840,12 +846,12 @@ ksocknal_select_ips(struct ksock_peer *peer, __u32 *peerips, int n_peerips) } static void -ksocknal_create_routes(struct ksock_peer *peer, int port, +ksocknal_create_routes(struct ksock_peer *peer_ni, int port, __u32 *peer_ipaddrs, int npeer_ipaddrs) { struct ksock_route *newroute = NULL; rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; - struct lnet_ni *ni = peer->ksnp_ni; + struct lnet_ni *ni = peer_ni->ksnp_ni; struct ksock_net *net = ni->ni_data; struct ksock_route *route; struct ksock_interface *iface; @@ -888,13 +894,13 @@ ksocknal_create_routes(struct ksock_peer *peer, int port, write_lock_bh(global_lock); } - if (peer->ksnp_closing) { - /* peer got closed under me */ + if (peer_ni->ksnp_closing) { + /* peer_ni got closed under me */ break; } /* Already got a route? */ - list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) + list_for_each_entry(route, &peer_ni->ksnp_routes, ksnr_list) if (route->ksnr_ipaddr != newroute->ksnr_ipaddr) goto next_ipaddr; @@ -909,7 +915,8 @@ ksocknal_create_routes(struct ksock_peer *peer, int port, iface = &net->ksnn_interfaces[j]; /* Using this interface already? */ - list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) + list_for_each_entry(route, &peer_ni->ksnp_routes, + ksnr_list) if (route->ksnr_myipaddr == iface->ksni_ipaddr) goto next_iface; @@ -935,7 +942,7 @@ ksocknal_create_routes(struct ksock_peer *peer, int port, newroute->ksnr_myipaddr = best_iface->ksni_ipaddr; best_iface->ksni_nroutes++; - ksocknal_add_route_locked(peer, newroute); + ksocknal_add_route_locked(peer_ni, newroute); newroute = NULL; next_ipaddr:; } @@ -977,11 +984,11 @@ ksocknal_accept(struct lnet_ni *ni, struct socket *sock) } static int -ksocknal_connecting(struct ksock_peer *peer, __u32 ipaddr) +ksocknal_connecting(struct ksock_peer *peer_ni, __u32 ipaddr) { struct ksock_route *route; - list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) { + list_for_each_entry(route, &peer_ni->ksnp_routes, ksnr_list) { if (route->ksnr_ipaddr == ipaddr) return route->ksnr_connecting; } @@ -998,7 +1005,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, __u64 incarnation; struct ksock_conn *conn; struct ksock_conn *conn2; - struct ksock_peer *peer = NULL; + struct ksock_peer *peer_ni = NULL; struct ksock_peer *peer2; struct ksock_sched *sched; struct ksock_hello_msg *hello; @@ -1054,21 +1061,21 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, goto failed_1; /* - * Find out/confirm peer's NID and connection type and get the + * Find out/confirm peer_ni's NID and connection type and get the * vector of interfaces she's willing to let me connect to. - * Passive connections use the listener timeout since the peer sends + * Passive connections use the listener timeout since the peer_ni sends * eagerly */ if (active) { - peer = route->ksnr_peer; - LASSERT(ni == peer->ksnp_ni); + peer_ni = route->ksnr_peer; + LASSERT(ni == peer_ni->ksnp_ni); /* Active connection sends HELLO eagerly */ hello->kshm_nips = ksocknal_local_ipvec(ni, hello->kshm_ips); - peerid = peer->ksnp_id; + peerid = peer_ni->ksnp_id; write_lock_bh(global_lock); - conn->ksnc_proto = peer->ksnp_proto; + conn->ksnc_proto = peer_ni->ksnp_proto; write_unlock_bh(global_lock); if (!conn->ksnc_proto) { @@ -1088,7 +1095,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, peerid.nid = LNET_NID_ANY; peerid.pid = LNET_PID_ANY; - /* Passive, get protocol from peer */ + /* Passive, get protocol from peer_ni */ conn->ksnc_proto = NULL; } @@ -1103,10 +1110,10 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, cpt = lnet_cpt_of_nid(peerid.nid, ni); if (active) { - ksocknal_peer_addref(peer); + ksocknal_peer_addref(peer_ni); write_lock_bh(global_lock); } else { - rc = ksocknal_create_peer(&peer, ni, peerid); + rc = ksocknal_create_peer(&peer_ni, ni, peerid); if (rc) goto failed_1; @@ -1118,61 +1125,61 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, peer2 = ksocknal_find_peer_locked(ni, peerid); if (!peer2) { /* - * NB this puts an "empty" peer in the peer + * NB this puts an "empty" peer_ni in the peer * table (which takes my ref) */ - list_add_tail(&peer->ksnp_list, + list_add_tail(&peer_ni->ksnp_list, ksocknal_nid2peerlist(peerid.nid)); } else { - ksocknal_peer_decref(peer); - peer = peer2; + ksocknal_peer_decref(peer_ni); + peer_ni = peer2; } /* +1 ref for me */ - ksocknal_peer_addref(peer); - peer->ksnp_accepting++; + ksocknal_peer_addref(peer_ni); + peer_ni->ksnp_accepting++; /* * Am I already connecting to this guy? Resolve in * favour of higher NID... */ if (peerid.nid < ni->ni_nid && - ksocknal_connecting(peer, conn->ksnc_ipaddr)) { + ksocknal_connecting(peer_ni, conn->ksnc_ipaddr)) { rc = EALREADY; warn = "connection race resolution"; goto failed_2; } } - if (peer->ksnp_closing || + if (peer_ni->ksnp_closing || (active && route->ksnr_deleted)) { - /* peer/route got closed under me */ + /* peer_ni/route got closed under me */ rc = -ESTALE; - warn = "peer/route removed"; + warn = "peer_ni/route removed"; goto failed_2; } - if (!peer->ksnp_proto) { + if (!peer_ni->ksnp_proto) { /* * Never connected before. * NB recv_hello may have returned EPROTO to signal my peer * wants a different protocol than the one I asked for. */ - LASSERT(list_empty(&peer->ksnp_conns)); + LASSERT(list_empty(&peer_ni->ksnp_conns)); - peer->ksnp_proto = conn->ksnc_proto; - peer->ksnp_incarnation = incarnation; + peer_ni->ksnp_proto = conn->ksnc_proto; + peer_ni->ksnp_incarnation = incarnation; } - if (peer->ksnp_proto != conn->ksnc_proto || - peer->ksnp_incarnation != incarnation) { - /* Peer rebooted or I've got the wrong protocol version */ - ksocknal_close_peer_conns_locked(peer, 0, 0); + if (peer_ni->ksnp_proto != conn->ksnc_proto || + peer_ni->ksnp_incarnation != incarnation) { + /* peer_ni rebooted or I've got the wrong protocol version */ + ksocknal_close_peer_conns_locked(peer_ni, 0, 0); - peer->ksnp_proto = NULL; + peer_ni->ksnp_proto = NULL; rc = ESTALE; - warn = peer->ksnp_incarnation != incarnation ? - "peer rebooted" : + warn = peer_ni->ksnp_incarnation != incarnation ? + "peer_ni rebooted" : "wrong proto version"; goto failed_2; } @@ -1195,7 +1202,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, * loopback connection */ if (conn->ksnc_ipaddr != conn->ksnc_myipaddr) { - list_for_each_entry(conn2, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn2, &peer_ni->ksnp_conns, ksnc_list) { if (conn2->ksnc_ipaddr != conn->ksnc_ipaddr || conn2->ksnc_myipaddr != conn->ksnc_myipaddr || @@ -1223,7 +1230,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, if (active && route->ksnr_ipaddr != conn->ksnc_ipaddr) { CERROR("Route %s %pI4h connected to %pI4h\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &route->ksnr_ipaddr, &conn->ksnc_ipaddr); } @@ -1231,10 +1238,10 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, /* * Search for a route corresponding to the new connection and * create an association. This allows incoming connections created - * by routes in my peer to match my own route entries so I don't + * by routes in my peer_ni to match my own route entries so I don't * continually create duplicate routes. */ - list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) { + list_for_each_entry(route, &peer_ni->ksnp_routes, ksnr_list) { if (route->ksnr_ipaddr != conn->ksnc_ipaddr) continue; @@ -1242,10 +1249,10 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, break; } - conn->ksnc_peer = peer; /* conn takes my ref on peer */ - peer->ksnp_last_alive = ktime_get_seconds(); - peer->ksnp_send_keepalive = 0; - peer->ksnp_error = 0; + conn->ksnc_peer = peer_ni; /* conn takes my ref on peer_ni */ + peer_ni->ksnp_last_alive = ktime_get_seconds(); + peer_ni->ksnp_send_keepalive = 0; + peer_ni->ksnp_error = 0; sched = ksocknal_choose_scheduler_locked(cpt); sched->kss_nconns++; @@ -1256,9 +1263,9 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, conn->ksnc_tx_bufnob = sock->sk->sk_wmem_queued; conn->ksnc_tx_deadline = ktime_get_seconds() + *ksocknal_tunables.ksnd_timeout; - mb(); /* order with adding to peer's conn list */ + mb(); /* order with adding to peer_ni's conn list */ - list_add(&conn->ksnc_list, &peer->ksnp_conns); + list_add(&conn->ksnc_list, &peer_ni->ksnp_conns); ksocknal_conn_addref(conn); ksocknal_new_packet(conn, 0); @@ -1266,7 +1273,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, conn->ksnc_zc_capable = ksocknal_lib_zc_capable(conn); /* Take packets blocking for this connection. */ - list_for_each_entry_safe(tx, txtmp, &peer->ksnp_tx_queue, tx_list) { + list_for_each_entry_safe(tx, txtmp, &peer_ni->ksnp_tx_queue, tx_list) { int match = conn->ksnc_proto->pro_match_tx(conn, tx, tx->tx_nonblk); @@ -1295,10 +1302,10 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, if (active) { /* additional routes after interface exchange? */ - ksocknal_create_routes(peer, conn->ksnc_port, + ksocknal_create_routes(peer_ni, conn->ksnc_port, hello->kshm_ips, hello->kshm_nips); } else { - hello->kshm_nips = ksocknal_select_ips(peer, hello->kshm_ips, + hello->kshm_nips = ksocknal_select_ips(peer_ni, hello->kshm_ips, hello->kshm_nips); rc = ksocknal_send_hello(ni, conn, peerid.nid, hello); } @@ -1321,7 +1328,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, ksocknal_lib_set_callback(sock, conn); if (!active) - peer->ksnp_accepting--; + peer_ni->ksnp_accepting--; write_unlock_bh(global_lock); @@ -1344,12 +1351,12 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, return rc; failed_2: - if (!peer->ksnp_closing && - list_empty(&peer->ksnp_conns) && - list_empty(&peer->ksnp_routes)) { - list_add(&zombies, &peer->ksnp_tx_queue); - list_del_init(&peer->ksnp_tx_queue); - ksocknal_unlink_peer_locked(peer); + if (!peer_ni->ksnp_closing && + list_empty(&peer_ni->ksnp_conns) && + list_empty(&peer_ni->ksnp_routes)) { + list_add(&zombies, &peer_ni->ksnp_tx_queue); + list_del_init(&peer_ni->ksnp_tx_queue); + ksocknal_unlink_peer_locked(peer_ni); } write_unlock_bh(global_lock); @@ -1375,12 +1382,12 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, } write_lock_bh(global_lock); - peer->ksnp_accepting--; + peer_ni->ksnp_accepting--; write_unlock_bh(global_lock); } ksocknal_txlist_done(ni, &zombies, 1); - ksocknal_peer_decref(peer); + ksocknal_peer_decref(peer_ni); failed_1: kvfree(hello); @@ -1400,15 +1407,15 @@ ksocknal_close_conn_locked(struct ksock_conn *conn, int error) * connection for the reaper to terminate. * Caller holds ksnd_global_lock exclusively in irq context */ - struct ksock_peer *peer = conn->ksnc_peer; + struct ksock_peer *peer_ni = conn->ksnc_peer; struct ksock_route *route; struct ksock_conn *conn2; - LASSERT(!peer->ksnp_error); + LASSERT(!peer_ni->ksnp_error); LASSERT(!conn->ksnc_closing); conn->ksnc_closing = 1; - /* ksnd_deathrow_conns takes over peer's ref */ + /* ksnd_deathrow_conns takes over peer_ni's ref */ list_del(&conn->ksnc_list); route = conn->ksnc_route; @@ -1417,7 +1424,7 @@ ksocknal_close_conn_locked(struct ksock_conn *conn, int error) LASSERT(!route->ksnr_deleted); LASSERT(route->ksnr_connected & (1 << conn->ksnc_type)); - list_for_each_entry(conn2, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn2, &peer_ni->ksnp_conns, ksnc_list) { if (conn2->ksnc_route == route && conn2->ksnc_type == conn->ksnc_type) goto conn2_found; @@ -1429,10 +1436,10 @@ ksocknal_close_conn_locked(struct ksock_conn *conn, int error) ksocknal_route_decref(route); /* drop conn's ref on route */ } - if (list_empty(&peer->ksnp_conns)) { - /* No more connections to this peer */ + if (list_empty(&peer_ni->ksnp_conns)) { + /* No more connections to this peer_ni */ - if (!list_empty(&peer->ksnp_tx_queue)) { + if (!list_empty(&peer_ni->ksnp_tx_queue)) { struct ksock_tx *tx; LASSERT(conn->ksnc_proto == &ksocknal_protocol_v3x); @@ -1441,25 +1448,25 @@ ksocknal_close_conn_locked(struct ksock_conn *conn, int error) * throw them to the last connection..., * these TXs will be send to /dev/null by scheduler */ - list_for_each_entry(tx, &peer->ksnp_tx_queue, + list_for_each_entry(tx, &peer_ni->ksnp_tx_queue, tx_list) ksocknal_tx_prep(conn, tx); spin_lock_bh(&conn->ksnc_scheduler->kss_lock); - list_splice_init(&peer->ksnp_tx_queue, + list_splice_init(&peer_ni->ksnp_tx_queue, &conn->ksnc_tx_queue); spin_unlock_bh(&conn->ksnc_scheduler->kss_lock); } - peer->ksnp_proto = NULL; /* renegotiate protocol version */ - peer->ksnp_error = error; /* stash last conn close reason */ + peer_ni->ksnp_proto = NULL; /* renegotiate protocol version */ + peer_ni->ksnp_error = error; /* stash last conn close reason */ - if (list_empty(&peer->ksnp_routes)) { + if (list_empty(&peer_ni->ksnp_routes)) { /* * I've just closed last conn belonging to a - * peer with no routes to it + * peer_ni with no routes to it */ - ksocknal_unlink_peer_locked(peer); + ksocknal_unlink_peer_locked(peer_ni); } } @@ -1473,37 +1480,37 @@ ksocknal_close_conn_locked(struct ksock_conn *conn, int error) } void -ksocknal_peer_failed(struct ksock_peer *peer) +ksocknal_peer_failed(struct ksock_peer *peer_ni) { int notify = 0; time64_t last_alive = 0; /* * There has been a connection failure or comms error; but I'll only - * tell LNET I think the peer is dead if it's to another kernel and + * tell LNET I think the peer_ni is dead if it's to another kernel and * there are no connections or connection attempts in existence. */ read_lock(&ksocknal_data.ksnd_global_lock); - if (!(peer->ksnp_id.pid & LNET_PID_USERFLAG) && - list_empty(&peer->ksnp_conns) && - !peer->ksnp_accepting && - !ksocknal_find_connecting_route_locked(peer)) { + if (!(peer_ni->ksnp_id.pid & LNET_PID_USERFLAG) && + list_empty(&peer_ni->ksnp_conns) && + !peer_ni->ksnp_accepting && + !ksocknal_find_connecting_route_locked(peer_ni)) { notify = 1; - last_alive = peer->ksnp_last_alive; + last_alive = peer_ni->ksnp_last_alive; } read_unlock(&ksocknal_data.ksnd_global_lock); if (notify) - lnet_notify(peer->ksnp_ni, peer->ksnp_id.nid, 0, + lnet_notify(peer_ni->ksnp_ni, peer_ni->ksnp_id.nid, 0, last_alive); } void ksocknal_finalize_zcreq(struct ksock_conn *conn) { - struct ksock_peer *peer = conn->ksnc_peer; + struct ksock_peer *peer_ni = conn->ksnc_peer; struct ksock_tx *tx; struct ksock_tx *tmp; LIST_HEAD(zlist); @@ -1514,9 +1521,10 @@ ksocknal_finalize_zcreq(struct ksock_conn *conn) */ LASSERT(!conn->ksnc_sock); - spin_lock(&peer->ksnp_lock); + spin_lock(&peer_ni->ksnp_lock); - list_for_each_entry_safe(tx, tmp, &peer->ksnp_zc_req_list, tx_zc_list) { + list_for_each_entry_safe(tx, tmp, &peer_ni->ksnp_zc_req_list, + tx_zc_list) { if (tx->tx_conn != conn) continue; @@ -1528,7 +1536,7 @@ ksocknal_finalize_zcreq(struct ksock_conn *conn) list_add(&tx->tx_zc_list, &zlist); } - spin_unlock(&peer->ksnp_lock); + spin_unlock(&peer_ni->ksnp_lock); while (!list_empty(&zlist)) { tx = list_entry(zlist.next, struct ksock_tx, tx_zc_list); @@ -1547,7 +1555,7 @@ ksocknal_terminate_conn(struct ksock_conn *conn) * ksnc_refcount will eventually hit zero, and then the reaper will * destroy it. */ - struct ksock_peer *peer = conn->ksnc_peer; + struct ksock_peer *peer_ni = conn->ksnc_peer; struct ksock_sched *sched = conn->ksnc_scheduler; int failed = 0; @@ -1583,17 +1591,17 @@ ksocknal_terminate_conn(struct ksock_conn *conn) */ conn->ksnc_scheduler->kss_nconns--; - if (peer->ksnp_error) { - /* peer's last conn closed in error */ - LASSERT(list_empty(&peer->ksnp_conns)); + if (peer_ni->ksnp_error) { + /* peer_ni's last conn closed in error */ + LASSERT(list_empty(&peer_ni->ksnp_conns)); failed = 1; - peer->ksnp_error = 0; /* avoid multiple notifications */ + peer_ni->ksnp_error = 0; /* avoid multiple notifications */ } write_unlock_bh(&ksocknal_data.ksnd_global_lock); if (failed) - ksocknal_peer_failed(peer); + ksocknal_peer_failed(peer_ni); /* * The socket is closed on the final put; either here, or in @@ -1679,14 +1687,15 @@ ksocknal_destroy_conn(struct ksock_conn *conn) } int -ksocknal_close_peer_conns_locked(struct ksock_peer *peer, __u32 ipaddr, int why) +ksocknal_close_peer_conns_locked(struct ksock_peer *peer_ni, + __u32 ipaddr, int why) { struct ksock_conn *conn; struct list_head *ctmp; struct list_head *cnxt; int count = 0; - list_for_each_safe(ctmp, cnxt, &peer->ksnp_conns) { + list_for_each_safe(ctmp, cnxt, &peer_ni->ksnp_conns) { conn = list_entry(ctmp, struct ksock_conn, ksnc_list); if (!ipaddr || conn->ksnc_ipaddr == ipaddr) { @@ -1701,13 +1710,13 @@ ksocknal_close_peer_conns_locked(struct ksock_peer *peer, __u32 ipaddr, int why) int ksocknal_close_conn_and_siblings(struct ksock_conn *conn, int why) { - struct ksock_peer *peer = conn->ksnc_peer; + struct ksock_peer *peer_ni = conn->ksnc_peer; __u32 ipaddr = conn->ksnc_ipaddr; int count; write_lock_bh(&ksocknal_data.ksnd_global_lock); - count = ksocknal_close_peer_conns_locked(peer, ipaddr, why); + count = ksocknal_close_peer_conns_locked(peer_ni, ipaddr, why); write_unlock_bh(&ksocknal_data.ksnd_global_lock); @@ -1717,9 +1726,8 @@ ksocknal_close_conn_and_siblings(struct ksock_conn *conn, int why) int ksocknal_close_matching_conns(struct lnet_process_id id, __u32 ipaddr) { - struct ksock_peer *peer; - struct list_head *ptmp; - struct list_head *pnxt; + struct ksock_peer *peer_ni; + struct ksock_peer *pnxt; int lo; int hi; int i; @@ -1736,16 +1744,17 @@ ksocknal_close_matching_conns(struct lnet_process_id id, __u32 ipaddr) } for (i = lo; i <= hi; i++) { - list_for_each_safe(ptmp, pnxt, - &ksocknal_data.ksnd_peers[i]) { - peer = list_entry(ptmp, struct ksock_peer, ksnp_list); - - if (!((id.nid == LNET_NID_ANY || id.nid == peer->ksnp_id.nid) && - (id.pid == LNET_PID_ANY || id.pid == peer->ksnp_id.pid))) + list_for_each_entry_safe(peer_ni, pnxt, + &ksocknal_data.ksnd_peers[i], + ksnp_list) { + if (!((id.nid == LNET_NID_ANY || + id.nid == peer_ni->ksnp_id.nid) && + (id.pid == LNET_PID_ANY || + id.pid == peer_ni->ksnp_id.pid))) continue; - count += ksocknal_close_peer_conns_locked(peer, ipaddr, - 0); + count += ksocknal_close_peer_conns_locked(peer_ni, + ipaddr, 0); } } @@ -1794,7 +1803,7 @@ ksocknal_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when) int connect = 1; time64_t last_alive = 0; time64_t now = ktime_get_seconds(); - struct ksock_peer *peer = NULL; + struct ksock_peer *peer_ni = NULL; rwlock_t *glock = &ksocknal_data.ksnd_global_lock; struct lnet_process_id id = { .nid = nid, @@ -1803,25 +1812,25 @@ ksocknal_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when) read_lock(glock); - peer = ksocknal_find_peer_locked(ni, id); - if (peer) { + peer_ni = ksocknal_find_peer_locked(ni, id); + if (peer_ni) { struct ksock_conn *conn; int bufnob; - list_for_each_entry(conn, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn, &peer_ni->ksnp_conns, ksnc_list) { bufnob = conn->ksnc_sock->sk->sk_wmem_queued; if (bufnob < conn->ksnc_tx_bufnob) { /* something got ACKed */ conn->ksnc_tx_deadline = ktime_get_seconds() + *ksocknal_tunables.ksnd_timeout; - peer->ksnp_last_alive = now; + peer_ni->ksnp_last_alive = now; conn->ksnc_tx_bufnob = bufnob; } } - last_alive = peer->ksnp_last_alive; - if (!ksocknal_find_connectable_route_locked(peer)) + last_alive = peer_ni->ksnp_last_alive; + if (!ksocknal_find_connectable_route_locked(peer_ni)) connect = 0; } @@ -1830,8 +1839,8 @@ ksocknal_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when) if (last_alive) *when = last_alive * HZ; - CDEBUG(D_NET, "Peer %s %p, alive %lld secs ago, connect %d\n", - libcfs_nid2str(nid), peer, + CDEBUG(D_NET, "peer_ni %s %p, alive %lld secs ago, connect %d\n", + libcfs_nid2str(nid), peer_ni, last_alive ? now - last_alive : -1, connect); @@ -1842,15 +1851,15 @@ ksocknal_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when) write_lock_bh(glock); - peer = ksocknal_find_peer_locked(ni, id); - if (peer) - ksocknal_launch_all_connections_locked(peer); + peer_ni = ksocknal_find_peer_locked(ni, id); + if (peer_ni) + ksocknal_launch_all_connections_locked(peer_ni); write_unlock_bh(glock); } static void -ksocknal_push_peer(struct ksock_peer *peer) +ksocknal_push_peer(struct ksock_peer *peer_ni) { int index; int i; @@ -1862,7 +1871,7 @@ ksocknal_push_peer(struct ksock_peer *peer) i = 0; conn = NULL; - list_for_each_entry(conn, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn, &peer_ni->ksnp_conns, ksnc_list) { if (i++ == index) { ksocknal_conn_addref(conn); break; @@ -1896,22 +1905,22 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) } for (tmp = start; tmp <= end; tmp++) { - int peer_off; /* searching offset in peer hash table */ + int peer_off; /* searching offset in peer_ni hash table */ for (peer_off = 0; ; peer_off++) { - struct ksock_peer *peer; + struct ksock_peer *peer_ni; int i = 0; read_lock(&ksocknal_data.ksnd_global_lock); - list_for_each_entry(peer, tmp, ksnp_list) { + list_for_each_entry(peer_ni, tmp, ksnp_list) { if (!((id.nid == LNET_NID_ANY || - id.nid == peer->ksnp_id.nid) && + id.nid == peer_ni->ksnp_id.nid) && (id.pid == LNET_PID_ANY || - id.pid == peer->ksnp_id.pid))) + id.pid == peer_ni->ksnp_id.pid))) continue; if (i++ == peer_off) { - ksocknal_peer_addref(peer); + ksocknal_peer_addref(peer_ni); break; } } @@ -1921,8 +1930,8 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) break; rc = 0; - ksocknal_push_peer(peer); - ksocknal_peer_decref(peer); + ksocknal_push_peer(peer_ni); + ksocknal_peer_decref(peer_ni); } } return rc; @@ -1936,7 +1945,7 @@ ksocknal_add_interface(struct lnet_ni *ni, __u32 ipaddress, __u32 netmask) int rc; int i; int j; - struct ksock_peer *peer; + struct ksock_peer *peer_ni; struct ksock_route *route; if (!ipaddress || !netmask) @@ -1959,14 +1968,19 @@ ksocknal_add_interface(struct lnet_ni *ni, __u32 ipaddress, __u32 netmask) iface->ksni_npeers = 0; for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) { - list_for_each_entry(peer, &ksocknal_data.ksnd_peers[i], + list_for_each_entry(peer_ni, + &ksocknal_data.ksnd_peers[i], ksnp_list) { - for (j = 0; j < peer->ksnp_n_passive_ips; j++) - if (peer->ksnp_passive_ips[j] == ipaddress) + for (j = 0; + j < peer_ni->ksnp_n_passive_ips; + j++) + if (peer_ni->ksnp_passive_ips[j] == + ipaddress) iface->ksni_npeers++; - list_for_each_entry(route, &peer->ksnp_routes, + list_for_each_entry(route, + &peer_ni->ksnp_routes, ksnr_list) { if (route->ksnr_myipaddr == ipaddress) iface->ksni_nroutes++; @@ -1987,7 +2001,7 @@ ksocknal_add_interface(struct lnet_ni *ni, __u32 ipaddress, __u32 netmask) } static void -ksocknal_peer_del_interface_locked(struct ksock_peer *peer, __u32 ipaddr) +ksocknal_peer_del_interface_locked(struct ksock_peer *peer_ni, __u32 ipaddr) { struct list_head *tmp; struct list_head *nxt; @@ -1996,16 +2010,16 @@ ksocknal_peer_del_interface_locked(struct ksock_peer *peer, __u32 ipaddr) int i; int j; - for (i = 0; i < peer->ksnp_n_passive_ips; i++) - if (peer->ksnp_passive_ips[i] == ipaddr) { - for (j = i + 1; j < peer->ksnp_n_passive_ips; j++) - peer->ksnp_passive_ips[j - 1] = - peer->ksnp_passive_ips[j]; - peer->ksnp_n_passive_ips--; + for (i = 0; i < peer_ni->ksnp_n_passive_ips; i++) + if (peer_ni->ksnp_passive_ips[i] == ipaddr) { + for (j = i + 1; j < peer_ni->ksnp_n_passive_ips; j++) + peer_ni->ksnp_passive_ips[j - 1] = + peer_ni->ksnp_passive_ips[j]; + peer_ni->ksnp_n_passive_ips--; break; } - list_for_each_safe(tmp, nxt, &peer->ksnp_routes) { + list_for_each_safe(tmp, nxt, &peer_ni->ksnp_routes) { route = list_entry(tmp, struct ksock_route, ksnr_list); if (route->ksnr_myipaddr != ipaddr) @@ -2019,7 +2033,7 @@ ksocknal_peer_del_interface_locked(struct ksock_peer *peer, __u32 ipaddr) } } - list_for_each_safe(tmp, nxt, &peer->ksnp_conns) { + list_for_each_safe(tmp, nxt, &peer_ni->ksnp_conns) { conn = list_entry(tmp, struct ksock_conn, ksnc_list); if (conn->ksnc_myipaddr == ipaddr) @@ -2032,9 +2046,8 @@ ksocknal_del_interface(struct lnet_ni *ni, __u32 ipaddress) { struct ksock_net *net = ni->ni_data; int rc = -ENOENT; - struct list_head *tmp; - struct list_head *nxt; - struct ksock_peer *peer; + struct ksock_peer *nxt; + struct ksock_peer *peer_ni; __u32 this_ip; int i; int j; @@ -2056,14 +2069,14 @@ ksocknal_del_interface(struct lnet_ni *ni, __u32 ipaddress) net->ksnn_ninterfaces--; for (j = 0; j < ksocknal_data.ksnd_peer_hash_size; j++) { - list_for_each_safe(tmp, nxt, - &ksocknal_data.ksnd_peers[j]) { - peer = list_entry(tmp, struct ksock_peer, ksnp_list); - - if (peer->ksnp_ni != ni) + list_for_each_entry_safe(peer_ni, nxt, + &ksocknal_data.ksnd_peers[j], + ksnp_list) { + if (peer_ni->ksnp_ni != ni) continue; - ksocknal_peer_del_interface_locked(peer, this_ip); + ksocknal_peer_del_interface_locked(peer_ni, + this_ip); } } } @@ -2461,36 +2474,41 @@ ksocknal_base_startup(void) static void ksocknal_debug_peerhash(struct lnet_ni *ni) { - struct ksock_peer *peer = NULL; + struct ksock_peer *peer_ni = NULL; int i; read_lock(&ksocknal_data.ksnd_global_lock); for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) { - list_for_each_entry(peer, &ksocknal_data.ksnd_peers[i], ksnp_list) { + list_for_each_entry(peer_ni, &ksocknal_data.ksnd_peers[i], + ksnp_list) { struct ksock_route *route; struct ksock_conn *conn; - if (peer->ksnp_ni != ni) + if (peer_ni->ksnp_ni != ni) continue; - CWARN("Active peer on shutdown: %s, ref %d, scnt %d, closing %d, accepting %d, err %d, zcookie %llu, txq %d, zc_req %d\n", - libcfs_id2str(peer->ksnp_id), - atomic_read(&peer->ksnp_refcount), - peer->ksnp_sharecount, peer->ksnp_closing, - peer->ksnp_accepting, peer->ksnp_error, - peer->ksnp_zc_next_cookie, - !list_empty(&peer->ksnp_tx_queue), - !list_empty(&peer->ksnp_zc_req_list)); + CWARN("Active peer_ni on shutdown: %s, ref %d, scnt %d, closing %d, accepting %d, err %d, zcookie %llu, txq %d, zc_req %d\n", + libcfs_id2str(peer_ni->ksnp_id), + atomic_read(&peer_ni->ksnp_refcount), + peer_ni->ksnp_sharecount, peer_ni->ksnp_closing, + peer_ni->ksnp_accepting, peer_ni->ksnp_error, + peer_ni->ksnp_zc_next_cookie, + !list_empty(&peer_ni->ksnp_tx_queue), + !list_empty(&peer_ni->ksnp_zc_req_list)); - list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) { + list_for_each_entry(route, &peer_ni->ksnp_routes, + ksnr_list) { CWARN("Route: ref %d, schd %d, conn %d, cnted %d, del %d\n", atomic_read(&route->ksnr_refcount), - route->ksnr_scheduled, route->ksnr_connecting, - route->ksnr_connected, route->ksnr_deleted); + route->ksnr_scheduled, + route->ksnr_connecting, + route->ksnr_connected, + route->ksnr_deleted); } - list_for_each_entry(conn, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn, &peer_ni->ksnp_conns, + ksnc_list) { CWARN("Conn: ref %d, sref %d, t %d, c %d\n", atomic_read(&conn->ksnc_conn_refcount), atomic_read(&conn->ksnc_sock_refcount), @@ -2523,7 +2541,7 @@ ksocknal_shutdown(struct lnet_ni *ni) /* Delete all peers */ ksocknal_del_peer(ni, anyid, 0); - /* Wait for all peer state to clean up */ + /* Wait for all peer_ni state to clean up */ i = 2; spin_lock_bh(&net->ksnn_lock); while (net->ksnn_npeers) { diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index 2a619291fccc..cc813e4c1422 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h @@ -54,7 +54,7 @@ #define SOCKNAL_NSCHEDS 3 #define SOCKNAL_NSCHEDS_HIGH (SOCKNAL_NSCHEDS << 1) -#define SOCKNAL_PEER_HASH_SIZE 101 /* # peer lists */ +#define SOCKNAL_PEER_HASH_SIZE 101 /* # peer_ni lists */ #define SOCKNAL_RESCHED 100 /* # scheduler loops before reschedule */ #define SOCKNAL_INSANITY_RECONN 5000 /* connd is trying on reconn infinitely */ #define SOCKNAL_ENOMEM_RETRY 1 /* seconds between retries */ @@ -142,10 +142,11 @@ struct ksock_tunables { int *ksnd_credits; /* # concurrent sends */ int *ksnd_peertxcredits; /* # concurrent sends to 1 peer */ - int *ksnd_peerrtrcredits; /* # per-peer router buffer + int *ksnd_peerrtrcredits; /* # per-peer_ni router buffer * credits */ - int *ksnd_peertimeout; /* seconds to consider peer dead + int *ksnd_peertimeout; /* seconds to consider + * peer_ni dead */ int *ksnd_enable_csum; /* enable check sum */ int *ksnd_inject_csum_error; /* set non-zero to inject @@ -185,8 +186,8 @@ struct ksock_nal_data { */ int ksnd_nnets; /* # networks set up */ struct list_head ksnd_nets; /* list of nets */ - rwlock_t ksnd_global_lock; /* stabilize peer/conn - * ops + rwlock_t ksnd_global_lock; /* stabilize + * peer_ni/conn ops */ struct list_head *ksnd_peers; /* hash table of all my * known peers @@ -270,7 +271,7 @@ struct ksock_proto; /* forward ref */ struct ksock_tx { /* transmit packet */ struct list_head tx_list; /* queue on conn for transmission etc */ - struct list_head tx_zc_list; /* queue on peer for ZC request */ + struct list_head tx_zc_list; /* queue on peer_ni for ZC request */ atomic_t tx_refcount; /* tx reference count */ int tx_nob; /* # packet bytes */ int tx_resid; /* residual bytes */ @@ -311,9 +312,9 @@ struct ksock_tx { /* transmit packet */ #define SOCKNAL_RX_SLOP 6 /* skipping body */ struct ksock_conn { - struct ksock_peer *ksnc_peer; /* owning peer */ + struct ksock_peer *ksnc_peer; /* owning peer_ni */ struct ksock_route *ksnc_route; /* owning route */ - struct list_head ksnc_list; /* stash on peer's conn list */ + struct list_head ksnc_list; /* stash on peer_ni's conn list */ struct socket *ksnc_sock; /* actual socket */ void *ksnc_saved_data_ready; /* socket's original * data_ready() callback @@ -326,8 +327,8 @@ struct ksock_conn { struct ksock_sched *ksnc_scheduler; /* who schedules this connection */ __u32 ksnc_myipaddr; /* my IP */ - __u32 ksnc_ipaddr; /* peer's IP */ - int ksnc_port; /* peer's port */ + __u32 ksnc_ipaddr; /* peer_ni's IP */ + int ksnc_port; /* peer_ni's port */ signed int ksnc_type:3; /* type of connection, should be * signed value */ @@ -382,9 +383,9 @@ struct ksock_conn { }; struct ksock_route { - struct list_head ksnr_list; /* chain on peer route list */ + struct list_head ksnr_list; /* chain on peer_ni route list */ struct list_head ksnr_connd_list; /* chain on ksnr_connd_routes */ - struct ksock_peer *ksnr_peer; /* owning peer */ + struct ksock_peer *ksnr_peer; /* owning peer_ni */ atomic_t ksnr_refcount; /* # users */ time64_t ksnr_timeout; /* when (in secs) reconnection * can happen next @@ -400,7 +401,7 @@ struct ksock_route { unsigned int ksnr_connected:4; /* connections established by * type */ - unsigned int ksnr_deleted:1; /* been removed from peer? */ + unsigned int ksnr_deleted:1; /* been removed from peer_ni? */ unsigned int ksnr_share_count; /* created explicitly? */ int ksnr_conn_count; /* # conns established by this * route @@ -410,7 +411,7 @@ struct ksock_route { #define SOCKNAL_KEEPALIVE_PING 1 /* cookie for keepalive ping */ struct ksock_peer { - struct list_head ksnp_list; /* stash on global peer list */ + struct list_head ksnp_list; /* stash on global peer_ni list */ time64_t ksnp_last_alive; /* when (in seconds) I was last * alive */ @@ -422,9 +423,12 @@ struct ksock_peer { */ int ksnp_error; /* errno on closing last conn */ __u64 ksnp_zc_next_cookie; /* ZC completion cookie */ - __u64 ksnp_incarnation; /* latest known peer incarnation + __u64 ksnp_incarnation; /* latest known peer_ni + * incarnation + */ + struct ksock_proto *ksnp_proto; /* latest known peer_ni + * protocol */ - struct ksock_proto *ksnp_proto; /* latest known peer protocol */ struct list_head ksnp_conns; /* all active connections */ struct list_head ksnp_routes; /* routes */ struct list_head ksnp_tx_queue; /* waiting packets */ @@ -606,20 +610,20 @@ ksocknal_route_decref(struct ksock_route *route) } static inline void -ksocknal_peer_addref(struct ksock_peer *peer) +ksocknal_peer_addref(struct ksock_peer *peer_ni) { - LASSERT(atomic_read(&peer->ksnp_refcount) > 0); - atomic_inc(&peer->ksnp_refcount); + LASSERT(atomic_read(&peer_ni->ksnp_refcount) > 0); + atomic_inc(&peer_ni->ksnp_refcount); } -void ksocknal_destroy_peer(struct ksock_peer *peer); +void ksocknal_destroy_peer(struct ksock_peer *peer_ni); static inline void -ksocknal_peer_decref(struct ksock_peer *peer) +ksocknal_peer_decref(struct ksock_peer *peer_ni) { - LASSERT(atomic_read(&peer->ksnp_refcount) > 0); - if (atomic_dec_and_test(&peer->ksnp_refcount)) - ksocknal_destroy_peer(peer); + LASSERT(atomic_read(&peer_ni->ksnp_refcount) > 0); + if (atomic_dec_and_test(&peer_ni->ksnp_refcount)) + ksocknal_destroy_peer(peer_ni); } int ksocknal_startup(struct lnet_ni *ni); @@ -636,17 +640,17 @@ struct ksock_peer *ksocknal_find_peer_locked(struct lnet_ni *ni, struct lnet_process_id id); struct ksock_peer *ksocknal_find_peer(struct lnet_ni *ni, struct lnet_process_id id); -void ksocknal_peer_failed(struct ksock_peer *peer); +void ksocknal_peer_failed(struct ksock_peer *peer_ni); int ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, struct socket *sock, int type); void ksocknal_close_conn_locked(struct ksock_conn *conn, int why); void ksocknal_terminate_conn(struct ksock_conn *conn); void ksocknal_destroy_conn(struct ksock_conn *conn); -int ksocknal_close_peer_conns_locked(struct ksock_peer *peer, +int ksocknal_close_peer_conns_locked(struct ksock_peer *peer_ni, __u32 ipaddr, int why); int ksocknal_close_conn_and_siblings(struct ksock_conn *conn, int why); int ksocknal_close_matching_conns(struct lnet_process_id id, __u32 ipaddr); -struct ksock_conn *ksocknal_find_conn_locked(struct ksock_peer *peer, +struct ksock_conn *ksocknal_find_conn_locked(struct ksock_peer *peer_ni, struct ksock_tx *tx, int nonblk); int ksocknal_launch_packet(struct lnet_ni *ni, struct ksock_tx *tx, @@ -661,9 +665,11 @@ void ksocknal_notify(struct lnet_ni *ni, lnet_nid_t gw_nid, int alive); void ksocknal_query(struct lnet_ni *ni, lnet_nid_t nid, time64_t *when); int ksocknal_thread_start(int (*fn)(void *arg), void *arg, char *name); void ksocknal_thread_fini(void); -void ksocknal_launch_all_connections_locked(struct ksock_peer *peer); -struct ksock_route *ksocknal_find_connectable_route_locked(struct ksock_peer *peer); -struct ksock_route *ksocknal_find_connecting_route_locked(struct ksock_peer *peer); +void ksocknal_launch_all_connections_locked(struct ksock_peer *peer_ni); +struct ksock_route *ksocknal_find_connectable_route_locked( + struct ksock_peer *peer_ni); +struct ksock_route *ksocknal_find_connecting_route_locked( + struct ksock_peer *peer_ni); int ksocknal_new_packet(struct ksock_conn *conn, int skip); int ksocknal_scheduler(void *arg); int ksocknal_connd(void *arg); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 32b76727f400..1bf0170503ed 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -375,12 +375,12 @@ static void ksocknal_check_zc_req(struct ksock_tx *tx) { struct ksock_conn *conn = tx->tx_conn; - struct ksock_peer *peer = conn->ksnc_peer; + struct ksock_peer *peer_ni = conn->ksnc_peer; /* * Set tx_msg.ksm_zc_cookies[0] to a unique non-zero cookie and add tx * to ksnp_zc_req_list if some fragment of this message should be sent - * zero-copy. Our peer will send an ACK containing this cookie when + * zero-copy. Our peer_ni will send an ACK containing this cookie when * she has received this message to tell us we can signal completion. * tx_msg.ksm_zc_cookies[0] remains non-zero while tx is on * ksnp_zc_req_list. @@ -400,46 +400,46 @@ ksocknal_check_zc_req(struct ksock_tx *tx) */ ksocknal_tx_addref(tx); - spin_lock(&peer->ksnp_lock); + spin_lock(&peer_ni->ksnp_lock); - /* ZC_REQ is going to be pinned to the peer */ + /* ZC_REQ is going to be pinned to the peer_ni */ tx->tx_deadline = ktime_get_seconds() + *ksocknal_tunables.ksnd_timeout; LASSERT(!tx->tx_msg.ksm_zc_cookies[0]); - tx->tx_msg.ksm_zc_cookies[0] = peer->ksnp_zc_next_cookie++; + tx->tx_msg.ksm_zc_cookies[0] = peer_ni->ksnp_zc_next_cookie++; - if (!peer->ksnp_zc_next_cookie) - peer->ksnp_zc_next_cookie = SOCKNAL_KEEPALIVE_PING + 1; + if (!peer_ni->ksnp_zc_next_cookie) + peer_ni->ksnp_zc_next_cookie = SOCKNAL_KEEPALIVE_PING + 1; - list_add_tail(&tx->tx_zc_list, &peer->ksnp_zc_req_list); + list_add_tail(&tx->tx_zc_list, &peer_ni->ksnp_zc_req_list); - spin_unlock(&peer->ksnp_lock); + spin_unlock(&peer_ni->ksnp_lock); } static void ksocknal_uncheck_zc_req(struct ksock_tx *tx) { - struct ksock_peer *peer = tx->tx_conn->ksnc_peer; + struct ksock_peer *peer_ni = tx->tx_conn->ksnc_peer; LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP); LASSERT(tx->tx_zc_capable); tx->tx_zc_checked = 0; - spin_lock(&peer->ksnp_lock); + spin_lock(&peer_ni->ksnp_lock); if (!tx->tx_msg.ksm_zc_cookies[0]) { /* Not waiting for an ACK */ - spin_unlock(&peer->ksnp_lock); + spin_unlock(&peer_ni->ksnp_lock); return; } tx->tx_msg.ksm_zc_cookies[0] = 0; list_del(&tx->tx_zc_list); - spin_unlock(&peer->ksnp_lock); + spin_unlock(&peer_ni->ksnp_lock); ksocknal_tx_decref(tx); } @@ -540,14 +540,14 @@ ksocknal_launch_connection_locked(struct ksock_route *route) } void -ksocknal_launch_all_connections_locked(struct ksock_peer *peer) +ksocknal_launch_all_connections_locked(struct ksock_peer *peer_ni) { struct ksock_route *route; /* called holding write lock on ksnd_global_lock */ for (;;) { /* launch any/all connections that need it */ - route = ksocknal_find_connectable_route_locked(peer); + route = ksocknal_find_connectable_route_locked(peer_ni); if (!route) return; @@ -556,7 +556,7 @@ ksocknal_launch_all_connections_locked(struct ksock_peer *peer) } struct ksock_conn * -ksocknal_find_conn_locked(struct ksock_peer *peer, struct ksock_tx *tx, +ksocknal_find_conn_locked(struct ksock_peer *peer_ni, struct ksock_tx *tx, int nonblk) { struct ksock_conn *c; @@ -566,7 +566,7 @@ ksocknal_find_conn_locked(struct ksock_peer *peer, struct ksock_tx *tx, int tnob = 0; int fnob = 0; - list_for_each_entry(c, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(c, &peer_ni->ksnp_conns, ksnc_list) { int nob, rc; nob = atomic_read(&c->ksnc_tx_nob) + @@ -722,12 +722,12 @@ ksocknal_queue_tx_locked(struct ksock_tx *tx, struct ksock_conn *conn) } struct ksock_route * -ksocknal_find_connectable_route_locked(struct ksock_peer *peer) +ksocknal_find_connectable_route_locked(struct ksock_peer *peer_ni) { time64_t now = ktime_get_seconds(); struct ksock_route *route; - list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) { + list_for_each_entry(route, &peer_ni->ksnp_routes, ksnr_list) { LASSERT(!route->ksnr_connecting || route->ksnr_scheduled); /* connections being established */ @@ -756,11 +756,11 @@ ksocknal_find_connectable_route_locked(struct ksock_peer *peer) } struct ksock_route * -ksocknal_find_connecting_route_locked(struct ksock_peer *peer) +ksocknal_find_connecting_route_locked(struct ksock_peer *peer_ni) { struct ksock_route *route; - list_for_each_entry(route, &peer->ksnp_routes, ksnr_list) { + list_for_each_entry(route, &peer_ni->ksnp_routes, ksnr_list) { LASSERT(!route->ksnr_connecting || route->ksnr_scheduled); @@ -775,7 +775,7 @@ int ksocknal_launch_packet(struct lnet_ni *ni, struct ksock_tx *tx, struct lnet_process_id id) { - struct ksock_peer *peer; + struct ksock_peer *peer_ni; struct ksock_conn *conn; rwlock_t *g_lock; int retry; @@ -787,10 +787,11 @@ ksocknal_launch_packet(struct lnet_ni *ni, struct ksock_tx *tx, for (retry = 0;; retry = 1) { read_lock(g_lock); - peer = ksocknal_find_peer_locked(ni, id); - if (peer) { - if (!ksocknal_find_connectable_route_locked(peer)) { - conn = ksocknal_find_conn_locked(peer, tx, tx->tx_nonblk); + peer_ni = ksocknal_find_peer_locked(ni, id); + if (peer_ni) { + if (!ksocknal_find_connectable_route_locked(peer_ni)) { + conn = ksocknal_find_conn_locked(peer_ni, tx, + tx->tx_nonblk); if (conn) { /* * I've got no routes that need to be @@ -809,8 +810,8 @@ ksocknal_launch_packet(struct lnet_ni *ni, struct ksock_tx *tx, write_lock_bh(g_lock); - peer = ksocknal_find_peer_locked(ni, id); - if (peer) + peer_ni = ksocknal_find_peer_locked(ni, id); + if (peer_ni) break; write_unlock_bh(g_lock); @@ -822,7 +823,7 @@ ksocknal_launch_packet(struct lnet_ni *ni, struct ksock_tx *tx, } if (retry) { - CERROR("Can't find peer %s\n", libcfs_id2str(id)); + CERROR("Can't find peer_ni %s\n", libcfs_id2str(id)); return -EHOSTUNREACH; } @@ -830,15 +831,15 @@ ksocknal_launch_packet(struct lnet_ni *ni, struct ksock_tx *tx, LNET_NIDADDR(id.nid), lnet_acceptor_port()); if (rc) { - CERROR("Can't add peer %s: %d\n", + CERROR("Can't add peer_ni %s: %d\n", libcfs_id2str(id), rc); return rc; } } - ksocknal_launch_all_connections_locked(peer); + ksocknal_launch_all_connections_locked(peer_ni); - conn = ksocknal_find_conn_locked(peer, tx, tx->tx_nonblk); + conn = ksocknal_find_conn_locked(peer_ni, tx, tx->tx_nonblk); if (conn) { /* Connection exists; queue message on it */ ksocknal_queue_tx_locked(tx, conn); @@ -846,14 +847,14 @@ ksocknal_launch_packet(struct lnet_ni *ni, struct ksock_tx *tx, return 0; } - if (peer->ksnp_accepting > 0 || - ksocknal_find_connecting_route_locked(peer)) { - /* the message is going to be pinned to the peer */ + if (peer_ni->ksnp_accepting > 0 || + ksocknal_find_connecting_route_locked(peer_ni)) { + /* the message is going to be pinned to the peer_ni */ tx->tx_deadline = ktime_get_seconds() + *ksocknal_tunables.ksnd_timeout; /* Queue the message until a connection is established */ - list_add_tail(&tx->tx_list, &peer->ksnp_tx_queue); + list_add_tail(&tx->tx_list, &peer_ni->ksnp_tx_queue); write_unlock_bh(g_lock); return 0; } @@ -1167,7 +1168,7 @@ ksocknal_process_receive(struct ksock_conn *conn) conn->ksnc_proto->pro_unpack(&conn->ksnc_msg); if (conn->ksnc_peer->ksnp_id.pid & LNET_PID_USERFLAG) { - /* Userspace peer */ + /* Userspace peer_ni */ lhdr = &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr; id = &conn->ksnc_peer->ksnp_id; @@ -1667,7 +1668,9 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, proto = ksocknal_parse_proto_version(hello); if (!proto) { if (!active) { - /* unknown protocol from peer, tell peer my protocol */ + /* unknown protocol from peer_ni, + * tell peer_ni my protocol + */ conn->ksnc_proto = &ksocknal_protocol_v3x; #if SOCKNAL_VERSION_DEBUG if (*ksocknal_tunables.ksnd_protocol == 2) @@ -1708,7 +1711,7 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, if (!active && conn->ksnc_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) { - /* Userspace NAL assigns peer process ID from socket */ + /* Userspace NAL assigns peer_ni process ID from socket */ recv_id.pid = conn->ksnc_port | LNET_PID_USERFLAG; recv_id.nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), conn->ksnc_ipaddr); @@ -1720,7 +1723,7 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, if (!active) { *peerid = recv_id; - /* peer determines type */ + /* peer_ni determines type */ conn->ksnc_type = ksocknal_invert_type(hello->kshm_ctype); if (conn->ksnc_type == SOCKLND_CONN_NONE) { CERROR("Unexpected type %d from %s ip %pI4h\n", @@ -1760,7 +1763,7 @@ static int ksocknal_connect(struct ksock_route *route) { LIST_HEAD(zombies); - struct ksock_peer *peer = route->ksnr_peer; + struct ksock_peer *peer_ni = route->ksnr_peer; int type; int wanted; struct socket *sock; @@ -1781,21 +1784,21 @@ ksocknal_connect(struct ksock_route *route) wanted = ksocknal_route_mask() & ~route->ksnr_connected; /* - * stop connecting if peer/route got closed under me, or + * stop connecting if peer_ni/route got closed under me, or * route got connected while queued */ - if (peer->ksnp_closing || route->ksnr_deleted || + if (peer_ni->ksnp_closing || route->ksnr_deleted || !wanted) { retry_later = 0; break; } - /* reschedule if peer is connecting to me */ - if (peer->ksnp_accepting > 0) { + /* reschedule if peer_ni is connecting to me */ + if (peer_ni->ksnp_accepting > 0) { CDEBUG(D_NET, - "peer %s(%d) already connecting to me, retry later.\n", - libcfs_nid2str(peer->ksnp_id.nid), - peer->ksnp_accepting); + "peer_ni %s(%d) already connecting to me, retry later.\n", + libcfs_nid2str(peer_ni->ksnp_id.nid), + peer_ni->ksnp_accepting); retry_later = 1; } @@ -1817,21 +1820,21 @@ ksocknal_connect(struct ksock_route *route) if (ktime_get_seconds() >= deadline) { rc = -ETIMEDOUT; - lnet_connect_console_error(rc, peer->ksnp_id.nid, + lnet_connect_console_error(rc, peer_ni->ksnp_id.nid, route->ksnr_ipaddr, route->ksnr_port); goto failed; } - rc = lnet_connect(&sock, peer->ksnp_id.nid, + rc = lnet_connect(&sock, peer_ni->ksnp_id.nid, route->ksnr_myipaddr, route->ksnr_ipaddr, route->ksnr_port); if (rc) goto failed; - rc = ksocknal_create_conn(peer->ksnp_ni, route, sock, type); + rc = ksocknal_create_conn(peer_ni->ksnp_ni, route, sock, type); if (rc < 0) { - lnet_connect_console_error(rc, peer->ksnp_id.nid, + lnet_connect_console_error(rc, peer_ni->ksnp_id.nid, route->ksnr_ipaddr, route->ksnr_port); goto failed; @@ -1843,8 +1846,8 @@ ksocknal_connect(struct ksock_route *route) */ retry_later = (rc); if (retry_later) - CDEBUG(D_NET, "peer %s: conn race, retry later.\n", - libcfs_nid2str(peer->ksnp_id.nid)); + CDEBUG(D_NET, "peer_ni %s: conn race, retry later.\n", + libcfs_nid2str(peer_ni->ksnp_id.nid)); write_lock_bh(&ksocknal_data.ksnd_global_lock); } @@ -1855,10 +1858,10 @@ ksocknal_connect(struct ksock_route *route) if (retry_later) { /* * re-queue for attention; this frees me up to handle - * the peer's incoming connection request + * the peer_ni's incoming connection request */ if (rc == EALREADY || - (!rc && peer->ksnp_accepting > 0)) { + (!rc && peer_ni->ksnp_accepting > 0)) { /* * We want to introduce a delay before next * attempt to connect if we lost conn race, @@ -1895,17 +1898,17 @@ ksocknal_connect(struct ksock_route *route) LASSERT(route->ksnr_retry_interval); route->ksnr_timeout = ktime_get_seconds() + route->ksnr_retry_interval; - if (!list_empty(&peer->ksnp_tx_queue) && - !peer->ksnp_accepting && - !ksocknal_find_connecting_route_locked(peer)) { + if (!list_empty(&peer_ni->ksnp_tx_queue) && + !peer_ni->ksnp_accepting && + !ksocknal_find_connecting_route_locked(peer_ni)) { struct ksock_conn *conn; /* * ksnp_tx_queue is queued on a conn on successful * connection for V1.x and V2.x */ - if (!list_empty(&peer->ksnp_conns)) { - conn = list_entry(peer->ksnp_conns.next, + if (!list_empty(&peer_ni->ksnp_conns)) { + conn = list_entry(peer_ni->ksnp_conns.next, struct ksock_conn, ksnc_list); LASSERT(conn->ksnc_proto == &ksocknal_protocol_v3x); } @@ -1914,13 +1917,13 @@ ksocknal_connect(struct ksock_route *route) * take all the blocked packets while I've got the lock and * complete below... */ - list_splice_init(&peer->ksnp_tx_queue, &zombies); + list_splice_init(&peer_ni->ksnp_tx_queue, &zombies); } write_unlock_bh(&ksocknal_data.ksnd_global_lock); - ksocknal_peer_failed(peer); - ksocknal_txlist_done(peer->ksnp_ni, &zombies, 1); + ksocknal_peer_failed(peer_ni); + ksocknal_txlist_done(peer_ni->ksnp_ni, &zombies, 1); return 0; } @@ -2167,12 +2170,12 @@ ksocknal_connd(void *arg) } static struct ksock_conn * -ksocknal_find_timed_out_conn(struct ksock_peer *peer) +ksocknal_find_timed_out_conn(struct ksock_peer *peer_ni) { /* We're called with a shared lock on ksnd_global_lock */ struct ksock_conn *conn; - list_for_each_entry(conn, &peer->ksnp_conns, ksnc_list) { + list_for_each_entry(conn, &peer_ni->ksnp_conns, ksnc_list) { int error; /* Don't need the {get,put}connsock dance to deref ksnc_sock */ @@ -2189,20 +2192,20 @@ ksocknal_find_timed_out_conn(struct ksock_peer *peer) switch (error) { case ECONNRESET: CNETERR("A connection with %s (%pI4h:%d) was reset; it may have rebooted.\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; case ETIMEDOUT: CNETERR("A connection with %s (%pI4h:%d) timed out; the network or node may be down.\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; default: CNETERR("An unexpected network error %d occurred with %s (%pI4h:%d\n", error, - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); break; @@ -2216,7 +2219,7 @@ ksocknal_find_timed_out_conn(struct ksock_peer *peer) /* Timed out incomplete incoming message */ ksocknal_conn_addref(conn); CNETERR("Timeout receiving from %s (%pI4h:%d), state %d wanted %zd left %d\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port, conn->ksnc_rx_state, @@ -2234,7 +2237,7 @@ ksocknal_find_timed_out_conn(struct ksock_peer *peer) */ ksocknal_conn_addref(conn); CNETERR("Timeout sending data to %s (%pI4h:%d) the network or that node may be down.\n", - libcfs_id2str(peer->ksnp_id), + libcfs_id2str(peer_ni->ksnp_id), &conn->ksnc_ipaddr, conn->ksnc_port); return conn; @@ -2245,15 +2248,16 @@ ksocknal_find_timed_out_conn(struct ksock_peer *peer) } static inline void -ksocknal_flush_stale_txs(struct ksock_peer *peer) +ksocknal_flush_stale_txs(struct ksock_peer *peer_ni) { struct ksock_tx *tx; LIST_HEAD(stale_txs); write_lock_bh(&ksocknal_data.ksnd_global_lock); - while (!list_empty(&peer->ksnp_tx_queue)) { - tx = list_entry(peer->ksnp_tx_queue.next, struct ksock_tx, tx_list); + while (!list_empty(&peer_ni->ksnp_tx_queue)) { + tx = list_entry(peer_ni->ksnp_tx_queue.next, struct ksock_tx, + tx_list); if (ktime_get_seconds() < tx->tx_deadline) break; @@ -2264,11 +2268,11 @@ ksocknal_flush_stale_txs(struct ksock_peer *peer) write_unlock_bh(&ksocknal_data.ksnd_global_lock); - ksocknal_txlist_done(peer->ksnp_ni, &stale_txs, 1); + ksocknal_txlist_done(peer_ni->ksnp_ni, &stale_txs, 1); } static int -ksocknal_send_keepalive_locked(struct ksock_peer *peer) +ksocknal_send_keepalive_locked(struct ksock_peer *peer_ni) __must_hold(&ksocknal_data.ksnd_global_lock) { struct ksock_sched *sched; @@ -2276,27 +2280,27 @@ ksocknal_send_keepalive_locked(struct ksock_peer *peer) struct ksock_tx *tx; /* last_alive will be updated by create_conn */ - if (list_empty(&peer->ksnp_conns)) + if (list_empty(&peer_ni->ksnp_conns)) return 0; - if (peer->ksnp_proto != &ksocknal_protocol_v3x) + if (peer_ni->ksnp_proto != &ksocknal_protocol_v3x) return 0; if (*ksocknal_tunables.ksnd_keepalive <= 0 || - ktime_get_seconds() < peer->ksnp_last_alive + + ktime_get_seconds() < peer_ni->ksnp_last_alive + *ksocknal_tunables.ksnd_keepalive) return 0; - if (ktime_get_seconds() < peer->ksnp_send_keepalive) + if (ktime_get_seconds() < peer_ni->ksnp_send_keepalive) return 0; /* * retry 10 secs later, so we wouldn't put pressure - * on this peer if we failed to send keepalive this time + * on this peer_ni if we failed to send keepalive this time */ - peer->ksnp_send_keepalive = ktime_get_seconds() + 10; + peer_ni->ksnp_send_keepalive = ktime_get_seconds() + 10; - conn = ksocknal_find_conn_locked(peer, NULL, 1); + conn = ksocknal_find_conn_locked(peer_ni, NULL, 1); if (conn) { sched = conn->ksnc_scheduler; @@ -2319,7 +2323,7 @@ ksocknal_send_keepalive_locked(struct ksock_peer *peer) return -ENOMEM; } - if (!ksocknal_launch_packet(peer->ksnp_ni, tx, peer->ksnp_id)) { + if (!ksocknal_launch_packet(peer_ni->ksnp_ni, tx, peer_ni->ksnp_id)) { read_lock(&ksocknal_data.ksnd_global_lock); return 1; } @@ -2334,7 +2338,7 @@ static void ksocknal_check_peer_timeouts(int idx) { struct list_head *peers = &ksocknal_data.ksnd_peers[idx]; - struct ksock_peer *peer; + struct ksock_peer *peer_ni; struct ksock_conn *conn; struct ksock_tx *tx; @@ -2346,18 +2350,18 @@ ksocknal_check_peer_timeouts(int idx) */ read_lock(&ksocknal_data.ksnd_global_lock); - list_for_each_entry(peer, peers, ksnp_list) { + list_for_each_entry(peer_ni, peers, ksnp_list) { struct ksock_tx *tx_stale; time64_t deadline = 0; int resid = 0; int n = 0; - if (ksocknal_send_keepalive_locked(peer)) { + if (ksocknal_send_keepalive_locked(peer_ni)) { read_unlock(&ksocknal_data.ksnd_global_lock); goto again; } - conn = ksocknal_find_timed_out_conn(peer); + conn = ksocknal_find_timed_out_conn(peer_ni); if (conn) { read_unlock(&ksocknal_data.ksnd_global_lock); @@ -2366,7 +2370,7 @@ ksocknal_check_peer_timeouts(int idx) /* * NB we won't find this one again, but we can't - * just proceed with the next peer, since we dropped + * just proceed with the next peer_ni, since we dropped * ksnd_global_lock and it might be dead already! */ ksocknal_conn_decref(conn); @@ -2377,27 +2381,28 @@ ksocknal_check_peer_timeouts(int idx) * we can't process stale txs right here because we're * holding only shared lock */ - if (!list_empty(&peer->ksnp_tx_queue)) { - tx = list_entry(peer->ksnp_tx_queue.next, + if (!list_empty(&peer_ni->ksnp_tx_queue)) { + tx = list_entry(peer_ni->ksnp_tx_queue.next, struct ksock_tx, tx_list); if (ktime_get_seconds() >= tx->tx_deadline) { - ksocknal_peer_addref(peer); + ksocknal_peer_addref(peer_ni); read_unlock(&ksocknal_data.ksnd_global_lock); - ksocknal_flush_stale_txs(peer); + ksocknal_flush_stale_txs(peer_ni); - ksocknal_peer_decref(peer); + ksocknal_peer_decref(peer_ni); goto again; } } - if (list_empty(&peer->ksnp_zc_req_list)) + if (list_empty(&peer_ni->ksnp_zc_req_list)) continue; tx_stale = NULL; - spin_lock(&peer->ksnp_lock); - list_for_each_entry(tx, &peer->ksnp_zc_req_list, tx_zc_list) { + spin_lock(&peer_ni->ksnp_lock); + list_for_each_entry(tx, &peer_ni->ksnp_zc_req_list, + tx_zc_list) { if (ktime_get_seconds() < tx->tx_deadline) break; /* ignore the TX if connection is being closed */ @@ -2409,7 +2414,7 @@ ksocknal_check_peer_timeouts(int idx) } if (!tx_stale) { - spin_unlock(&peer->ksnp_lock); + spin_unlock(&peer_ni->ksnp_lock); continue; } @@ -2418,11 +2423,11 @@ ksocknal_check_peer_timeouts(int idx) conn = tx_stale->tx_conn; ksocknal_conn_addref(conn); - spin_unlock(&peer->ksnp_lock); + spin_unlock(&peer_ni->ksnp_lock); read_unlock(&ksocknal_data.ksnd_global_lock); - CERROR("Total %d stale ZC_REQs for peer %s detected; the oldest(%p) timed out %lld secs ago, resid: %d, wmem: %d\n", - n, libcfs_nid2str(peer->ksnp_id.nid), tx_stale, + CERROR("Total %d stale ZC_REQs for peer_ni %s detected; the oldest(%p) timed out %lld secs ago, resid: %d, wmem: %d\n", + n, libcfs_nid2str(peer_ni->ksnp_id.nid), tx_stale, ktime_get_seconds() - deadline, resid, conn->ksnc_sock->sk->sk_wmem_queued); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c index 93a02cd6b6b5..33847b9615ed 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c @@ -44,7 +44,7 @@ ksocknal_lib_get_conn_addrs(struct ksock_conn *conn) LASSERT(!conn->ksnc_closing); if (rc) { - CERROR("Error %d getting sock peer IP\n", rc); + CERROR("Error %d getting sock peer_ni IP\n", rc); return rc; } @@ -157,7 +157,7 @@ ksocknal_lib_eager_ack(struct ksock_conn *conn) * Remind the socket to ACK eagerly. If I don't, the socket might * think I'm about to send something it could piggy-back the ACK * on, introducing delay in completing zero-copy sends in my - * peer. + * peer_ni. */ kernel_setsockopt(sock, SOL_TCP, TCP_QUICKACK, (char *)&opt, sizeof(opt)); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c index abfaf5701758..8c10eda382b7 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c @@ -367,14 +367,14 @@ ksocknal_match_tx_v3(struct ksock_conn *conn, struct ksock_tx *tx, int nonblk) static int ksocknal_handle_zcreq(struct ksock_conn *c, __u64 cookie, int remote) { - struct ksock_peer *peer = c->ksnc_peer; + struct ksock_peer *peer_ni = c->ksnc_peer; struct ksock_conn *conn; struct ksock_tx *tx; int rc; read_lock(&ksocknal_data.ksnd_global_lock); - conn = ksocknal_find_conn_locked(peer, NULL, !!remote); + conn = ksocknal_find_conn_locked(peer_ni, NULL, !!remote); if (conn) { struct ksock_sched *sched = conn->ksnc_scheduler; @@ -399,7 +399,7 @@ ksocknal_handle_zcreq(struct ksock_conn *c, __u64 cookie, int remote) if (!tx) return -ENOMEM; - rc = ksocknal_launch_packet(peer->ksnp_ni, tx, peer->ksnp_id); + rc = ksocknal_launch_packet(peer_ni->ksnp_ni, tx, peer_ni->ksnp_id); if (!rc) return 0; @@ -411,7 +411,7 @@ ksocknal_handle_zcreq(struct ksock_conn *c, __u64 cookie, int remote) static int ksocknal_handle_zcack(struct ksock_conn *conn, __u64 cookie1, __u64 cookie2) { - struct ksock_peer *peer = conn->ksnc_peer; + struct ksock_peer *peer_ni = conn->ksnc_peer; struct ksock_tx *tx; struct ksock_tx *tmp; LIST_HEAD(zlist); @@ -428,9 +428,9 @@ ksocknal_handle_zcack(struct ksock_conn *conn, __u64 cookie1, __u64 cookie2) return count == 1 ? 0 : -EPROTO; } - spin_lock(&peer->ksnp_lock); + spin_lock(&peer_ni->ksnp_lock); - list_for_each_entry_safe(tx, tmp, &peer->ksnp_zc_req_list, + list_for_each_entry_safe(tx, tmp, &peer_ni->ksnp_zc_req_list, tx_zc_list) { __u64 c = tx->tx_msg.ksm_zc_cookies[0]; @@ -445,7 +445,7 @@ ksocknal_handle_zcack(struct ksock_conn *conn, __u64 cookie1, __u64 cookie2) } } - spin_unlock(&peer->ksnp_lock); + spin_unlock(&peer_ni->ksnp_lock); while (!list_empty(&zlist)) { tx = list_entry(zlist.next, struct ksock_tx, tx_zc_list); From neilb at suse.com Tue Sep 25 23:36:30 2018 From: neilb at suse.com (NeilBrown) Date: Wed, 26 Sep 2018 09:36:30 +1000 Subject: [lustre-devel] [PATCH] lustre: lnet: copy the correct amountof cpts to lnet_cpts In-Reply-To: <1537846650-8490-1-git-send-email-jsimmons@infradead.org> References: <1537846650-8490-1-git-send-email-jsimmons@infradead.org> Message-ID: <87h8idi1z5.fsf@notabene.neil.brown.name> On Mon, Sep 24 2018, James Simmons wrote: > The incorrect size was used in the memory copy of the requested > cpts to net->lnet_cpts. This lead to the following in testing > RIP: 0010:lnet_match2mt.isra.8+0x2b/0x40 [lnet] > > lnet_mt_of_attach+0x72/0x1b0 [lnet] > LNetMEAttach+0x60/0x1f0 [lnet] > ptl_send_rpc+0x26f/0xbb0 [ptlrpc] > libcfs_debug_msg+0x57/0x80 [libcfs] > ptlrpc_send_new_req+0x4c9/0x860 [ptlrpc] > ptlrpc_check_set.part.21+0x855/0x18b0 [ptlrpc] > ? try_to_del_timer_sync+0x4d/0x80 > ? del_timer_sync+0x35/0x40 > ptlrpcd_check+0x3ae/0x3f0 [ptlrpc] > ptlrpcd+0x2be/0x320 [ptlrpc] > ? wait_woken+0x80/0x80 > > Changing the size from ncpts to ncpts * sizeof(*net->net_cpts) > > Signed-off-by: James Simmons > WC-bug-id: https://jira.whamcloud.com/browse/LU-11424 > Reviewed-on: https://review.whamcloud.com/33229 Thanks. Applied. NeilBrown > --- > drivers/staging/lustre/lnet/lnet/config.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c > index c11821a..4c22416 100644 > --- a/drivers/staging/lustre/lnet/lnet/config.c > +++ b/drivers/staging/lustre/lnet/lnet/config.c > @@ -174,7 +174,7 @@ struct lnet_text_buf { /* tmp struct for parsing routes */ > GFP_KERNEL); > if (!net->net_cpts) > return -ENOMEM; > - memcpy(net->net_cpts, cpts, ncpts); > + memcpy(net->net_cpts, cpts, ncpts * sizeof(*net->net_cpts)); > net->net_ncpts = ncpts; > return 0; > } > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From jsimmons at infradead.org Wed Sep 26 02:47:52 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:52 -0400 Subject: [lustre-devel] [PATCH 00/25] lustre: lnet: remaining fixes for multi-rail Message-ID: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> This is the remaining patches to land to 2.10 to resolve issues found in MR testing. These patches are based on lustre-testing commit 18c9cf20ec376d5b3d432aa3923645a12636d14b. A few fixes for o2iblnd is also pushed. Amir Shehata (10): lustre: lnet: Normalize ioctl interface lustre: lnet: selftest MR fix lustre: lnet: prevent assert on ln_state lustre: lnet: increment per NI stats lustre: lnet: correct locking in legacy add net lustre: lnet: fix lnet_cpt_of_md() lustre: lnet: safe access to msg lustre: lnet: handle empty CPTs lustre: lnet: set LND tunables properly lustre: lnd: pending transmits dropped silently Dmitry Eremin (1): lustre: lnet: Fix lost lock Doug Oucharek (4): lustre: lnet: Allow min stats to be reset in peers and nis lustre: lnd: Turn on 2 sges by default lustre: lnd: Don't Assert On Reconnect with MultiQP lustre: lnd: Don't Page Align remote_addr with FastReg John L. Hammond (1): lustre: ko2iblnd: allow for discontiguous fragments Liang Zhen (1): lustre: o2iblnd: multiple sges for work request Olaf Weber (5): lustre: lnet: remove debug ioctl lustre: lnet: fix race in lnet shutdown path lustre: lnet: loopback NID in lnet_select_pathway() lustre: lnet: rename LNET_MAX_INTERFACES lustre: socklnd: propagate errors on send failure Sergey Cheremencev (3): lustre: lnet: remove ni from lnet_finalize lustre: o2iblnd: reconnect peer for REJ_INVALID_SERVICE_ID lustre: o2iblnd: kill timedout txs from ibp_tx_queue .../staging/lustre/include/linux/lnet/lib-lnet.h | 12 +- .../staging/lustre/include/linux/lnet/lib-types.h | 11 +- .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 3 +- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 67 ++++--- .../lustre/include/uapi/linux/lnet/lnet-types.h | 2 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 79 ++++++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 11 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 212 +++++++++++---------- .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 11 +- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 61 ++++-- .../staging/lustre/lnet/klnds/socklnd/socklnd.h | 8 +- .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 21 +- .../lustre/lnet/klnds/socklnd/socklnd_proto.c | 4 +- drivers/staging/lustre/lnet/lnet/api-ni.c | 69 +++---- drivers/staging/lustre/lnet/lnet/config.c | 10 +- drivers/staging/lustre/lnet/lnet/lib-md.c | 96 ++++++++-- drivers/staging/lustre/lnet/lnet/lib-move.c | 100 ++++++---- drivers/staging/lustre/lnet/lnet/lib-msg.c | 10 +- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 4 +- drivers/staging/lustre/lnet/lnet/lo.c | 4 +- drivers/staging/lustre/lnet/lnet/net_fault.c | 2 +- drivers/staging/lustre/lnet/lnet/peer.c | 60 +++--- drivers/staging/lustre/lnet/lnet/router.c | 6 +- drivers/staging/lustre/lnet/lnet/router_proc.c | 69 ++++++- drivers/staging/lustre/lnet/selftest/rpc.c | 2 +- 25 files changed, 593 insertions(+), 341 deletions(-) -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:47:57 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:57 -0400 Subject: [lustre-devel] [PATCH 05/25] lustre: lnet: fix race in lnet shutdown path In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-6-git-send-email-jsimmons@infradead.org> From: Olaf Weber The locking changes for the lnet_net_lock made for Multi-Rail introduce a race in the LNet shutdown path. The code keeps two states in the_lnet.ln_shutdown: 0 means LNet is either up and running or shut down, while 1 means lnet is shutting down. In lnet_select_pathway() if we need to restart and drop and relock the lnet_net_lock we can find that LNet went from running to stopped, and not be able to tell the difference. Replace ln_shutdown with a three-state ln_state patterned on ln_rc_state: states are LNET_STATE_SHUTDOWN, LNET_STATE_RUNNING, and LNET_STATE_STOPPING. Most checks against ln_shutdown now test ln_state against LNET_STATE_RUNNING. LNet moves to RUNNING state in lnet_startup_lndnets(). Signed-off-by: Olaf Weber WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26690 Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/include/linux/lnet/lib-types.h | 9 +++++++-- drivers/staging/lustre/lnet/lnet/api-ni.c | 15 ++++++++++++--- drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- drivers/staging/lustre/lnet/lnet/lib-ptl.c | 4 ++-- drivers/staging/lustre/lnet/lnet/peer.c | 10 +++++----- drivers/staging/lustre/lnet/lnet/router.c | 6 +++--- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 18e2665..6abac19 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -726,6 +726,11 @@ struct lnet_msg_container { #define LNET_RC_STATE_RUNNING 1 /* started up OK */ #define LNET_RC_STATE_STOPPING 2 /* telling thread to stop */ +/* LNet states */ +#define LNET_STATE_SHUTDOWN 0 /* not started */ +#define LNET_STATE_RUNNING 1 /* started up OK */ +#define LNET_STATE_STOPPING 2 /* telling thread to stop */ + struct lnet { /* CPU partition table of LNet */ struct cfs_cpt_table *ln_cpt_table; @@ -805,8 +810,8 @@ struct lnet { int ln_niinit_self; /* LNetNIInit/LNetNIFini counter */ int ln_refcount; - /* shutdown in progress */ - int ln_shutdown; + /* SHUTDOWN/RUNNING/STOPPING */ + int ln_state; int ln_routing; /* am I a router? */ lnet_pid_t ln_pid; /* requested pid */ diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 2d430d0..7c907a3 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1277,11 +1277,11 @@ struct lnet_ni * /* NB called holding the global mutex */ /* All quiet on the API front */ - LASSERT(!the_lnet.ln_shutdown); + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); LASSERT(!the_lnet.ln_refcount); lnet_net_lock(LNET_LOCK_EX); - the_lnet.ln_shutdown = 1; /* flag shutdown */ + the_lnet.ln_state = LNET_STATE_STOPPING; while (!list_empty(&the_lnet.ln_nets)) { /* @@ -1309,7 +1309,7 @@ struct lnet_ni * } lnet_net_lock(LNET_LOCK_EX); - the_lnet.ln_shutdown = 0; + the_lnet.ln_state = LNET_STATE_SHUTDOWN; lnet_net_unlock(LNET_LOCK_EX); } @@ -1583,6 +1583,15 @@ struct lnet_ni * int rc; int ni_count = 0; + /* + * Change to running state before bringing up the LNDs. This + * allows lnet_shutdown_lndnets() to assert that we've passed + * through here. + */ + lnet_net_lock(LNET_LOCK_EX); + the_lnet.ln_state = LNET_STATE_RUNNING; + lnet_net_unlock(LNET_LOCK_EX); + while (!list_empty(netlist)) { net = list_entry(netlist->next, struct lnet_net, net_list); list_del_init(&net->net_list); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index a213387..ea7e2c3 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1242,7 +1242,7 @@ seq = lnet_get_dlc_seq_locked(); - if (the_lnet.ln_shutdown) { + if (the_lnet.ln_state != LNET_STATE_RUNNING) { lnet_net_unlock(cpt); return -ESHUTDOWN; } diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index d403353..6fa5bbf 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -589,7 +589,7 @@ struct list_head * mtable = lnet_mt_of_match(info, msg); lnet_res_lock(mtable->mt_cpt); - if (the_lnet.ln_shutdown) { + if (the_lnet.ln_state != LNET_STATE_RUNNING) { rc = LNET_MATCHMD_DROP; goto out1; } @@ -951,7 +951,7 @@ struct list_head * list_move(&msg->msg_list, &zombies); } } else { - if (the_lnet.ln_shutdown) + if (the_lnet.ln_state != LNET_STATE_RUNNING) CWARN("Active lazy portal %d on exit\n", portal); else CDEBUG(D_NET, "clearing portal %d lazy\n", portal); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index ae3ffca..2fbf93a 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -428,7 +428,7 @@ void lnet_peer_uninit(void) struct lnet_peer_table *ptable; int i; - LASSERT(the_lnet.ln_shutdown || net); + LASSERT(the_lnet.ln_state != LNET_STATE_SHUTDOWN || net); /* * If just deleting the peers for a NI, get rid of any routes these * peers are gateways for. @@ -458,7 +458,7 @@ void lnet_peer_uninit(void) struct list_head *peers; struct lnet_peer_ni *lp; - LASSERT(!the_lnet.ln_shutdown); + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; list_for_each_entry(lp, peers, lpni_hashlist) { @@ -1000,7 +1000,7 @@ struct lnet_peer_ni * struct lnet_peer_ni *lpni = NULL; int rc; - if (the_lnet.ln_shutdown) /* it's shutting down */ + if (the_lnet.ln_state != LNET_STATE_RUNNING) return ERR_PTR(-ESHUTDOWN); /* @@ -1034,7 +1034,7 @@ struct lnet_peer_ni * struct lnet_peer_ni *lpni = NULL; int rc; - if (the_lnet.ln_shutdown) /* it's shutting down */ + if (the_lnet.ln_state != LNET_STATE_RUNNING) return ERR_PTR(-ESHUTDOWN); /* @@ -1063,7 +1063,7 @@ struct lnet_peer_ni * * Shutdown is only set under the ln_api_lock, so a single * check here is sufficent. */ - if (the_lnet.ln_shutdown) { + if (the_lnet.ln_state != LNET_STATE_RUNNING) { lpni = ERR_PTR(-ESHUTDOWN); goto out_mutex_unlock; } diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index a0483f9..d3aef8b 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -252,7 +252,7 @@ struct lnet_remotenet * struct lnet_remotenet *rnet; struct list_head *rn_list; - LASSERT(!the_lnet.ln_shutdown); + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); rn_list = lnet_net2rnethash(net); list_for_each_entry(rnet, rn_list, lrn_list) { @@ -374,7 +374,7 @@ static void lnet_shuffle_seed(void) return rc; } route->lr_gateway = lpni; - LASSERT(!the_lnet.ln_shutdown); + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); rnet2 = lnet_find_rnet_locked(net); if (!rnet2) { @@ -1775,7 +1775,7 @@ int lnet_get_rtr_pool_cfg(int idx, struct lnet_ioctl_pool_cfg *pool_cfg) lnet_net_lock(cpt); - if (the_lnet.ln_shutdown) { + if (the_lnet.ln_state != LNET_STATE_RUNNING) { lnet_net_unlock(cpt); return -ESHUTDOWN; } -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:47:59 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:59 -0400 Subject: [lustre-devel] [PATCH 07/25] lustre: lnet: rename LNET_MAX_INTERFACES In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-8-git-send-email-jsimmons@infradead.org> From: Olaf Weber LNET_MAX_INTERFACES is the number of interfaces supported by interface bonding in the ksocknal LND. It shows up in LNet because a number of data structures are shared between LNDs. Rename it to LNET_NUM_INTERFACES to reduce the confusion of what it does. Also it allows us to build the userland tools. Signed-off-by: Olaf Weber WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26693 Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/include/linux/lnet/lib-types.h | 2 +- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 4 ++-- .../lustre/include/uapi/linux/lnet/lnet-types.h | 2 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 22 +++++++++++----------- .../staging/lustre/lnet/klnds/socklnd/socklnd.h | 4 ++-- .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 2 +- .../lustre/lnet/klnds/socklnd/socklnd_proto.c | 4 ++-- drivers/staging/lustre/lnet/lnet/config.c | 10 +++++----- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 6abac19..90f7577 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -371,7 +371,7 @@ struct lnet_ni { * equivalent interfaces to use * This is an array because socklnd bonding can still be configured */ - char *ni_interfaces[LNET_MAX_INTERFACES]; + char *ni_interfaces[LNET_NUM_INTERFACES]; /* original net namespace */ struct net *ni_net_ns; }; diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index e603455..07516fd 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -81,7 +81,7 @@ struct lnet_ioctl_config_lnd_tunables { }; struct lnet_ioctl_net_config { - char ni_interfaces[LNET_MAX_INTERFACES][LNET_MAX_STR_LEN]; + char ni_interfaces[LNET_NUM_INTERFACES][LNET_MAX_STR_LEN]; __u32 ni_status; __u32 ni_cpts[LNET_MAX_SHOW_NUM_CPT]; char cfg_bulk[0]; @@ -184,7 +184,7 @@ struct lnet_ioctl_element_msg_stats { struct lnet_ioctl_config_ni { struct libcfs_ioctl_hdr lic_cfg_hdr; lnet_nid_t lic_nid; - char lic_ni_intf[LNET_MAX_INTERFACES][LNET_MAX_STR_LEN]; + char lic_ni_intf[LNET_NUM_INTERFACES][LNET_MAX_STR_LEN]; char lic_legacy_ip2nets[LNET_MAX_STR_LEN]; __u32 lic_cpts[LNET_MAX_SHOW_NUM_CPT]; __u32 lic_ncpts; diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h index 837e5fe..a373b9c 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h @@ -264,7 +264,7 @@ struct lnet_counters { #define LNET_NI_STATUS_DOWN 0xdeadface #define LNET_NI_STATUS_INVALID 0x00000000 -#define LNET_MAX_INTERFACES 16 +#define LNET_NUM_INTERFACES 16 /** * Objects maintained by the LNet are accessed through handles. Handle types diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index b3a4344..aea83a5 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2870,7 +2870,7 @@ static int kiblnd_startup(struct lnet_ni *ni) if (ni->ni_interfaces[0]) { /* Use the IPoIB interface specified in 'networks=' */ - BUILD_BUG_ON(LNET_MAX_INTERFACES <= 1); + BUILD_BUG_ON(LNET_NUM_INTERFACES <= 1); if (ni->ni_interfaces[1]) { CERROR("Multiple interfaces not supported\n"); goto failed; diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 9b9cc87..ad94837 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -53,7 +53,7 @@ struct ksock_interface *iface; for (i = 0; i < net->ksnn_ninterfaces; i++) { - LASSERT(i < LNET_MAX_INTERFACES); + LASSERT(i < LNET_NUM_INTERFACES); iface = &net->ksnn_interfaces[i]; if (iface->ksni_ipaddr == ip) @@ -221,7 +221,7 @@ struct ksock_peer * struct ksock_interface *iface; for (i = 0; i < peer_ni->ksnp_n_passive_ips; i++) { - LASSERT(i < LNET_MAX_INTERFACES); + LASSERT(i < LNET_NUM_INTERFACES); ip = peer_ni->ksnp_passive_ips[i]; iface = ksocknal_ip2iface(peer_ni->ksnp_ni, ip); @@ -678,7 +678,7 @@ struct ksock_peer * read_lock(&ksocknal_data.ksnd_global_lock); nip = net->ksnn_ninterfaces; - LASSERT(nip <= LNET_MAX_INTERFACES); + LASSERT(nip <= LNET_NUM_INTERFACES); /* * Only offer interfaces for additional connections if I have @@ -759,8 +759,8 @@ struct ksock_peer * */ write_lock_bh(global_lock); - LASSERT(n_peerips <= LNET_MAX_INTERFACES); - LASSERT(net->ksnn_ninterfaces <= LNET_MAX_INTERFACES); + LASSERT(n_peerips <= LNET_NUM_INTERFACES); + LASSERT(net->ksnn_ninterfaces <= LNET_NUM_INTERFACES); /* * Only match interfaces for additional connections @@ -879,7 +879,7 @@ struct ksock_peer * return; } - LASSERT(npeer_ipaddrs <= LNET_MAX_INTERFACES); + LASSERT(npeer_ipaddrs <= LNET_NUM_INTERFACES); for (i = 0; i < npeer_ipaddrs; i++) { if (newroute) { @@ -908,7 +908,7 @@ struct ksock_peer * best_nroutes = 0; best_netmatch = 0; - LASSERT(net->ksnn_ninterfaces <= LNET_MAX_INTERFACES); + LASSERT(net->ksnn_ninterfaces <= LNET_NUM_INTERFACES); /* Select interface to connect from */ for (j = 0; j < net->ksnn_ninterfaces; j++) { @@ -1048,7 +1048,7 @@ struct ksock_peer * atomic_set(&conn->ksnc_tx_nob, 0); hello = kvzalloc(offsetof(struct ksock_hello_msg, - kshm_ips[LNET_MAX_INTERFACES]), + kshm_ips[LNET_NUM_INTERFACES]), GFP_KERNEL); if (!hello) { rc = -ENOMEM; @@ -1956,7 +1956,7 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) if (iface) { /* silently ignore dups */ rc = 0; - } else if (net->ksnn_ninterfaces == LNET_MAX_INTERFACES) { + } else if (net->ksnn_ninterfaces == LNET_NUM_INTERFACES) { rc = -ENOSPC; } else { iface = &net->ksnn_interfaces[net->ksnn_ninterfaces++]; @@ -2594,7 +2594,7 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) continue; } - if (j == LNET_MAX_INTERFACES) { + if (j == LNET_NUM_INTERFACES) { CWARN("Ignoring interface %s (too many interfaces)\n", name); continue; @@ -2782,7 +2782,7 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) net->ksnn_ninterfaces = rc; } else { - for (i = 0; i < LNET_MAX_INTERFACES; i++) { + for (i = 0; i < LNET_NUM_INTERFACES; i++) { if (!ni->ni_interfaces[i]) break; rc = ksocknal_enumerate_interfaces(net, ni->ni_interfaces[i]); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index cc813e4..95ca2aa 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h @@ -173,7 +173,7 @@ struct ksock_net { int ksnn_npeers; /* # peers */ int ksnn_shutdown; /* shutting down? */ int ksnn_ninterfaces; /* IP interfaces */ - struct ksock_interface ksnn_interfaces[LNET_MAX_INTERFACES]; + struct ksock_interface ksnn_interfaces[LNET_NUM_INTERFACES]; }; /** connd timeout */ @@ -441,7 +441,7 @@ struct ksock_peer { int ksnp_n_passive_ips; /* # of... */ /* preferred local interfaces */ - __u32 ksnp_passive_ips[LNET_MAX_INTERFACES]; + u32 ksnp_passive_ips[LNET_NUM_INTERFACES]; }; struct ksock_connreq { diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 2e99a17..73321a7 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -1580,7 +1580,7 @@ void ksocknal_write_callback(struct ksock_conn *conn) /* CAVEAT EMPTOR: this byte flips 'ipaddrs' */ struct ksock_net *net = (struct ksock_net *)ni->ni_data; - LASSERT(hello->kshm_nips <= LNET_MAX_INTERFACES); + LASSERT(hello->kshm_nips <= LNET_NUM_INTERFACES); /* rely on caller to hold a ref on socket so it wouldn't disappear */ LASSERT(conn->ksnc_proto); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c index 8c10eda..10a2757 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c @@ -614,7 +614,7 @@ hello->kshm_nips = le32_to_cpu(hdr->payload_length) / sizeof(__u32); - if (hello->kshm_nips > LNET_MAX_INTERFACES) { + if (hello->kshm_nips > LNET_NUM_INTERFACES) { CERROR("Bad nips %d from ip %pI4h\n", hello->kshm_nips, &conn->ksnc_ipaddr); rc = -EPROTO; @@ -684,7 +684,7 @@ __swab32s(&hello->kshm_nips); } - if (hello->kshm_nips > LNET_MAX_INTERFACES) { + if (hello->kshm_nips > LNET_NUM_INTERFACES) { CERROR("Bad nips %d from ip %pI4h\n", hello->kshm_nips, &conn->ksnc_ipaddr); return -EPROTO; diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 4c22416..3ea56c8 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -123,10 +123,10 @@ struct lnet_text_buf { /* tmp struct for parsing routes */ /* check that the NI is unique to the interfaces with in the same NI. * This is only a consideration if use_tcp_bonding is set */ static bool -lnet_ni_unique_ni(char *iface_list[LNET_MAX_INTERFACES], char *iface) +lnet_ni_unique_ni(char *iface_list[LNET_NUM_INTERFACES], char *iface) { int i; - for (i = 0; i < LNET_MAX_INTERFACES; i++) { + for (i = 0; i < LNET_NUM_INTERFACES; i++) { if (iface_list[i] && strncmp(iface_list[i], iface, strlen(iface)) == 0) return false; @@ -304,7 +304,7 @@ struct lnet_text_buf { /* tmp struct for parsing routes */ kfree(ni->ni_cpts); - for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) + for (i = 0; i < LNET_NUM_INTERFACES && ni->ni_interfaces[i]; i++) kfree(ni->ni_interfaces[i]); /* release reference to net namespace */ @@ -397,11 +397,11 @@ struct lnet_net * * can free the tokens at the end of the function. * The newly allocated ni_interfaces[] can be * freed when freeing the NI */ - while (niface < LNET_MAX_INTERFACES && + while (niface < LNET_NUM_INTERFACES && ni->ni_interfaces[niface]) niface++; - if (niface >= LNET_MAX_INTERFACES) { + if (niface >= LNET_NUM_INTERFACES) { LCONSOLE_ERROR_MSG(0x115, "Too many interfaces " "for net %s\n", libcfs_net2str(LNET_NIDNET(ni->ni_nid))); -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:47:53 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:53 -0400 Subject: [lustre-devel] [PATCH 01/25] lustre: lnet: remove ni from lnet_finalize In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-2-git-send-email-jsimmons@infradead.org> From: Sergey Cheremencev Remove ni from lnet_finalize and kiblnd_txlist_done input arguments. Also small code cleanup by introducing ibprm_cookie to avoid checkpatch issues. Signed-off-by: Sergey Cheremencev WC-bug-id: https://jira.whamcloud.com/browse/LU-9094 Seagate-bug-id: MRP-4056 Reviewed-on: https://review.whamcloud.com/25375 Reviewed-by: Doug Oucharek Reviewed-by: Amir Shehata Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 2 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 3 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 65 ++++++++++------------ .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 3 +- .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 4 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 20 +++---- drivers/staging/lustre/lnet/lnet/lib-msg.c | 2 +- drivers/staging/lustre/lnet/lnet/lo.c | 4 +- drivers/staging/lustre/lnet/lnet/net_fault.c | 2 +- 10 files changed, 50 insertions(+), 57 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index aedc88c..53cbf6d 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -537,7 +537,7 @@ struct lnet_msg *lnet_create_reply_msg(struct lnet_ni *ni, void lnet_set_reply_msg_len(struct lnet_ni *ni, struct lnet_msg *msg, unsigned int len); -void lnet_finalize(struct lnet_ni *ni, struct lnet_msg *msg, int rc); +void lnet_finalize(struct lnet_msg *msg, int rc); void lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, unsigned int nob); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 75a7e96..b3a4344 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -521,7 +521,7 @@ static int kiblnd_del_peer(struct lnet_ni *ni, lnet_nid_t nid) write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); - kiblnd_txlist_done(ni, &zombies, -EIO); + kiblnd_txlist_done(&zombies, -EIO); return rc; } diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index b1851b5..a3d89ec 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -1034,8 +1034,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, void kiblnd_close_conn_locked(struct kib_conn *conn, int error); void kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid); -void kiblnd_txlist_done(struct lnet_ni *ni, struct list_head *txlist, - int status); +void kiblnd_txlist_done(struct list_head *txlist, int status); void kiblnd_qp_event(struct ib_event *event, void *arg); void kiblnd_cq_event(struct ib_event *event, void *arg); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index cb752dc..debed17 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -54,14 +54,12 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, static void kiblnd_check_sends_locked(struct kib_conn *conn); static void -kiblnd_tx_done(struct lnet_ni *ni, struct kib_tx *tx) +kiblnd_tx_done(struct kib_tx *tx) { struct lnet_msg *lntmsg[2]; - struct kib_net *net = ni->ni_data; int rc; int i; - LASSERT(net); LASSERT(!in_interrupt()); LASSERT(!tx->tx_queued); /* mustn't be queued for sending */ LASSERT(!tx->tx_sending); /* mustn't be awaiting sent callback */ @@ -76,8 +74,6 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, rc = tx->tx_status; if (tx->tx_conn) { - LASSERT(ni == tx->tx_conn->ibc_peer->ibp_ni); - kiblnd_conn_decref(tx->tx_conn); tx->tx_conn = NULL; } @@ -92,12 +88,12 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, if (!lntmsg[i]) continue; - lnet_finalize(ni, lntmsg[i], rc); + lnet_finalize(lntmsg[i], rc); } } void -kiblnd_txlist_done(struct lnet_ni *ni, struct list_head *txlist, int status) +kiblnd_txlist_done(struct list_head *txlist, int status) { struct kib_tx *tx; @@ -108,7 +104,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, /* complete now */ tx->tx_waiting = 0; tx->tx_status = status; - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); } } @@ -281,7 +277,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, spin_unlock(&conn->ibc_lock); if (idle) - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); } static void @@ -794,7 +790,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, * posted NOOPs complete */ spin_unlock(&conn->ibc_lock); - kiblnd_tx_done(peer_ni->ibp_ni, tx); + kiblnd_tx_done(tx); spin_lock(&conn->ibc_lock); CDEBUG(D_NET, "%s(%d): redundant or enough NOOP\n", libcfs_nid2str(peer_ni->ibp_nid), @@ -888,7 +884,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, kiblnd_close_conn(conn, rc); if (done) - kiblnd_tx_done(peer_ni->ibp_ni, tx); + kiblnd_tx_done(tx); spin_lock(&conn->ibc_lock); @@ -1007,7 +1003,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, spin_unlock(&conn->ibc_lock); if (idle) - kiblnd_tx_done(conn->ibc_peer->ibp_ni, tx); + kiblnd_tx_done(tx); } static void @@ -1343,7 +1339,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, CWARN("Abort reconnection of %s: %s\n", libcfs_nid2str(peer_ni->ibp_nid), reason); - kiblnd_txlist_done(peer_ni->ibp_ni, &txs, -ECONNABORTED); + kiblnd_txlist_done(&txs, -ECONNABORTED); return false; } @@ -1421,7 +1417,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, if (tx) { tx->tx_status = -EHOSTUNREACH; tx->tx_waiting = 0; - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); } return; } @@ -1557,7 +1553,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, if (rc) { CERROR("Can't setup GET sink for %s: %d\n", libcfs_nid2str(target.nid), rc); - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); return -EIO; } @@ -1571,7 +1567,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, if (!tx->tx_lntmsg[1]) { CERROR("Can't create reply for GET -> %s\n", libcfs_nid2str(target.nid)); - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); return -EIO; } @@ -1606,7 +1602,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, if (rc) { CERROR("Can't setup PUT src for %s: %d\n", libcfs_nid2str(target.nid), rc); - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); return -EIO; } @@ -1697,7 +1693,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, if (!nob) { /* No RDMA: local completion may happen now! */ - lnet_finalize(ni, lntmsg, 0); + lnet_finalize(lntmsg, 0); } else { /* RDMA: lnet_finalize(lntmsg) when it completes */ tx->tx_lntmsg[0] = lntmsg; @@ -1707,9 +1703,9 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, return; failed_1: - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); failed_0: - lnet_finalize(ni, lntmsg, -EIO); + lnet_finalize(lntmsg, -EIO); } int @@ -1722,6 +1718,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, struct kib_tx *tx; int nob; int post_credit = IBLND_POSTRX_PEER_CREDIT; + u64 ibprm_cookie; int rc = 0; LASSERT(iov_iter_count(to) <= rlen); @@ -1750,17 +1747,18 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, } rc = 0; - lnet_finalize(ni, lntmsg, 0); + lnet_finalize(lntmsg, 0); break; case IBLND_MSG_PUT_REQ: { + u64 ibprm_cookie = rxmsg->ibm_u.putreq.ibprm_cookie; struct kib_msg *txmsg; struct kib_rdma_desc *rd; if (!iov_iter_count(to)) { - lnet_finalize(ni, lntmsg, 0); - kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, 0, - rxmsg->ibm_u.putreq.ibprm_cookie); + lnet_finalize(lntmsg, 0); + kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, + 0, ibprm_cookie); break; } @@ -1788,15 +1786,15 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, if (rc) { CERROR("Can't setup PUT sink for %s: %d\n", libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); - kiblnd_tx_done(ni, tx); + kiblnd_tx_done(tx); /* tell peer_ni it's over */ - kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, rc, - rxmsg->ibm_u.putreq.ibprm_cookie); + kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, + rc, ibprm_cookie); break; } nob = offsetof(struct kib_putack_msg, ibpam_rd.rd_frags[rd->rd_nfrags]); - txmsg->ibm_u.putack.ibpam_src_cookie = rxmsg->ibm_u.putreq.ibprm_cookie; + txmsg->ibm_u.putack.ibpam_src_cookie = ibprm_cookie; txmsg->ibm_u.putack.ibpam_dst_cookie = tx->tx_cookie; kiblnd_init_tx_msg(ni, tx, IBLND_MSG_PUT_ACK, nob); @@ -1817,8 +1815,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, } else { /* GET didn't match anything */ kiblnd_send_completion(rx->rx_conn, IBLND_MSG_GET_DONE, - -ENODATA, - rxmsg->ibm_u.get.ibgm_cookie); + -ENODATA, ibprm_cookie); } break; } @@ -2016,7 +2013,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, spin_unlock(&conn->ibc_lock); - kiblnd_txlist_done(conn->ibc_peer->ibp_ni, &zombies, -ECONNABORTED); + kiblnd_txlist_done(&zombies, -ECONNABORTED); } static void @@ -2098,7 +2095,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, CNETERR("Deleting messages for %s: connection failed\n", libcfs_nid2str(peer_ni->ibp_nid)); - kiblnd_txlist_done(peer_ni->ibp_ni, &zombies, -EHOSTUNREACH); + kiblnd_txlist_done(&zombies, -EHOSTUNREACH); } static void @@ -2170,13 +2167,11 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, if (!kiblnd_peer_active(peer_ni) || /* peer_ni has been deleted */ conn->ibc_comms_error) { /* error has happened already */ - struct lnet_ni *ni = peer_ni->ibp_ni; - /* start to shut down connection */ kiblnd_close_conn_locked(conn, -ECONNABORTED); write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); - kiblnd_txlist_done(ni, &txs, -ECONNABORTED); + kiblnd_txlist_done(&txs, -ECONNABORTED); return; } diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 534ba84..9b9cc87 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -1653,8 +1653,7 @@ struct ksock_peer * &conn->ksnc_ipaddr, conn->ksnc_port, iov_iter_count(&conn->ksnc_rx_to), conn->ksnc_rx_nob_left, ktime_get_seconds() - last_rcv); - lnet_finalize(conn->ksnc_peer->ksnp_ni, - conn->ksnc_cookie, -EIO); + lnet_finalize(conn->ksnc_cookie, -EIO); break; case SOCKNAL_RX_LNET_HEADER: if (conn->ksnc_rx_started) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 1bf0170..2e99a17 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -343,7 +343,7 @@ struct ksock_tx * ksocknal_free_tx(tx); if (lnetmsg) /* KSOCK_MSG_NOOP go without lnetmsg */ - lnet_finalize(ni, lnetmsg, rc); + lnet_finalize(lnetmsg, rc); } void @@ -1226,7 +1226,7 @@ struct ksock_route * le64_to_cpu(lhdr->src_nid) != id->nid); } - lnet_finalize(conn->ksnc_peer->ksnp_ni, conn->ksnc_cookie, rc); + lnet_finalize(conn->ksnc_cookie, rc); if (rc) { ksocknal_new_packet(conn, 0); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index d39331f..a213387 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -408,7 +408,7 @@ } rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); if (rc < 0) - lnet_finalize(ni, msg, rc); + lnet_finalize(msg, rc); } static void @@ -462,7 +462,7 @@ rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); if (rc < 0) - lnet_finalize(ni, msg, rc); + lnet_finalize(msg, rc); } static int @@ -637,7 +637,7 @@ CNETERR("Dropping message for %s: peer not alive\n", libcfs_id2str(msg->msg_target)); if (do_send) - lnet_finalize(ni, msg, -EHOSTUNREACH); + lnet_finalize(msg, -EHOSTUNREACH); lnet_net_lock(cpt); return -EHOSTUNREACH; @@ -650,7 +650,7 @@ CNETERR("Aborting message for %s: LNetM[DE]Unlink() already called on the MD/ME.\n", libcfs_id2str(msg->msg_target)); if (do_send) - lnet_finalize(ni, msg, -ECANCELED); + lnet_finalize(msg, -ECANCELED); lnet_net_lock(cpt); return -ECANCELED; @@ -915,7 +915,7 @@ lnet_ni_recv(msg->msg_rxni, msg->msg_private, NULL, 0, 0, 0, msg->msg_hdr.payload_length); list_del_init(&msg->msg_list); - lnet_finalize(NULL, msg, -ECANCELED); + lnet_finalize(msg, -ECANCELED); } lnet_net_lock(cpt); @@ -1914,7 +1914,7 @@ libcfs_nid2str(ni->ni_nid), libcfs_id2str(info.mi_id), rc); - lnet_finalize(ni, msg, rc); + lnet_finalize(msg, rc); } return 0; @@ -2402,7 +2402,7 @@ free_drop: LASSERT(!msg->msg_md); - lnet_finalize(ni, msg, rc); + lnet_finalize(msg, rc); drop: lnet_drop_message(ni, cpt, private, payload_length); @@ -2447,7 +2447,7 @@ * but we still should give error code so lnet_msg_decommit() * can skip counters operations and other checks. */ - lnet_finalize(msg->msg_rxni, msg, -ENOENT); + lnet_finalize(msg, -ENOENT); } } @@ -2605,7 +2605,7 @@ if (rc) { CNETERR("Error sending PUT to %s: %d\n", libcfs_id2str(target), rc); - lnet_finalize(NULL, msg, rc); + lnet_finalize(msg, rc); } /* completion will be signalled by an event */ @@ -2804,7 +2804,7 @@ struct lnet_msg * if (rc < 0) { CNETERR("Error sending GET to %s: %d\n", libcfs_id2str(target), rc); - lnet_finalize(NULL, msg, rc); + lnet_finalize(msg, rc); } /* completion will be signalled by an event */ diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index aa28b6a..00be9ab 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -452,7 +452,7 @@ } void -lnet_finalize(struct lnet_ni *ni, struct lnet_msg *msg, int status) +lnet_finalize(struct lnet_msg *msg, int status) { struct lnet_msg_container *container; int my_slot; diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c index 8167980..c8a1eb62 100644 --- a/drivers/staging/lustre/lnet/lnet/lo.c +++ b/drivers/staging/lustre/lnet/lnet/lo.c @@ -62,10 +62,10 @@ sendmsg->msg_offset, iov_iter_count(to)); - lnet_finalize(ni, lntmsg, 0); + lnet_finalize(lntmsg, 0); } - lnet_finalize(ni, sendmsg, 0); + lnet_finalize(sendmsg, 0); return 0; } diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c index 17891f6..3841bac 100644 --- a/drivers/staging/lustre/lnet/lnet/net_fault.c +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c @@ -633,7 +633,7 @@ struct delay_daemon_data { } lnet_drop_message(ni, cpt, msg->msg_private, msg->msg_len); - lnet_finalize(ni, msg, rc); + lnet_finalize(msg, rc); } } -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:02 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:02 -0400 Subject: [lustre-devel] [PATCH 10/25] lustre: lnet: increment per NI stats In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-11-git-send-email-jsimmons@infradead.org> From: Amir Shehata Increment the per NI stats for messages being routed. This will give a better view of the traffic distribution over multiple peer interfaces. Added extra trace messages to track the messages sent and received. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26907 Reviewed-by: Doug Oucharek Reviewed-by: Sonia Sharma Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/lnet/lib-move.c | 16 ++++++++++++++++ drivers/staging/lustre/lnet/lnet/lib-msg.c | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 2cf9c89..275e8a9 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1723,6 +1723,16 @@ rc = lnet_post_send_locked(msg, 0); + if (!rc) + CDEBUG(D_NET, "TRACE: %s(%s:%s) -> %s(%s:%s) : %s\n", + libcfs_nid2str(msg->msg_hdr.src_nid), + libcfs_nid2str(msg->msg_txni->ni_nid), + libcfs_nid2str(src_nid), + libcfs_nid2str(msg->msg_hdr.dest_nid), + libcfs_nid2str(dst_nid), + libcfs_nid2str(msg->msg_txpeer->lpni_nid), + lnet_msgtyp2str(msg->msg_type)); + lnet_net_unlock(cpt); return rc; @@ -2195,6 +2205,12 @@ for_me = (ni->ni_nid == dest_nid); cpt = lnet_cpt_of_nid(from_nid, ni); + CDEBUG(D_NET, "TRACE: %s(%s) <- %s : %s\n", + libcfs_nid2str(dest_nid), + libcfs_nid2str(ni->ni_nid), + libcfs_nid2str(src_nid), + lnet_msgtyp2str(type)); + switch (type) { case LNET_MSG_ACK: case LNET_MSG_GET: diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index 00be9ab..1817e54 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -187,7 +187,7 @@ counters->route_length += msg->msg_len; counters->route_count++; - goto out; + goto incr_stats; case LNET_EVENT_PUT: /* should have been decommitted */ @@ -215,6 +215,8 @@ } counters->send_count++; + +incr_stats: if (msg->msg_txpeer) atomic_inc(&msg->msg_txpeer->lpni_stats.send_count); if (msg->msg_txni) @@ -241,7 +243,7 @@ default: LASSERT(!ev->type); LASSERT(msg->msg_routing); - goto out; + goto incr_stats; case LNET_EVENT_ACK: LASSERT(msg->msg_type == LNET_MSG_ACK); @@ -274,6 +276,8 @@ } counters->recv_count++; + +incr_stats: if (msg->msg_rxpeer) atomic_inc(&msg->msg_rxpeer->lpni_stats.recv_count); if (msg->msg_rxni) -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:05 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:05 -0400 Subject: [lustre-devel] [PATCH 13/25] lustre: lnet: fix lnet_cpt_of_md() In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-14-git-send-email-jsimmons@infradead.org> From: Amir Shehata The intent of this function is to get the cpt nearest to the memory described by the MD. There are three scenarios that must be handled: 1. The memory is described by an lnet_kiov_t structure -> this describes kernel pages 2. The memory is described by a struct kvec -> this describes kernel logical addresses 3. The memory is a contiguous buffer allocated via vmalloc For case 1 and 2 we look at the first vector which contains the data to be DMAed, taking into consideration the msg offset. For case 2 we have to take the extra step of translating the kernel logical address to a physical page using virt_to_page() macro. For case 3 we need to use is_vmalloc_addr() and vmalloc_to_page to get the associated page to be able to identify the CPT. o2iblnd uses the same strategy when it's mapping the memory into a scatter/gather list. Therefore, lnet_kvaddr_to_page() common function was created to be used by both the o2iblnd and lnet_cpt_of_md() kmap_to_page() performs the high memory check which lnet_kvaddr_to_page() does. However, unlike the latter it handles the highmem case properly instead of calling LBUG. It's not 100% clear why the code was written that way. Since the legacy code will need to still be maintained, adding kmap_to_page() will not simplify the code. At worst calling kmap_to_page() might mask some problems which would've been caught by the LBUG earlier on. However, at the time of this fix, that LBUG has never been observed. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9203 Reviewed-on: https://review.whamcloud.com/28165 Reviewed-by: Dmitry Eremin Reviewed-by: Sonia Sharma Reviewed-by: Olaf Weber Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 +- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 25 +----- drivers/staging/lustre/lnet/lnet/lib-md.c | 96 ++++++++++++++++++---- drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- 4 files changed, 82 insertions(+), 44 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 6bfdc9b..16e64d8 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -595,7 +595,8 @@ void lnet_copy_kiov2iter(struct iov_iter *to, void lnet_md_unlink(struct lnet_libmd *md); void lnet_md_deconstruct(struct lnet_libmd *lmd, struct lnet_md *umd); -int lnet_cpt_of_md(struct lnet_libmd *md); +struct page *lnet_kvaddr_to_page(unsigned long vaddr); +int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset); void lnet_register_lnd(struct lnet_lnd *lnd); void lnet_unregister_lnd(struct lnet_lnd *lnd); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index debed17..a6b261a 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -531,29 +531,6 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, kiblnd_drop_rx(rx); /* Don't re-post rx. */ } -static struct page * -kiblnd_kvaddr_to_page(unsigned long vaddr) -{ - struct page *page; - - if (is_vmalloc_addr((void *)vaddr)) { - page = vmalloc_to_page((void *)vaddr); - LASSERT(page); - return page; - } -#ifdef CONFIG_HIGHMEM - if (vaddr >= PKMAP_BASE && - vaddr < (PKMAP_BASE + LAST_PKMAP * PAGE_SIZE)) { - /* No highmem pages only used for bulk (kiov) I/O */ - CERROR("find page for address in highmem\n"); - LBUG(); - } -#endif - page = virt_to_page(vaddr); - LASSERT(page); - return page; -} - static int kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, struct kib_rdma_desc *rd, __u32 nob) { @@ -660,7 +637,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, vaddr = ((unsigned long)iov->iov_base) + offset; page_offset = vaddr & (PAGE_SIZE - 1); - page = kiblnd_kvaddr_to_page(vaddr); + page = lnet_kvaddr_to_page(vaddr); if (!page) { CERROR("Can't find page\n"); return -EFAULT; diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c index 9e26911..db5425e 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-md.c +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c @@ -84,33 +84,93 @@ kfree(md); } -int -lnet_cpt_of_md(struct lnet_libmd *md) +struct page *lnet_kvaddr_to_page(unsigned long vaddr) { - int cpt = CFS_CPT_ANY; + if (is_vmalloc_addr((void *)vaddr)) + return vmalloc_to_page((void *)vaddr); + +#ifdef CONFIG_HIGHMEM + return kmap_to_page((void *)vaddr); +#else + return virt_to_page(vaddr); +#endif /* CONFIG_HIGHMEM */ +} +EXPORT_SYMBOL(lnet_kvaddr_to_page); - if (!md) - return CFS_CPT_ANY; +int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset) +{ + int cpt = CFS_CPT_ANY; + unsigned int niov; - if ((md->md_options & LNET_MD_BULK_HANDLE) != 0 && - md->md_bulk_handle.cookie != LNET_WIRE_HANDLE_COOKIE_NONE) { + /* + * if the md_options has a bulk handle then we want to look at the + * bulk md because that's the data which we will be DMAing + */ + if (md && (md->md_options & LNET_MD_BULK_HANDLE) != 0 && + md->md_bulk_handle.cookie != LNET_WIRE_HANDLE_COOKIE_NONE) md = lnet_handle2md(&md->md_bulk_handle); - if (!md) - return CFS_CPT_ANY; - } + if (!md || md->md_niov == 0) + return CFS_CPT_ANY; + + niov = md->md_niov; + /* + * There are three cases to handle: + * 1. The MD is using lnet_kiov_t + * 2. The MD is using struct kvec + * 3. Contiguous buffer allocated via vmalloc + * + * in case 2 we can use virt_to_page() macro to get the page + * address of the memory kvec describes. + * + * in case 3 use is_vmalloc_addr() and vmalloc_to_page() + * + * The offset provided can be within the first iov/kiov entry or + * it could go beyond it. In that case we need to make sure to + * look at the page which actually contains the data that will be + * DMAed. + */ if ((md->md_options & LNET_MD_KIOV) != 0) { - if (md->md_iov.kiov[0].bv_page) - cpt = cfs_cpt_of_node( - lnet_cpt_table(), - page_to_nid(md->md_iov.kiov[0].bv_page)); - } else if (md->md_iov.iov[0].iov_base) { - cpt = cfs_cpt_of_node( - lnet_cpt_table(), - page_to_nid(virt_to_page(md->md_iov.iov[0].iov_base))); + struct bio_vec *kiov = md->md_iov.kiov; + + while (offset >= kiov->bv_len) { + offset -= kiov->bv_len; + niov--; + kiov++; + if (niov == 0) { + CERROR("offset %d goes beyond kiov\n", offset); + goto out; + } + } + + cpt = cfs_cpt_of_node(lnet_cpt_table(), + page_to_nid(kiov->bv_page)); + } else { + struct kvec *iov = md->md_iov.iov; + unsigned long vaddr; + struct page *page; + + while (offset >= iov->iov_len) { + offset -= iov->iov_len; + niov--; + iov++; + if (niov == 0) { + CERROR("offset %d goes beyond iov\n", offset); + goto out; + } + } + + vaddr = ((unsigned long)iov->iov_base) + offset; + page = lnet_kvaddr_to_page(vaddr); + if (!page) { + CERROR("Couldn't resolve vaddr 0x%lx to page\n", vaddr); + goto out; + } + cpt = cfs_cpt_of_node(lnet_cpt_table(), page_to_nid(page)); } +out: return cpt; } diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index f2bc97d..4d74421 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1226,7 +1226,7 @@ */ cpt = lnet_net_lock_current(); - md_cpt = lnet_cpt_of_md(msg->msg_md); + md_cpt = lnet_cpt_of_md(msg->msg_md, msg->msg_offset); if (md_cpt == CFS_CPT_ANY) md_cpt = cpt; -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:47:54 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:54 -0400 Subject: [lustre-devel] [PATCH 02/25] lustre: lnet: Allow min stats to be reset in peers and nis In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-3-git-send-email-jsimmons@infradead.org> From: Doug Oucharek Allow writes to the peers and nis LNet procfs files to reset the mininum stat columns. Signed-off-by: Doug Oucharek WC-bug-id: https://jira.whamcloud.com/browse/LU-7214 Reviewed-on: https://review.whamcloud.com/20470 Reviewed-by: Olaf Weber Reviewed-by: Amir Shehata Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/lnet/router_proc.c | 69 +++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index a887ca4..4ddd35b 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -393,7 +393,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, { const int tmpsiz = 256; struct lnet_peer_table *ptable; - char *tmpstr; + char *tmpstr = NULL; char *s; int cpt = LNET_PROC_CPT_GET(*ppos); int ver = LNET_PROC_VER_GET(*ppos); @@ -402,12 +402,33 @@ static int proc_lnet_peers(struct ctl_table *table, int write, int rc = 0; int len; - BUILD_BUG_ON(LNET_PROC_HASH_BITS < LNET_PEER_HASH_BITS); - LASSERT(!write); + if (write) { + struct lnet_peer_ni *peer; + int i; + + cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { + lnet_net_lock(i); + for (hash = 0; hash < LNET_PEER_HASH_SIZE; hash++) { + list_for_each_entry(peer, + &ptable->pt_hash[hash], + lpni_hashlist) { + peer->lpni_mintxcredits = + peer->lpni_txcredits; + peer->lpni_minrtrcredits = + peer->lpni_rtrcredits; + } + } + lnet_net_unlock(i); + } + *ppos += *lenp; + return 0; + } if (!*lenp) return 0; + BUILD_BUG_ON(LNET_PROC_HASH_BITS < LNET_PEER_HASH_BITS); + if (cpt >= LNET_CPT_NUMBER) { *lenp = 0; return 0; @@ -627,11 +648,45 @@ static int proc_lnet_nis(struct ctl_table *table, int write, char *s; int len; - LASSERT(!write); - if (!*lenp) return 0; + if (write) { + /* Just reset the min stat. */ + struct lnet_net *net; + struct lnet_ni *ni; + + lnet_net_lock(0); + + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + struct lnet_tx_queue *tq; + int i; + int j; + + cfs_percpt_for_each(tq, i, ni->ni_tx_queues) { + for (j = 0; ni->ni_cpts && + j < ni->ni_ncpts; j++) { + if (i == ni->ni_cpts[j]) + break; + } + + if (j == ni->ni_ncpts) + continue; + + if (i != 0) + lnet_net_lock(i); + tq->tq_credits_min = tq->tq_credits; + if (i != 0) + lnet_net_unlock(i); + } + } + } + lnet_net_unlock(0); + *ppos += *lenp; + return 0; + } + tmpstr = kvmalloc(tmpsiz, GFP_KERNEL); if (!tmpstr) return -ENOMEM; @@ -847,7 +902,7 @@ static int proc_lnet_portal_rotor(struct ctl_table *table, int write, }, { .procname = "peers", - .mode = 0444, + .mode = 0644, .proc_handler = &proc_lnet_peers, }, { @@ -857,7 +912,7 @@ static int proc_lnet_portal_rotor(struct ctl_table *table, int write, }, { .procname = "nis", - .mode = 0444, + .mode = 0644, .proc_handler = &proc_lnet_nis, }, { -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:47:55 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:55 -0400 Subject: [lustre-devel] [PATCH 03/25] lustre: lnet: remove debug ioctl In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-4-git-send-email-jsimmons@infradead.org> From: Olaf Weber Remove a debug ioctl that was added to allow for debug messages from user space. However, the code is currently not being used. Signed-off-by: Amir Shehata Signed-off-by: Olaf Weber WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26688 Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 3 +-- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 22 -------------------- drivers/staging/lustre/lnet/lnet/api-ni.c | 24 ---------------------- 3 files changed, 1 insertion(+), 48 deletions(-) diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h index a231f6d..2a9beed 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h @@ -144,7 +144,6 @@ struct libcfs_debug_ioctl_data { #define IOC_LIBCFS_GET_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 97, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_SET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_GET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 99, IOCTL_CONFIG_SIZE) -#define IOC_LIBCFS_DBG _IOWR(IOC_LIBCFS_TYPE, 100, IOCTL_CONFIG_SIZE) -#define IOC_LIBCFS_MAX_NR 100 +#define IOC_LIBCFS_MAX_NR 99 #endif /* __LIBCFS_IOCTL_H__ */ diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index d1e2911..2594642 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -94,10 +94,6 @@ struct lnet_ioctl_net_config { /* # different router buffer pools */ #define LNET_NRBPOOLS (LNET_LARGE_BUF_IDX + 1) -enum lnet_dbg_task { - LNET_DBG_INCR_DLC_SEQ = 0 -}; - struct lnet_ioctl_pool_cfg { struct { __u32 pl_npages; @@ -196,24 +192,6 @@ struct lnet_ioctl_peer { } pr_lnd_u; }; -struct lnet_dbg_task_info { - /* - * TODO: a union can be added if the task requires more - * information from user space to be carried out in kernel space. - */ -}; - -/* - * This structure is intended to allow execution of debugging tasks. This - * is not intended to be backwards compatible. Extra tasks can be added in - * the future - */ -struct lnet_ioctl_dbg { - struct libcfs_ioctl_hdr dbg_hdr; - enum lnet_dbg_task dbg_task; - char dbg_bulk[0]; -}; - struct lnet_ioctl_peer_cfg { struct libcfs_ioctl_hdr prcfg_hdr; lnet_nid_t prcfg_prim_nid; diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 9a09927..43e8db1 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1866,17 +1866,6 @@ void lnet_lib_exit(void) } EXPORT_SYMBOL(LNetNIFini); -static int lnet_handle_dbg_task(struct lnet_ioctl_dbg *dbg, - struct lnet_dbg_task_info *dbg_info) -{ - switch (dbg->dbg_task) { - case LNET_DBG_INCR_DLC_SEQ: - lnet_incr_dlc_seq(); - } - - return 0; -} - /** * Grabs the ni data from the ni structure and fills the out * parameters @@ -2845,19 +2834,6 @@ u32 lnet_get_dlc_seq_locked(void) return 0; } - case IOC_LIBCFS_DBG: { - struct lnet_ioctl_dbg *dbg = arg; - struct lnet_dbg_task_info *dbg_info; - size_t total = sizeof(*dbg) + sizeof(*dbg_info); - - if (dbg->dbg_hdr.ioc_len < total) - return -EINVAL; - - dbg_info = (struct lnet_dbg_task_info *)dbg->dbg_bulk; - - return lnet_handle_dbg_task(dbg, dbg_info); - } - default: ni = lnet_net2ni_addref(data->ioc_net); if (!ni) -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:08 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:08 -0400 Subject: [lustre-devel] [PATCH 16/25] lustre: o2iblnd: kill timedout txs from ibp_tx_queue In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-17-git-send-email-jsimmons@infradead.org> From: Sergey Cheremencev Sometimes connection can't be established for a long time due to rejections and produces cycle of reconnections. Peer is not removed in each iteration unlike connection. Thus until connection becomes established txs live in peer->ibp_tx_queue. This patch adds tx_deadline checking for txs from peer tx_queue. Signed-off-by: Sergey Cheremencev WC-bug-id: https://jira.whamcloud.com/browse/LU-9094 Seagate-bug-id: MRP-4056 Reviewed-on: https://review.whamcloud.com/25376 Reviewed-by: Doug Oucharek Reviewed-by: Amir Shehata Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index dc71554..3218999 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -3159,8 +3159,10 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, { LIST_HEAD(closes); LIST_HEAD(checksends); + LIST_HEAD(timedout_txs); struct list_head *peers = &kiblnd_data.kib_peers[idx]; struct kib_peer_ni *peer_ni; + struct kib_tx *tx_tmp, *tx; struct kib_conn *conn; unsigned long flags; @@ -3169,9 +3171,19 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, * RDMAs to time out, so we just use a shared lock while we * take a look... */ - read_lock_irqsave(&kiblnd_data.kib_global_lock, flags); + write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); list_for_each_entry(peer_ni, peers, ibp_list) { + /* Check tx_deadline */ + list_for_each_entry_safe(tx, tx_tmp, &peer_ni->ibp_tx_queue, tx_list) { + if (ktime_compare(ktime_get(), tx->tx_deadline) >= 0) { + CWARN("Timed out tx for %s: %lld seconds\n", + libcfs_nid2str(peer_ni->ibp_nid), + ktime_ms_delta(ktime_get(), + tx->tx_deadline) / MSEC_PER_SEC); + list_move(&tx->tx_list, &timedout_txs); + } + } list_for_each_entry(conn, &peer_ni->ibp_conns, ibc_list) { int timedout; @@ -3207,7 +3219,10 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, } } - read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); + write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); + + if (!list_empty(&timedout_txs)) + kiblnd_txlist_done(&timedout_txs, -ETIMEDOUT); /* * Handle timeout by closing the whole -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:00 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:00 -0400 Subject: [lustre-devel] [PATCH 08/25] lustre: lnet: selftest MR fix In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-9-git-send-email-jsimmons@infradead.org> From: Amir Shehata selftest always responded to the primary nid of the peer rather than the source of the message, which it should be. Signed-off-by: Amir Shehata Signed-off-by: Olaf Weber WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26723 Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/selftest/rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index 298de41..26132ab 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -1482,7 +1482,7 @@ struct srpc_client_rpc * sv->sv_shuttingdown); buffer = container_of(ev->md.start, struct srpc_buffer, buf_msg); - buffer->buf_peer = ev->initiator; + buffer->buf_peer = ev->source; buffer->buf_self = ev->target.nid; LASSERT(scd->scd_buf_nposted > 0); -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:47:56 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:56 -0400 Subject: [lustre-devel] [PATCH 04/25] lustre: lnet: Normalize ioctl interface In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-5-git-send-email-jsimmons@infradead.org> From: Amir Shehata To avoid backwards compatibility issues between base MR and Dynamic Discovery standardize the ioctl interface by bringing in changes to the interface required by Dynamic Discovery now. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26689 Reviewed-by: Olaf Weber Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/include/linux/lnet/lib-lnet.h | 5 ++- .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 39 ++++++++++++++++--- drivers/staging/lustre/lnet/lnet/api-ni.c | 21 +++++----- drivers/staging/lustre/lnet/lnet/peer.c | 45 ++++++++++++++-------- 4 files changed, 77 insertions(+), 33 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index 53cbf6d..f510b9e 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -665,8 +665,9 @@ bool lnet_peer_is_ni_pref_locked(struct lnet_peer_ni *lpni, int lnet_add_peer_ni_to_peer(lnet_nid_t key_nid, lnet_nid_t nid, bool mr); int lnet_del_peer_ni_from_peer(lnet_nid_t key_nid, lnet_nid_t nid); int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, - bool *mr, struct lnet_peer_ni_credit_info *peer_ni_info, - struct lnet_ioctl_element_stats *peer_ni_stats); + bool *mr, + struct lnet_peer_ni_credit_info __user *peer_ni_info, + struct lnet_ioctl_element_stats __user *peer_ni_stats); int lnet_get_peer_ni_info(__u32 peer_index, __u64 *nid, char alivness[LNET_MAX_STR_LEN], __u32 *cpt_iter, __u32 *refcount, diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index 2594642..e603455 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -104,6 +104,17 @@ struct lnet_ioctl_pool_cfg { __u32 pl_routing; }; +struct lnet_ioctl_ping_data { + struct libcfs_ioctl_hdr ping_hdr; + + __u32 op_param; + __u32 ping_count; + __u32 ping_flags; + bool mr_info; + struct lnet_process_id ping_id; + struct lnet_process_id __user *ping_buf; +}; + struct lnet_ioctl_config_data { struct libcfs_ioctl_hdr cfg_hdr; @@ -138,10 +149,26 @@ struct lnet_ioctl_config_data { char cfg_bulk[0]; }; +struct lnet_ioctl_comm_count { + __u32 ico_get_count; + __u32 ico_put_count; + __u32 ico_reply_count; + __u32 ico_ack_count; + __u32 ico_hello_count; +}; + struct lnet_ioctl_element_stats { - u32 send_count; - u32 recv_count; - u32 drop_count; + __u32 iel_send_count; + __u32 iel_recv_count; + __u32 iel_drop_count; +}; + +struct lnet_ioctl_element_msg_stats { + struct libcfs_ioctl_hdr im_hdr; + __u32 im_idx; + struct lnet_ioctl_comm_count im_send_stats; + struct lnet_ioctl_comm_count im_recv_stats; + struct lnet_ioctl_comm_count im_drop_stats; }; /* @@ -196,9 +223,11 @@ struct lnet_ioctl_peer_cfg { struct libcfs_ioctl_hdr prcfg_hdr; lnet_nid_t prcfg_prim_nid; lnet_nid_t prcfg_cfg_nid; - __u32 prcfg_idx; + __u32 prcfg_count; bool prcfg_mr; - char prcfg_bulk[0]; + __u32 prcfg_state; + __u32 prcfg_size; + void __user *prcfg_bulk; }; struct lnet_ioctl_numa_range { diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 43e8db1..2d430d0 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -1904,8 +1904,8 @@ void lnet_lib_exit(void) memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn)); if (stats) { - stats->send_count = atomic_read(&ni->ni_stats.send_count); - stats->recv_count = atomic_read(&ni->ni_stats.recv_count); + stats->iel_send_count = atomic_read(&ni->ni_stats.send_count); + stats->iel_recv_count = atomic_read(&ni->ni_stats.recv_count); } /* @@ -2761,20 +2761,19 @@ u32 lnet_get_dlc_seq_locked(void) case IOC_LIBCFS_GET_PEER_NI: { struct lnet_ioctl_peer_cfg *cfg = arg; - struct lnet_peer_ni_credit_info *lpni_cri; - struct lnet_ioctl_element_stats *lpni_stats; - size_t total = sizeof(*cfg) + sizeof(*lpni_cri) + - sizeof(*lpni_stats); + struct lnet_peer_ni_credit_info __user *lpni_cri; + struct lnet_ioctl_element_stats __user *lpni_stats; + size_t usr_size = sizeof(*lpni_cri) + sizeof(*lpni_stats); - if (cfg->prcfg_hdr.ioc_len < total) + if ((cfg->prcfg_hdr.ioc_len != sizeof(*cfg)) || + (cfg->prcfg_size != usr_size)) return -EINVAL; - lpni_cri = (struct lnet_peer_ni_credit_info *)cfg->prcfg_bulk; - lpni_stats = (struct lnet_ioctl_element_stats *) - (cfg->prcfg_bulk + sizeof(*lpni_cri)); + lpni_cri = cfg->prcfg_bulk; + lpni_stats = cfg->prcfg_bulk + sizeof(*lpni_cri); mutex_lock(&the_lnet.ln_api_mutex); - rc = lnet_get_peer_info(cfg->prcfg_idx, &cfg->prcfg_prim_nid, + rc = lnet_get_peer_info(cfg->prcfg_count, &cfg->prcfg_prim_nid, &cfg->prcfg_cfg_nid, &cfg->prcfg_mr, lpni_cri, lpni_stats); mutex_unlock(&the_lnet.ln_api_mutex); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 3a5f9db..ae3ffca 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -1179,12 +1179,16 @@ struct lnet_peer_ni * } int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, - bool *mr, struct lnet_peer_ni_credit_info *peer_ni_info, - struct lnet_ioctl_element_stats *peer_ni_stats) + bool *mr, + struct lnet_peer_ni_credit_info __user *peer_ni_info, + struct lnet_ioctl_element_stats __user *peer_ni_stats) { + struct lnet_ioctl_element_stats ni_stats; + struct lnet_peer_ni_credit_info ni_info; struct lnet_peer_ni *lpni = NULL; struct lnet_peer_net *lpn = NULL; struct lnet_peer *lp = NULL; + int rc; lpni = lnet_get_peer_ni_idx_locked(idx, &lpn, &lp); @@ -1194,24 +1198,35 @@ int lnet_get_peer_info(__u32 idx, lnet_nid_t *primary_nid, lnet_nid_t *nid, *primary_nid = lp->lp_primary_nid; *mr = lp->lp_multi_rail; *nid = lpni->lpni_nid; - snprintf(peer_ni_info->cr_aliveness, LNET_MAX_STR_LEN, "NA"); + snprintf(ni_info.cr_aliveness, LNET_MAX_STR_LEN, "NA"); if (lnet_isrouter(lpni) || lnet_peer_aliveness_enabled(lpni)) - snprintf(peer_ni_info->cr_aliveness, LNET_MAX_STR_LEN, + snprintf(ni_info.cr_aliveness, LNET_MAX_STR_LEN, lpni->lpni_alive ? "up" : "down"); - peer_ni_info->cr_refcount = atomic_read(&lpni->lpni_refcount); - peer_ni_info->cr_ni_peer_tx_credits = lpni->lpni_net ? + ni_info.cr_refcount = atomic_read(&lpni->lpni_refcount); + ni_info.cr_ni_peer_tx_credits = lpni->lpni_net ? lpni->lpni_net->net_tunables.lct_peer_tx_credits : 0; - peer_ni_info->cr_peer_tx_credits = lpni->lpni_txcredits; - peer_ni_info->cr_peer_rtr_credits = lpni->lpni_rtrcredits; - peer_ni_info->cr_peer_min_rtr_credits = lpni->lpni_minrtrcredits; - peer_ni_info->cr_peer_min_tx_credits = lpni->lpni_mintxcredits; - peer_ni_info->cr_peer_tx_qnob = lpni->lpni_txqnob; + ni_info.cr_peer_tx_credits = lpni->lpni_txcredits; + ni_info.cr_peer_rtr_credits = lpni->lpni_rtrcredits; + ni_info.cr_peer_min_rtr_credits = lpni->lpni_minrtrcredits; + ni_info.cr_peer_min_tx_credits = lpni->lpni_mintxcredits; + ni_info.cr_peer_tx_qnob = lpni->lpni_txqnob; - peer_ni_stats->send_count = atomic_read(&lpni->lpni_stats.send_count); - peer_ni_stats->recv_count = atomic_read(&lpni->lpni_stats.recv_count); - peer_ni_stats->drop_count = atomic_read(&lpni->lpni_stats.drop_count); + ni_stats.iel_send_count = atomic_read(&lpni->lpni_stats.send_count); + ni_stats.iel_recv_count = atomic_read(&lpni->lpni_stats.recv_count); + ni_stats.iel_drop_count = atomic_read(&lpni->lpni_stats.drop_count); - return 0; + /* If copy_to_user fails */ + rc = -EFAULT; + if (copy_to_user(peer_ni_info, &ni_info, sizeof(ni_info))) + goto copy_failed; + + if (copy_to_user(peer_ni_stats, &ni_stats, sizeof(ni_stats))) + goto copy_failed; + + rc = 0; + +copy_failed: + return rc; } -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:09 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:09 -0400 Subject: [lustre-devel] [PATCH 17/25] lustre: o2iblnd: multiple sges for work request In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-18-git-send-email-jsimmons@infradead.org> From: Liang Zhen In current protocol, lnet router cannot align buffer for rdma, o2iblnd may run into "too fragmented RDMA" issue while routing non-page-aligned IO larger than 512K, because each page will be splited into two fragments by kiblnd_init_rdma(). With this patch, o2iblnd can have multiple sges for each work request, and combine multiple remote fragments of the same page into one work request to resovle the "too fragmented RDMA" issue. Signed-off-by: Liang Zhen WC-bug-id: https://jira.whamcloud.com/browse/LU-5718 Reviewed-on: https://review.whamcloud.com/12451 Reviewed-by: Amir Shehata Reviewed-by: Nathaniel Clark Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 13 ++-- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 5 ++ .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 73 ++++++++++++---------- .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 7 ++- 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index aea83a5..9e8248e 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -761,7 +761,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, init_qp_attr->qp_context = conn; init_qp_attr->cap.max_send_wr = IBLND_SEND_WRS(conn); init_qp_attr->cap.max_recv_wr = IBLND_RECV_WRS(conn); - init_qp_attr->cap.max_send_sge = 1; + init_qp_attr->cap.max_send_sge = *kiblnd_tunables.kib_wrq_sge; init_qp_attr->cap.max_recv_sge = 1; init_qp_attr->sq_sig_type = IB_SIGNAL_REQ_WR; init_qp_attr->qp_type = IB_QPT_RC; @@ -772,9 +772,11 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, rc = rdma_create_qp(cmid, conn->ibc_hdev->ibh_pd, init_qp_attr); if (rc) { - CERROR("Can't create QP: %d, send_wr: %d, recv_wr: %d\n", + CERROR("Can't create QP: %d, send_wr: %d, recv_wr: %d, send_sge: %d, recv_sge: %d\n", rc, init_qp_attr->cap.max_send_wr, - init_qp_attr->cap.max_recv_wr); + init_qp_attr->cap.max_recv_wr, + init_qp_attr->cap.max_send_sge, + init_qp_attr->cap.max_recv_sge); goto failed_2; } @@ -2039,6 +2041,7 @@ static int kiblnd_create_tx_pool(struct kib_poolset *ps, int size, for (i = 0; i < size; i++) { struct kib_tx *tx = &tpo->tpo_tx_descs[i]; + int wrq_sge = *kiblnd_tunables.kib_wrq_sge; tx->tx_pool = tpo; if (ps->ps_net->ibn_fmr_ps) { @@ -2063,8 +2066,8 @@ static int kiblnd_create_tx_pool(struct kib_poolset *ps, int size, break; tx->tx_sge = kzalloc_cpt((1 + IBLND_MAX_RDMA_FRAGS) * - sizeof(*tx->tx_sge), - GFP_NOFS, ps->ps_cpt); + wrq_sge * sizeof(*tx->tx_sge), + GFP_KERNEL, ps->ps_cpt); if (!tx->tx_sge) break; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index de04355..f21bdee 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -89,6 +89,7 @@ struct kib_tunables { int *kib_require_priv_port; /* accept only privileged ports */ int *kib_use_priv_port; /* use privileged port for active connect */ int *kib_nscheds; /* # threads on each CPT */ + int *kib_wrq_sge; /* # sg elements per wrq */ }; extern struct kib_tunables kiblnd_tunables; @@ -495,7 +496,11 @@ struct kib_tx { /* transmit message */ struct kib_msg *tx_msg; /* message buffer (host vaddr) */ __u64 tx_msgaddr; /* message buffer (I/O addr) */ DECLARE_PCI_UNMAP_ADDR(tx_msgunmap); /* for dma_unmap_single() */ + /** sge for tx_msgaddr */ + struct ib_sge tx_msgsge; int tx_nwrq; /* # send work items */ + /* # used scatter/gather elements */ + int tx_nsge; struct ib_rdma_wr *tx_wrq; /* send work items... */ struct ib_sge *tx_sge; /* ...and their memory */ struct kib_rdma_desc *tx_rd; /* rdma descriptor */ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 3218999..80398c1 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -79,6 +79,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, } tx->tx_nwrq = 0; + tx->tx_nsge = 0; tx->tx_status = 0; kiblnd_pool_free_node(&tx->tx_pool->tpo_pool, &tx->tx_list); @@ -415,6 +416,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, * (b) tx_waiting set tells tx_complete() it's not done. */ tx->tx_nwrq = 0; /* overwrite PUT_REQ */ + tx->tx_nsge = 0; rc2 = kiblnd_init_rdma(conn, tx, IBLND_MSG_PUT_DONE, kiblnd_rd_size(&msg->ibm_u.putack.ibpam_rd), @@ -724,7 +726,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, LASSERT(tx->tx_queued); /* We rely on this for QP sizing */ - LASSERT(tx->tx_nwrq > 0); + LASSERT(tx->tx_nwrq > 0 && tx->tx_nsge >= 0); LASSERT(!credit || credit == 1); LASSERT(conn->ibc_outstanding_credits >= 0); @@ -988,7 +990,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, int body_nob) { struct kib_hca_dev *hdev = tx->tx_pool->tpo_hdev; - struct ib_sge *sge = &tx->tx_sge[tx->tx_nwrq]; + struct ib_sge *sge = &tx->tx_msgsge; struct ib_rdma_wr *wrq = &tx->tx_wrq[tx->tx_nwrq]; int nob = offsetof(struct kib_msg, ibm_u) + body_nob; @@ -1020,17 +1022,17 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, { struct kib_msg *ibmsg = tx->tx_msg; struct kib_rdma_desc *srcrd = tx->tx_rd; - struct ib_sge *sge = &tx->tx_sge[0]; - struct ib_rdma_wr *wrq, *next; + struct ib_rdma_wr *wrq = NULL; + struct ib_sge *sge; int rc = resid; int srcidx = 0; int dstidx = 0; - int wrknob; + int sge_nob; + int wrq_sge; LASSERT(!in_interrupt()); - LASSERT(!tx->tx_nwrq); - LASSERT(type == IBLND_MSG_GET_DONE || - type == IBLND_MSG_PUT_DONE); + LASSERT(!tx->tx_nwrq && !tx->tx_nsge); + LASSERT(type == IBLND_MSG_GET_DONE || type == IBLND_MSG_PUT_DONE); if (kiblnd_rd_size(srcrd) > conn->ibc_max_frags << PAGE_SHIFT) { CERROR("RDMA is too large for peer_ni %s (%d), src size: %d dst size: %d\n", @@ -1041,7 +1043,10 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, goto too_big; } - while (resid > 0) { + for (srcidx = dstidx = wrq_sge = sge_nob = 0; + resid > 0; resid -= sge_nob) { + int prev = dstidx; + if (srcidx >= srcrd->rd_nfrags) { CERROR("Src buffer exhausted: %d frags\n", srcidx); rc = -EPROTO; @@ -1064,40 +1069,44 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, break; } - wrknob = min3(kiblnd_rd_frag_size(srcrd, srcidx), - kiblnd_rd_frag_size(dstrd, dstidx), - (__u32)resid); + sge_nob = min3(kiblnd_rd_frag_size(srcrd, srcidx), + kiblnd_rd_frag_size(dstrd, dstidx), + (u32)resid); - sge = &tx->tx_sge[tx->tx_nwrq]; + sge = &tx->tx_sge[tx->tx_nsge]; sge->addr = kiblnd_rd_frag_addr(srcrd, srcidx); sge->lkey = kiblnd_rd_frag_key(srcrd, srcidx); - sge->length = wrknob; - - wrq = &tx->tx_wrq[tx->tx_nwrq]; - next = wrq + 1; + sge->length = sge_nob; - wrq->wr.next = &next->wr; - wrq->wr.wr_id = kiblnd_ptr2wreqid(tx, IBLND_WID_RDMA); - wrq->wr.sg_list = sge; - wrq->wr.num_sge = 1; - wrq->wr.opcode = IB_WR_RDMA_WRITE; - wrq->wr.send_flags = 0; + if (wrq_sge == 0) { + wrq = &tx->tx_wrq[tx->tx_nwrq]; - wrq->remote_addr = kiblnd_rd_frag_addr(dstrd, dstidx); - wrq->rkey = kiblnd_rd_frag_key(dstrd, dstidx); + wrq->wr.next = &(wrq + 1)->wr; + wrq->wr.wr_id = kiblnd_ptr2wreqid(tx, IBLND_WID_RDMA); + wrq->wr.sg_list = sge; + wrq->wr.opcode = IB_WR_RDMA_WRITE; + wrq->wr.send_flags = 0; - srcidx = kiblnd_rd_consume_frag(srcrd, srcidx, wrknob); - dstidx = kiblnd_rd_consume_frag(dstrd, dstidx, wrknob); + wrq->remote_addr = kiblnd_rd_frag_addr(dstrd, dstidx); + wrq->rkey = kiblnd_rd_frag_key(dstrd, dstidx); + } - resid -= wrknob; + srcidx = kiblnd_rd_consume_frag(srcrd, srcidx, sge_nob); + dstidx = kiblnd_rd_consume_frag(dstrd, dstidx, sge_nob); - tx->tx_nwrq++; - wrq++; - sge++; + wrq_sge++; + if (wrq_sge == *kiblnd_tunables.kib_wrq_sge || dstidx != prev) { + tx->tx_nwrq++; + wrq->wr.num_sge = wrq_sge; + wrq_sge = 0; + } + tx->tx_nsge++; } too_big: - if (rc < 0) /* no RDMA if completing with failure */ + if (rc < 0) { /* no RDMA if completing with failure */ + tx->tx_nsge = 0; tx->tx_nwrq = 0; + } ibmsg->ibm_u.completion.ibcm_status = rc; ibmsg->ibm_u.completion.ibcm_cookie = dstcookie; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index 5117594..891708e 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -147,6 +147,10 @@ module_param(use_privileged_port, int, 0644); MODULE_PARM_DESC(use_privileged_port, "use privileged port when initiating connection"); +static unsigned int wrq_sge = 1; +module_param(wrq_sge, uint, 0444); +MODULE_PARM_DESC(wrq_sge, "# scatter/gather element per work request"); + struct kib_tunables kiblnd_tunables = { .kib_dev_failover = &dev_failover, .kib_service = &service, @@ -160,7 +164,8 @@ struct kib_tunables kiblnd_tunables = { .kib_ib_mtu = &ib_mtu, .kib_require_priv_port = &require_privileged_port, .kib_use_priv_port = &use_privileged_port, - .kib_nscheds = &nscheds + .kib_nscheds = &nscheds, + .kib_wrq_sge = &wrq_sge, }; static struct lnet_ioctl_config_o2iblnd_tunables default_tunables; -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:16 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:16 -0400 Subject: [lustre-devel] [PATCH 24/25] lustre: socklnd: propagate errors on send failure In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-25-git-send-email-jsimmons@infradead.org> From: Olaf Weber When an attempt to send a message fails, for example because no connection could be established with the remote address, socklnd drops the message. For a PUT or REPLY message with non-zero payload, ksocknal_tx_done() calls lnet_finalize() with -EIO as the error code. But for an ACK or GET message there is no payload, and lnet_finalize() is called with 0 (no error) as the error code. This leaves upper layers to rely on other means to determine that sending the message did actually fail, and that (for example) no REPLY will ever answer a failed GET. Add an error code parameter to ksocknal_tx_done(). In ksocknal_txlist_done() change the 0/1 'error' indicator to be an actual error code that is passed on the ksocknal_tx_done(). Update the callers of ksocknal_txlist_done() to pass in the error code if they have encountered an error. Signed-off-by: Olaf Weber WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26691 Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c | 11 +++++++++-- drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h | 4 ++-- drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 15 +++++++-------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 1a49f5e..b2f0148 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -607,7 +607,7 @@ struct ksock_peer * write_unlock_bh(&ksocknal_data.ksnd_global_lock); - ksocknal_txlist_done(ni, &zombies, 1); + ksocknal_txlist_done(ni, &zombies, -ENETDOWN); return rc; } @@ -1023,6 +1023,7 @@ struct ksock_peer * int cpt; struct ksock_tx *tx; struct ksock_tx *txtmp; + int rc2; int rc; int active; char *warn = NULL; @@ -1406,7 +1407,13 @@ struct ksock_peer * write_unlock_bh(global_lock); } - ksocknal_txlist_done(ni, &zombies, 1); + /* + * If we get here without an error code, just use -EALREADY. + * Depending on how we got here, the error may be positive + * or negative. Normalize the value for ksocknal_txlist_done(). + */ + rc2 = (rc == 0 ? -EALREADY : (rc > 0 ? -rc : rc)); + ksocknal_txlist_done(ni, &zombies, rc2); ksocknal_peer_decref(peer_ni); failed_1: diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h index 95ca2aa..82e3523 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h @@ -582,14 +582,14 @@ struct ksock_proto { } void ksocknal_tx_prep(struct ksock_conn *, struct ksock_tx *tx); -void ksocknal_tx_done(struct lnet_ni *ni, struct ksock_tx *tx); +void ksocknal_tx_done(struct lnet_ni *ni, struct ksock_tx *tx, int error); static inline void ksocknal_tx_decref(struct ksock_tx *tx) { LASSERT(atomic_read(&tx->tx_refcount) > 0); if (atomic_dec_and_test(&tx->tx_refcount)) - ksocknal_tx_done(NULL, tx); + ksocknal_tx_done(NULL, tx, 0); } static inline void diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 73321a7..dc9a129 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -328,19 +328,18 @@ struct ksock_tx * } void -ksocknal_tx_done(struct lnet_ni *ni, struct ksock_tx *tx) +ksocknal_tx_done(struct lnet_ni *ni, struct ksock_tx *tx, int rc) { struct lnet_msg *lnetmsg = tx->tx_lnetmsg; - int rc = (!tx->tx_resid && !tx->tx_zc_aborted) ? 0 : -EIO; LASSERT(ni || tx->tx_conn); + if (!rc && (tx->tx_resid != 0 || tx->tx_zc_aborted)) + rc = -EIO; + if (tx->tx_conn) ksocknal_conn_decref(tx->tx_conn); - if (!ni && tx->tx_conn) - ni = tx->tx_conn->ksnc_peer->ksnp_ni; - ksocknal_free_tx(tx); if (lnetmsg) /* KSOCK_MSG_NOOP go without lnetmsg */ lnet_finalize(lnetmsg, rc); @@ -367,7 +366,7 @@ struct ksock_tx * list_del(&tx->tx_list); LASSERT(atomic_read(&tx->tx_refcount) == 1); - ksocknal_tx_done(ni, tx); + ksocknal_tx_done(ni, tx, error); } } @@ -1923,7 +1922,7 @@ void ksocknal_write_callback(struct ksock_conn *conn) write_unlock_bh(&ksocknal_data.ksnd_global_lock); ksocknal_peer_failed(peer_ni); - ksocknal_txlist_done(peer_ni->ksnp_ni, &zombies, 1); + ksocknal_txlist_done(peer_ni->ksnp_ni, &zombies, rc); return 0; } @@ -2268,7 +2267,7 @@ void ksocknal_write_callback(struct ksock_conn *conn) write_unlock_bh(&ksocknal_data.ksnd_global_lock); - ksocknal_txlist_done(peer_ni->ksnp_ni, &stale_txs, 1); + ksocknal_txlist_done(peer_ni->ksnp_ni, &stale_txs, -ETIMEDOUT); } static int -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:17 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:17 -0400 Subject: [lustre-devel] [PATCH 25/25] lustre: ko2iblnd: allow for discontiguous fragments In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-26-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" In the IOVEC case the buffers passed to the LND may not span complete pages, therefore the RDMA descriptor needs to describe all the buffers. Moreover for the FMR case, the addresses that get set in the RDMA descriptor need to be relative addresses. This issue was exposed after ko2iblnd was changed to handle the removal of ib_get_dma_mr() Fastreg still expects only one fragment with the total nob. Otherwise there is a dump_cqe error from MLX5 Signed-off-by: John L. Hammond Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9983 Reviewed-on: https://review.whamcloud.com/29290 Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index f2a01eb..b16153f 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -541,6 +541,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, bool is_fastreg = 0; int cpt; int rc; + int i; LASSERT(tx->tx_pool); LASSERT(tx->tx_pool->tpo_pool.po_owner); @@ -560,10 +561,15 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, * who will need the rkey */ rd->rd_key = tx->fmr.fmr_key; - if (!is_fastreg) - rd->rd_frags[0].rf_addr &= ~hdev->ibh_page_mask; - rd->rd_frags[0].rf_nob = nob; - rd->rd_nfrags = 1; + if (!is_fastreg) { + for (i = 0; i < rd->rd_nfrags; i++) { + rd->rd_frags[i].rf_addr &= ~hdev->ibh_page_mask; + rd->rd_frags[i].rf_addr += i << hdev->ibh_page_shift; + } + } else { + rd->rd_frags[0].rf_nob = nob; + rd->rd_nfrags = 1; + } return 0; } -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:47:58 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:47:58 -0400 Subject: [lustre-devel] [PATCH 06/25] lustre: lnet: loopback NID in lnet_select_pathway() In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-7-git-send-email-jsimmons@infradead.org> From: Olaf Weber In lnet_select_pathway() sending to the loopback NID is handled as a special case, because there are no credits involved. (The loopback NID doesn't use credits, and therefore does not have any credits. If a message goes through the credit-managing code it therefore ends up waiting indefinitely for credits to become available.) The check whether we're sending over the loopback NID must be done after we've completed choosing the NI to send over. In its present location it only handles the case where the loopback NID was explicitly passed in as the source NID. (Lustre does not exercise this code path during normal operation, the bug was encountered while testing code for the peer discovery feature.) Signed-off-by: Olaf Weber WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 Reviewed-on: https://review.whamcloud.com/26692 Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/lnet/lib-move.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index ea7e2c3..d533b8e 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1374,20 +1374,6 @@ } } - if (best_ni == the_lnet.ln_loni) { - /* No send credit hassles with LOLND */ - lnet_ni_addref_locked(best_ni, cpt); - msg->msg_hdr.dest_nid = cpu_to_le64(best_ni->ni_nid); - if (!msg->msg_routing) - msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); - msg->msg_target.nid = best_ni->ni_nid; - lnet_msg_commit(msg, cpt); - msg->msg_txni = best_ni; - lnet_net_unlock(cpt); - - return LNET_CREDIT_OK; - } - /* * if we already found a best_ni because src_nid is specified and * best_lpni because we are replying to a message then just send @@ -1630,6 +1616,21 @@ } send: + /* Shortcut for loopback. */ + if (best_ni == the_lnet.ln_loni) { + /* No send credit hassles with LOLND */ + lnet_ni_addref_locked(best_ni, cpt); + msg->msg_hdr.dest_nid = cpu_to_le64(best_ni->ni_nid); + if (!msg->msg_routing) + msg->msg_hdr.src_nid = cpu_to_le64(best_ni->ni_nid); + msg->msg_target.nid = best_ni->ni_nid; + lnet_msg_commit(msg, cpt); + msg->msg_txni = best_ni; + lnet_net_unlock(cpt); + + return LNET_CREDIT_OK; + } + routing = routing || routing2; /* -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:01 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:01 -0400 Subject: [lustre-devel] [PATCH 09/25] lustre: lnet: prevent assert on ln_state In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-10-git-send-email-jsimmons@infradead.org> From: Amir Shehata lnet_peer_primary_nid() is called from lnet_parse. It checks ln_state outside the net lock, causing a race condition during shutdown where the code expects the state to be running, but it's stopping or shutdown. Fixed the issue by renaming lnet_peer_primary_nid() to lnet_peer_primary_nid_locked(). This function is now called when lnet_net_lock is held in lnet_parse(). In lnet_create_reply_msg() we already have access to the msg_txpeer, so we lookup the primary_nid directly Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9549 Reviewed-on: https://review.whamcloud.com/27262 Reviewed-by: Doug Oucharek Reviewed-by: Sonia Sharma Reviewed-by: Olaf Weber Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/include/linux/lnet/lib-lnet.h | 2 +- drivers/staging/lustre/lnet/lnet/lib-move.c | 7 +++---- drivers/staging/lustre/lnet/lnet/peer.c | 5 +---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index f510b9e..6bfdc9b 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -653,7 +653,7 @@ struct lnet_peer_ni *lnet_get_next_peer_ni_locked(struct lnet_peer *peer, struct lnet_peer_ni *lnet_nid2peerni_ex(lnet_nid_t nid, int cpt); struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid); void lnet_peer_net_added(struct lnet_net *net); -lnet_nid_t lnet_peer_primary_nid(lnet_nid_t nid); +lnet_nid_t lnet_peer_primary_nid_locked(lnet_nid_t nid); void lnet_peer_tables_cleanup(struct lnet_net *net); void lnet_peer_uninit(void); int lnet_peer_tables_create(void); diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index d533b8e..2cf9c89 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -2338,8 +2338,6 @@ msg->msg_hdr.dest_pid = dest_pid; msg->msg_hdr.payload_length = payload_length; } - /* Multi-Rail: Primary NID of source. */ - msg->msg_initiator = lnet_peer_primary_nid(src_nid); lnet_net_lock(cpt); lpni = lnet_nid2peerni_locked(from_nid, cpt); @@ -2357,6 +2355,8 @@ msg->msg_rxpeer = lpni; msg->msg_rxni = ni; lnet_ni_addref_locked(ni, cpt); + /* Multi-Rail: Primary NID of source. */ + msg->msg_initiator = lnet_peer_primary_nid_locked(src_nid); if (lnet_isrouter(msg->msg_rxpeer)) { lnet_peer_set_alive(msg->msg_rxpeer); @@ -2658,8 +2658,7 @@ struct lnet_msg * libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id), getmd); /* setup information for lnet_build_msg_event */ - msg->msg_initiator = lnet_peer_primary_nid(peer_id.nid); - /* Cheaper: msg->msg_initiator = getmsg->msg_txpeer->lp_nid; */ + msg->msg_initiator = getmsg->msg_txpeer->lpni_peer_net->lpn_peer->lp_primary_nid; msg->msg_from = peer_id.nid; msg->msg_type = LNET_MSG_GET; /* flag this msg as an "optimized" GET */ msg->msg_hdr.src_nid = peer_id.nid; diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 2fbf93a..ebb8435 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -593,19 +593,16 @@ struct lnet_peer_ni * } lnet_nid_t -lnet_peer_primary_nid(lnet_nid_t nid) +lnet_peer_primary_nid_locked(lnet_nid_t nid) { struct lnet_peer_ni *lpni; lnet_nid_t primary_nid = nid; - int cpt; - cpt = lnet_net_lock_current(); lpni = lnet_find_peer_ni_locked(nid); if (lpni) { primary_nid = lpni->lpni_peer_net->lpn_peer->lp_primary_nid; lnet_peer_ni_decref_locked(lpni); } - lnet_net_unlock(cpt); return primary_nid; } -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:13 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:13 -0400 Subject: [lustre-devel] [PATCH 21/25] lustre: lnet: set LND tunables properly In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-22-git-send-email-jsimmons@infradead.org> From: Amir Shehata Make sure to set all NIs to the proper LND tunables specified. Add ntx tunable to dynamic configuration. This way all tunables required to tune OPA performance can be configured via lnetctl, allowing the ability to tune OPA network and IB network differently Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9536 Reviewed-on: https://review.whamcloud.com/27263 Reviewed-by: Doug Oucharek Reviewed-by: Sonia Sharma Reviewed-by: Olaf Weber Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h | 2 +- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 14 +++++++++----- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 4 +++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h index 07516fd..8f03aa3 100644 --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h @@ -66,7 +66,7 @@ struct lnet_ioctl_config_o2iblnd_tunables { __u32 lnd_fmr_flush_trigger; __u32 lnd_fmr_cache; __u16 lnd_conns_per_peer; - __u16 pad; + __u16 lnd_ntx; }; struct lnet_lnd_tunables { diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 0ce9962..50c0c00 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -2034,9 +2034,13 @@ static void kiblnd_destroy_tx_pool(struct kib_pool *pool) kfree(tpo); } -static int kiblnd_tx_pool_size(int ncpts) +static int kiblnd_tx_pool_size(struct lnet_ni *ni, int ncpts) { - int ntx = *kiblnd_tunables.kib_ntx / ncpts; + struct lnet_ioctl_config_o2iblnd_tunables *tunables; + int ntx; + + tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; + ntx = tunables->lnd_ntx / ncpts; return max(IBLND_TX_POOL, ntx); } @@ -2176,10 +2180,10 @@ static int kiblnd_net_init_pools(struct kib_net *net, struct lnet_ni *ni, tunables = &ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib; - if (tunables->lnd_fmr_pool_size < *kiblnd_tunables.kib_ntx / 4) { + if (tunables->lnd_fmr_pool_size < tunables->lnd_ntx / 4) { CERROR("Can't set fmr pool size (%d) < ntx / 4(%d)\n", tunables->lnd_fmr_pool_size, - *kiblnd_tunables.kib_ntx / 4); + tunables->lnd_ntx / 4); rc = -EINVAL; goto failed; } @@ -2237,7 +2241,7 @@ static int kiblnd_net_init_pools(struct kib_net *net, struct lnet_ni *ni, cpt = !cpts ? i : cpts[i]; rc = kiblnd_init_poolset(&net->ibn_tx_ps[cpt]->tps_poolset, cpt, net, "TX", - kiblnd_tx_pool_size(ncpts), + kiblnd_tx_pool_size(ni, ncpts), kiblnd_create_tx_pool, kiblnd_destroy_tx_pool, kiblnd_tx_init, NULL); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index 3bb537e..0f2ad91 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -157,7 +157,6 @@ struct kib_tunables kiblnd_tunables = { .kib_cksum = &cksum, .kib_timeout = &timeout, .kib_keepalive = &keepalive, - .kib_ntx = &ntx, .kib_default_ipif = &ipif_name, .kib_retry_count = &retry_count, .kib_rnr_retry_count = &rnr_retry_count, @@ -282,6 +281,8 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) tunables->lnd_fmr_flush_trigger = fmr_flush_trigger; if (!tunables->lnd_fmr_cache) tunables->lnd_fmr_cache = fmr_cache; + if (!tunables->lnd_ntx) + tunables->lnd_ntx = ntx; if (!tunables->lnd_conns_per_peer) { tunables->lnd_conns_per_peer = (conns_per_peer) ? conns_per_peer : 1; @@ -299,5 +300,6 @@ void kiblnd_tunables_init(void) default_tunables.lnd_fmr_pool_size = fmr_pool_size; default_tunables.lnd_fmr_flush_trigger = fmr_flush_trigger; default_tunables.lnd_fmr_cache = fmr_cache; + default_tunables.lnd_ntx = ntx; default_tunables.lnd_conns_per_peer = conns_per_peer; } -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:07 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:07 -0400 Subject: [lustre-devel] [PATCH 15/25] lustre: o2iblnd: reconnect peer for REJ_INVALID_SERVICE_ID In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-16-git-send-email-jsimmons@infradead.org> From: Sergey Cheremencev Don't kill the peer in case of INVALID_SERVICE_ID. This produces huge number of peers for the same nid and may cause an OOM. The OOM was frequently seen with mlnx-ofa-kernel-2.3 where used RCU mechanism in mlx4_cq_free. In older mlnx4 versions to mitigate the issue RCU was changed with spin locks. Signed-off-by: Sergey Cheremencev WC-bug-id: https://jira.whamcloud.com/browse/LU-9094 Seagate-bug-id: MRP-4056 Reviewed-on: https://review.whamcloud.com/25378 Reviewed-by: Doug Oucharek Reviewed-by: Amir Shehata Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 1 + drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index a3d89ec..de04355 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -460,6 +460,7 @@ struct kib_rej { #define IBLND_REJECT_RDMA_FRAGS 6 /* peer_ni's msg queue size doesn't match mine */ #define IBLND_REJECT_MSG_QUEUE_SIZE 7 +#define IBLND_REJECT_INVALID_SRV_ID 8 /***********************************************************************/ diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index a6b261a..dc71554 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -2611,6 +2611,10 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, case IBLND_REJECT_CONN_UNCOMPAT: reason = "version negotiation"; break; + + case IBLND_REJECT_INVALID_SRV_ID: + reason = "invalid service id"; + break; } conn->ibc_reconnect = 1; @@ -2648,6 +2652,8 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, break; case IB_CM_REJ_INVALID_SERVICE_ID: + kiblnd_check_reconnect(conn, IBLND_MSG_VERSION, 0, + IBLND_REJECT_INVALID_SRV_ID, NULL); CNETERR("%s rejected: no listener at %d\n", libcfs_nid2str(peer_ni->ibp_nid), *kiblnd_tunables.kib_service); -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:15 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:15 -0400 Subject: [lustre-devel] [PATCH 23/25] lustre: lnd: pending transmits dropped silently In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-24-git-send-email-jsimmons@infradead.org> From: Amir Shehata list_add was being used erroneously. The logic should be to move the txs on ibp_tx_queue on a local list which is then processed. The code, however, did the reverse, which would result in the pending txs not processed and thus dropped silently. This in turn would lead to peers reference counts at the LNet layer not decremented since lnet_finalize() might not be called for a message. Initialize local list and use list_splice_init() to move transmits on the ibp_tx_queue to the local list. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-10682 Reviewed-on: https://review.whamcloud.com/31374 Reviewed-by: Doug Oucharek Reviewed-by: Sonia Sharma Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 346d368..f2a01eb 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -2150,8 +2150,8 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, } /* grab pending txs while I have the lock */ - list_add(&txs, &peer_ni->ibp_tx_queue); - list_del_init(&peer_ni->ibp_tx_queue); + INIT_LIST_HEAD(&txs); + list_splice_init(&peer_ni->ibp_tx_queue, &txs); if (!kiblnd_peer_active(peer_ni) || /* peer_ni has been deleted */ conn->ibc_comms_error) { /* error has happened already */ -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:03 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:03 -0400 Subject: [lustre-devel] [PATCH 11/25] lustre: lnet: Fix lost lock In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-12-git-send-email-jsimmons@infradead.org> From: Dmitry Eremin Unlock lnet_net_lock in case of error in function lnet_select_pathway(). Signed-off-by: Dmitry Eremin WC-bug-id: https://jira.whamcloud.com/browse/LU-9607 Reviewed-on: https://review.whamcloud.com/27455 Reviewed-by: Doug Oucharek Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/lnet/lib-move.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 275e8a9..f2bc97d 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -1260,6 +1260,7 @@ } if (!peer->lp_multi_rail && lnet_get_num_peer_nis(peer) > 1) { + lnet_net_unlock(cpt); CERROR("peer %s is declared to be non MR capable, yet configured with more than one NID\n", libcfs_nid2str(dst_nid)); return -EINVAL; -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:04 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:04 -0400 Subject: [lustre-devel] [PATCH 12/25] lustre: lnet: correct locking in legacy add net In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-13-git-send-email-jsimmons@infradead.org> From: Amir Shehata Make sure to unlock the api mutex properly in lnet_dyn_add_net() Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9729 Reviewed-on: https://review.whamcloud.com/27907 Reviewed-by: Olaf Weber Reviewed-by: Sonia Sharma Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/lnet/api-ni.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 7c907a3..b37abde 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -2435,7 +2435,7 @@ int lnet_dyn_del_ni(struct lnet_ioctl_config_ni *conf) if (rc > 1) { rc = -EINVAL; /* only add one network per call */ - goto failed; + goto out_unlock_clean; } net = list_entry(net_head.next, struct lnet_net, net_list); @@ -2455,14 +2455,11 @@ int lnet_dyn_del_ni(struct lnet_ioctl_config_ni *conf) conf->cfg_config_u.cfg_net.net_max_tx_credits; rc = lnet_add_net_common(net, &tun); - if (rc != 0) - goto failed; - return 0; - -failed: +out_unlock_clean: mutex_unlock(&the_lnet.ln_api_mutex); while (!list_empty(&net_head)) { + /* net_head list is empty in success case */ net = list_entry(net_head.next, struct lnet_net, net_list); list_del_init(&net->net_list); lnet_net_free(net); -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:06 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:06 -0400 Subject: [lustre-devel] [PATCH 14/25] lustre: lnet: safe access to msg In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-15-git-send-email-jsimmons@infradead.org> From: Amir Shehata When tx credits are returned if there are pending messages they need to be sent. Messages could have different tx_cpts, so the correct one needs to be locked. After lnet_post_send_locked(), if we locked a different CPT then we need to relock the correct one However, as part of lnet_post_send_locked(), lnet_finalze() can be called which can free the message. Therefore, the cpt of the message being passed must be cached in order to prevent access to freed memory. Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9817 Reviewed-on: https://review.whamcloud.com/28308 Reviewed-by: Olaf Weber Reviewed-by: Sonia Sharma Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/lnet/lib-move.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 4d74421..e8c0216 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -847,6 +847,8 @@ txpeer->lpni_txcredits++; if (txpeer->lpni_txcredits <= 0) { + int msg2_cpt; + msg2 = list_entry(txpeer->lpni_txq.next, struct lnet_msg, msg_list); list_del(&msg2->msg_list); @@ -855,13 +857,26 @@ LASSERT(msg2->msg_txpeer == txpeer); LASSERT(msg2->msg_tx_delayed); - if (msg2->msg_tx_cpt != msg->msg_tx_cpt) { + msg2_cpt = msg2->msg_tx_cpt; + + /* + * The msg_cpt can be different from the msg2_cpt + * so we need to make sure we lock the correct cpt + * for msg2. + * Once we call lnet_post_send_locked() it is no + * longer safe to access msg2, since it could've + * been freed by lnet_finalize(), but we still + * need to relock the correct cpt, so we cache the + * msg2_cpt for the purpose of the check that + * follows the call to lnet_pose_send_locked(). + */ + if (msg2_cpt != msg->msg_tx_cpt) { lnet_net_unlock(msg->msg_tx_cpt); - lnet_net_lock(msg2->msg_tx_cpt); + lnet_net_lock(msg2_cpt); } (void)lnet_post_send_locked(msg2, 1); - if (msg2->msg_tx_cpt != msg->msg_tx_cpt) { - lnet_net_unlock(msg2->msg_tx_cpt); + if (msg2_cpt != msg->msg_tx_cpt) { + lnet_net_unlock(msg2_cpt); lnet_net_lock(msg->msg_tx_cpt); } } else { -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:10 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:10 -0400 Subject: [lustre-devel] [PATCH 18/25] lustre: lnd: Turn on 2 sges by default In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-19-git-send-email-jsimmons@infradead.org> From: Doug Oucharek Currently, the fix in LU-5718 which allows for multiple sges to deal with RDMA fragmentation is turned off by default (set to 1). This patch changes the default to 2 so RDMA fragmentation is fixed by default. Signed-off-by: Doug Oucharek WC-bug-id: https://jira.whamcloud.com/browse/LU-9425 Reviewed-on: https://review.whamcloud.com/26911 Reviewed-by: Ned Bass Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index 891708e..3bb537e 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -147,7 +147,7 @@ module_param(use_privileged_port, int, 0644); MODULE_PARM_DESC(use_privileged_port, "use privileged port when initiating connection"); -static unsigned int wrq_sge = 1; +static unsigned int wrq_sge = 2; module_param(wrq_sge, uint, 0444); MODULE_PARM_DESC(wrq_sge, "# scatter/gather element per work request"); -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:12 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:12 -0400 Subject: [lustre-devel] [PATCH 20/25] lustre: lnet: handle empty CPTs In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-21-git-send-email-jsimmons@infradead.org> From: Amir Shehata Make the LND code handle empty CPTs. If a scheduler is associated with an empty CPT it will have no threads created. If a NID hashes to that CPT, then pick the next scheduler which does have at least 1 started thread. Associate the connection with the CPT of the selected scheduler Signed-off-by: Amir Shehata WC-bug-id: https://jira.whamcloud.com/browse/LU-9448 Reviewed-on: https://review.whamcloud.com/27145 Reviewed-by: Doug Oucharek Reviewed-by: Dmitry Eremin Reviewed-by: Olaf Weber Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 42 ++++++++++++++++++++-- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 25 ++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 9e8248e..0ce9962 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -622,6 +622,36 @@ static int kiblnd_get_completion_vector(struct kib_conn *conn, int cpt) return 1; } +/* + * Get the scheduler bound to this CPT. If the scheduler has no + * threads, which means that the CPT has no CPUs, then grab the + * next scheduler that we can use. + * + * This case would be triggered if a NUMA node is configured with + * no associated CPUs. + */ +static struct kib_sched_info *kiblnd_get_scheduler(int cpt) +{ + struct kib_sched_info *sched; + int i; + + sched = kiblnd_data.kib_scheds[cpt]; + + if (sched->ibs_nthreads > 0) + return sched; + + cfs_percpt_for_each(sched, i, kiblnd_data.kib_scheds) { + if (sched->ibs_nthreads > 0) { + CDEBUG(D_NET, + "scheduler[%d] has no threads. selected scheduler[%d]\n", + cpt, sched->ibs_cpt); + return sched; + } + } + + return NULL; +} + struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, struct rdma_cm_id *cmid, int state, int version) @@ -656,9 +686,17 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, dev = net->ibn_dev; cpt = lnet_cpt_of_nid(peer_ni->ibp_nid, peer_ni->ibp_ni); - sched = kiblnd_data.kib_scheds[cpt]; + sched = kiblnd_get_scheduler(cpt); + if (!sched) { + CERROR("no schedulers available. node is unhealthy\n"); + goto failed_0; + } - LASSERT(sched->ibs_nthreads > 0); + /* + * The cpt might have changed if we ended up selecting a non cpt + * native scheduler. So use the scheduler's cpt instead. + */ + cpt = sched->ibs_cpt; init_qp_attr = kzalloc_cpt(sizeof(*init_qp_attr), GFP_NOFS, cpt); if (!init_qp_attr) { diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index ad94837..1a49f5e 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -652,8 +652,19 @@ struct ksock_peer * struct ksock_sched *sched; int i; - LASSERT(info->ksi_nthreads > 0); + if (info->ksi_nthreads == 0) { + cfs_percpt_for_each(info, i, ksocknal_data.ksnd_sched_info) { + if (info->ksi_nthreads > 0) { + CDEBUG(D_NET, + "scheduler[%d] has no threads. selected scheduler[%d]\n", + cpt, info->ksi_cpt); + goto select_sched; + } + } + return NULL; + } +select_sched: sched = &info->ksi_scheds[0]; /* * NB: it's safe so far, but info->ksi_nthreads could be changed @@ -1255,6 +1266,15 @@ struct ksock_peer * peer_ni->ksnp_error = 0; sched = ksocknal_choose_scheduler_locked(cpt); + if (!sched) { + CERROR("no schedulers available. node is unhealthy\n"); + goto failed_2; + } + /* + * The cpt might have changed if we ended up selecting a non cpt + * native scheduler. So use the scheduler's cpt instead. + */ + cpt = sched->kss_info->ksi_cpt; sched->kss_nconns++; conn->ksnc_scheduler = sched; @@ -2402,6 +2422,9 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) info->ksi_nthreads_max = nthrs; info->ksi_cpt = i; + if (nthrs == 0) + continue; + info->ksi_scheds = kzalloc_cpt(info->ksi_nthreads_max * sizeof(*sched), GFP_NOFS, i); if (!info->ksi_scheds) -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:14 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:14 -0400 Subject: [lustre-devel] [PATCH 22/25] lustre: lnd: Don't Page Align remote_addr with FastReg In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-23-git-send-email-jsimmons@infradead.org> From: Doug Oucharek Trying to page align the remote_addr for IB_RDMA_WRITE work requests is triggering "dump_cqe" errors from MOFED 4.x + mlx5. This patch removes the address masking we were doing with FastReg which was trying to page align remote_addr values. I am also removing the setting of "mr->iova" with FastReg as this is being done in the call to ib_map_mr_sg() and could cause problems. Signed-off-by: Doug Oucharek WC-bug-id: https://jira.whamcloud.com/browse/LU-9500 Reviewed-on: https://review.whamcloud.com/27149 Reviewed-by: Gu Zheng Reviewed-by: Dmitry Eremin Reviewed-by: Amir Shehata Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 6 +++--- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 2 +- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 50c0c00..c207663 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -1651,7 +1651,7 @@ void kiblnd_fmr_pool_unmap(struct kib_fmr *fmr, int status) int kiblnd_fmr_pool_map(struct kib_fmr_poolset *fps, struct kib_tx *tx, struct kib_rdma_desc *rd, __u32 nob, __u64 iov, - struct kib_fmr *fmr) + struct kib_fmr *fmr, bool *is_fastreg) { __u64 *pages = tx->tx_pages; bool is_rx = (rd != tx->tx_rd); @@ -1671,6 +1671,7 @@ int kiblnd_fmr_pool_map(struct kib_fmr_poolset *fps, struct kib_tx *tx, if (fpo->fpo_is_fmr) { struct ib_pool_fmr *pfmr; + *is_fastreg = 0; spin_unlock(&fps->fps_lock); if (!tx_pages_mapped) { @@ -1690,6 +1691,7 @@ int kiblnd_fmr_pool_map(struct kib_fmr_poolset *fps, struct kib_tx *tx, } rc = PTR_ERR(pfmr); } else { + *is_fastreg = 1; if (!list_empty(&fpo->fast_reg.fpo_pool_list)) { struct kib_fast_reg_descriptor *frd; struct ib_reg_wr *wr; @@ -1727,8 +1729,6 @@ int kiblnd_fmr_pool_map(struct kib_fmr_poolset *fps, struct kib_tx *tx, return n < 0 ? n : -EINVAL; } - mr->iova = iov; - /* Prepare FastReg WR */ wr = &frd->frd_fastreg_wr; memset(wr, 0, sizeof(*wr)); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index f21bdee..a4438d2 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -1003,7 +1003,7 @@ static inline unsigned int kiblnd_sg_dma_len(struct ib_device *dev, int kiblnd_fmr_pool_map(struct kib_fmr_poolset *fps, struct kib_tx *tx, struct kib_rdma_desc *rd, __u32 nob, __u64 iov, - struct kib_fmr *fmr); + struct kib_fmr *fmr, bool *is_fastreg); void kiblnd_fmr_pool_unmap(struct kib_fmr *fmr, int status); int kiblnd_tunables_setup(struct lnet_ni *ni); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index db563c0..346d368 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -538,6 +538,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, { struct kib_hca_dev *hdev; struct kib_fmr_poolset *fps; + bool is_fastreg = 0; int cpt; int rc; @@ -548,7 +549,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, cpt = tx->tx_pool->tpo_pool.po_owner->ps_cpt; fps = net->ibn_fmr_ps[cpt]; - rc = kiblnd_fmr_pool_map(fps, tx, rd, nob, 0, &tx->fmr); + rc = kiblnd_fmr_pool_map(fps, tx, rd, nob, 0, &tx->fmr, &is_fastreg); if (rc) { CERROR("Can't map %u bytes: %d\n", nob, rc); return rc; @@ -559,7 +560,8 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, * who will need the rkey */ rd->rd_key = tx->fmr.fmr_key; - rd->rd_frags[0].rf_addr &= ~hdev->ibh_page_mask; + if (!is_fastreg) + rd->rd_frags[0].rf_addr &= ~hdev->ibh_page_mask; rd->rd_frags[0].rf_nob = nob; rd->rd_nfrags = 1; -- 1.8.3.1 From jsimmons at infradead.org Wed Sep 26 02:48:11 2018 From: jsimmons at infradead.org (James Simmons) Date: Tue, 25 Sep 2018 22:48:11 -0400 Subject: [lustre-devel] [PATCH 19/25] lustre: lnd: Don't Assert On Reconnect with MultiQP In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <1537930097-11624-20-git-send-email-jsimmons@infradead.org> From: Doug Oucharek The work from LU-8943 activated the ability to have multiple connections between peers. If any of those connections need to be reconnected (i.e. parameter renegotiation), we were getting an assert from kiblnd_reconnect_peer() which was not changed to allow for having multiple connections ongoing at the same time. This patch gets rid of the assert from kiblnd_reconnect_peer() which is no longer valid after LU-8943. Signed-off-by: Doug Oucharek WC-bug-id: https://jira.whamcloud.com/browse/LU-9507 Reviewed-on: https://review.whamcloud.com/27139 Reviewed-by: Amir Shehata Reviewed-by: James Simmons Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 80398c1..db563c0 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1303,8 +1303,8 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, goto no_reconnect; } - LASSERT(!peer_ni->ibp_accepting && !peer_ni->ibp_connecting && - list_empty(&peer_ni->ibp_conns)); + if (peer_ni->ibp_accepting) + CNETERR("Detecting race between accepting and reconnecting\n"); peer_ni->ibp_reconnecting--; if (!kiblnd_peer_active(peer_ni)) { -- 1.8.3.1 From neilb at suse.com Wed Sep 26 23:57:40 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 09:57:40 +1000 Subject: [lustre-devel] [PATCH 01/25] lustre: lnet: remove ni from lnet_finalize In-Reply-To: <1537930097-11624-2-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> <1537930097-11624-2-git-send-email-jsimmons@infradead.org> Message-ID: <875zyrizgr.fsf@notabene.neil.brown.name> On Tue, Sep 25 2018, James Simmons wrote: > From: Sergey Cheremencev > > Remove ni from lnet_finalize and kiblnd_txlist_done > input arguments. Also small code cleanup by introducing > ibprm_cookie to avoid checkpatch issues. What checkpatch issues are avoided ?? Thanks, NeilBrown > > Signed-off-by: Sergey Cheremencev > WC-bug-id: https://jira.whamcloud.com/browse/LU-9094 > Seagate-bug-id: MRP-4056 > Reviewed-on: https://review.whamcloud.com/25375 > Reviewed-by: Doug Oucharek > Reviewed-by: Amir Shehata > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 2 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 3 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 65 ++++++++++------------ > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 3 +- > .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 4 +- > drivers/staging/lustre/lnet/lnet/lib-move.c | 20 +++---- > drivers/staging/lustre/lnet/lnet/lib-msg.c | 2 +- > drivers/staging/lustre/lnet/lnet/lo.c | 4 +- > drivers/staging/lustre/lnet/lnet/net_fault.c | 2 +- > 10 files changed, 50 insertions(+), 57 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index aedc88c..53cbf6d 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -537,7 +537,7 @@ struct lnet_msg *lnet_create_reply_msg(struct lnet_ni *ni, > void lnet_set_reply_msg_len(struct lnet_ni *ni, struct lnet_msg *msg, > unsigned int len); > > -void lnet_finalize(struct lnet_ni *ni, struct lnet_msg *msg, int rc); > +void lnet_finalize(struct lnet_msg *msg, int rc); > > void lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, > unsigned int nob); > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index 75a7e96..b3a4344 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -521,7 +521,7 @@ static int kiblnd_del_peer(struct lnet_ni *ni, lnet_nid_t nid) > > write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); > > - kiblnd_txlist_done(ni, &zombies, -EIO); > + kiblnd_txlist_done(&zombies, -EIO); > > return rc; > } > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h > index b1851b5..a3d89ec 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h > @@ -1034,8 +1034,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, > void kiblnd_close_conn_locked(struct kib_conn *conn, int error); > > void kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid); > -void kiblnd_txlist_done(struct lnet_ni *ni, struct list_head *txlist, > - int status); > +void kiblnd_txlist_done(struct list_head *txlist, int status); > > void kiblnd_qp_event(struct ib_event *event, void *arg); > void kiblnd_cq_event(struct ib_event *event, void *arg); > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > index cb752dc..debed17 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > @@ -54,14 +54,12 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > static void kiblnd_check_sends_locked(struct kib_conn *conn); > > static void > -kiblnd_tx_done(struct lnet_ni *ni, struct kib_tx *tx) > +kiblnd_tx_done(struct kib_tx *tx) > { > struct lnet_msg *lntmsg[2]; > - struct kib_net *net = ni->ni_data; > int rc; > int i; > > - LASSERT(net); > LASSERT(!in_interrupt()); > LASSERT(!tx->tx_queued); /* mustn't be queued for sending */ > LASSERT(!tx->tx_sending); /* mustn't be awaiting sent callback */ > @@ -76,8 +74,6 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > rc = tx->tx_status; > > if (tx->tx_conn) { > - LASSERT(ni == tx->tx_conn->ibc_peer->ibp_ni); > - > kiblnd_conn_decref(tx->tx_conn); > tx->tx_conn = NULL; > } > @@ -92,12 +88,12 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > if (!lntmsg[i]) > continue; > > - lnet_finalize(ni, lntmsg[i], rc); > + lnet_finalize(lntmsg[i], rc); > } > } > > void > -kiblnd_txlist_done(struct lnet_ni *ni, struct list_head *txlist, int status) > +kiblnd_txlist_done(struct list_head *txlist, int status) > { > struct kib_tx *tx; > > @@ -108,7 +104,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > /* complete now */ > tx->tx_waiting = 0; > tx->tx_status = status; > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > } > } > > @@ -281,7 +277,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > spin_unlock(&conn->ibc_lock); > > if (idle) > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > } > > static void > @@ -794,7 +790,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, > * posted NOOPs complete > */ > spin_unlock(&conn->ibc_lock); > - kiblnd_tx_done(peer_ni->ibp_ni, tx); > + kiblnd_tx_done(tx); > spin_lock(&conn->ibc_lock); > CDEBUG(D_NET, "%s(%d): redundant or enough NOOP\n", > libcfs_nid2str(peer_ni->ibp_nid), > @@ -888,7 +884,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, > kiblnd_close_conn(conn, rc); > > if (done) > - kiblnd_tx_done(peer_ni->ibp_ni, tx); > + kiblnd_tx_done(tx); > > spin_lock(&conn->ibc_lock); > > @@ -1007,7 +1003,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, > spin_unlock(&conn->ibc_lock); > > if (idle) > - kiblnd_tx_done(conn->ibc_peer->ibp_ni, tx); > + kiblnd_tx_done(tx); > } > > static void > @@ -1343,7 +1339,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > CWARN("Abort reconnection of %s: %s\n", > libcfs_nid2str(peer_ni->ibp_nid), reason); > - kiblnd_txlist_done(peer_ni->ibp_ni, &txs, -ECONNABORTED); > + kiblnd_txlist_done(&txs, -ECONNABORTED); > return false; > } > > @@ -1421,7 +1417,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > if (tx) { > tx->tx_status = -EHOSTUNREACH; > tx->tx_waiting = 0; > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > } > return; > } > @@ -1557,7 +1553,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > if (rc) { > CERROR("Can't setup GET sink for %s: %d\n", > libcfs_nid2str(target.nid), rc); > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > return -EIO; > } > > @@ -1571,7 +1567,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > if (!tx->tx_lntmsg[1]) { > CERROR("Can't create reply for GET -> %s\n", > libcfs_nid2str(target.nid)); > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > return -EIO; > } > > @@ -1606,7 +1602,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > if (rc) { > CERROR("Can't setup PUT src for %s: %d\n", > libcfs_nid2str(target.nid), rc); > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > return -EIO; > } > > @@ -1697,7 +1693,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > if (!nob) { > /* No RDMA: local completion may happen now! */ > - lnet_finalize(ni, lntmsg, 0); > + lnet_finalize(lntmsg, 0); > } else { > /* RDMA: lnet_finalize(lntmsg) when it completes */ > tx->tx_lntmsg[0] = lntmsg; > @@ -1707,9 +1703,9 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > return; > > failed_1: > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > failed_0: > - lnet_finalize(ni, lntmsg, -EIO); > + lnet_finalize(lntmsg, -EIO); > } > > int > @@ -1722,6 +1718,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > struct kib_tx *tx; > int nob; > int post_credit = IBLND_POSTRX_PEER_CREDIT; > + u64 ibprm_cookie; > int rc = 0; > > LASSERT(iov_iter_count(to) <= rlen); > @@ -1750,17 +1747,18 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > } > > rc = 0; > - lnet_finalize(ni, lntmsg, 0); > + lnet_finalize(lntmsg, 0); > break; > > case IBLND_MSG_PUT_REQ: { > + u64 ibprm_cookie = rxmsg->ibm_u.putreq.ibprm_cookie; > struct kib_msg *txmsg; > struct kib_rdma_desc *rd; > > if (!iov_iter_count(to)) { > - lnet_finalize(ni, lntmsg, 0); > - kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, 0, > - rxmsg->ibm_u.putreq.ibprm_cookie); > + lnet_finalize(lntmsg, 0); > + kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, > + 0, ibprm_cookie); > break; > } > > @@ -1788,15 +1786,15 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > if (rc) { > CERROR("Can't setup PUT sink for %s: %d\n", > libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); > - kiblnd_tx_done(ni, tx); > + kiblnd_tx_done(tx); > /* tell peer_ni it's over */ > - kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, rc, > - rxmsg->ibm_u.putreq.ibprm_cookie); > + kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, > + rc, ibprm_cookie); > break; > } > > nob = offsetof(struct kib_putack_msg, ibpam_rd.rd_frags[rd->rd_nfrags]); > - txmsg->ibm_u.putack.ibpam_src_cookie = rxmsg->ibm_u.putreq.ibprm_cookie; > + txmsg->ibm_u.putack.ibpam_src_cookie = ibprm_cookie; > txmsg->ibm_u.putack.ibpam_dst_cookie = tx->tx_cookie; > > kiblnd_init_tx_msg(ni, tx, IBLND_MSG_PUT_ACK, nob); > @@ -1817,8 +1815,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > } else { > /* GET didn't match anything */ > kiblnd_send_completion(rx->rx_conn, IBLND_MSG_GET_DONE, > - -ENODATA, > - rxmsg->ibm_u.get.ibgm_cookie); > + -ENODATA, ibprm_cookie); > } > break; > } > @@ -2016,7 +2013,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > spin_unlock(&conn->ibc_lock); > > - kiblnd_txlist_done(conn->ibc_peer->ibp_ni, &zombies, -ECONNABORTED); > + kiblnd_txlist_done(&zombies, -ECONNABORTED); > } > > static void > @@ -2098,7 +2095,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > CNETERR("Deleting messages for %s: connection failed\n", > libcfs_nid2str(peer_ni->ibp_nid)); > > - kiblnd_txlist_done(peer_ni->ibp_ni, &zombies, -EHOSTUNREACH); > + kiblnd_txlist_done(&zombies, -EHOSTUNREACH); > } > > static void > @@ -2170,13 +2167,11 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > if (!kiblnd_peer_active(peer_ni) || /* peer_ni has been deleted */ > conn->ibc_comms_error) { /* error has happened already */ > - struct lnet_ni *ni = peer_ni->ibp_ni; > - > /* start to shut down connection */ > kiblnd_close_conn_locked(conn, -ECONNABORTED); > write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); > > - kiblnd_txlist_done(ni, &txs, -ECONNABORTED); > + kiblnd_txlist_done(&txs, -ECONNABORTED); > > return; > } > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 534ba84..9b9cc87 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -1653,8 +1653,7 @@ struct ksock_peer * > &conn->ksnc_ipaddr, conn->ksnc_port, > iov_iter_count(&conn->ksnc_rx_to), conn->ksnc_rx_nob_left, > ktime_get_seconds() - last_rcv); > - lnet_finalize(conn->ksnc_peer->ksnp_ni, > - conn->ksnc_cookie, -EIO); > + lnet_finalize(conn->ksnc_cookie, -EIO); > break; > case SOCKNAL_RX_LNET_HEADER: > if (conn->ksnc_rx_started) > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > index 1bf0170..2e99a17 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > @@ -343,7 +343,7 @@ struct ksock_tx * > > ksocknal_free_tx(tx); > if (lnetmsg) /* KSOCK_MSG_NOOP go without lnetmsg */ > - lnet_finalize(ni, lnetmsg, rc); > + lnet_finalize(lnetmsg, rc); > } > > void > @@ -1226,7 +1226,7 @@ struct ksock_route * > le64_to_cpu(lhdr->src_nid) != id->nid); > } > > - lnet_finalize(conn->ksnc_peer->ksnp_ni, conn->ksnc_cookie, rc); > + lnet_finalize(conn->ksnc_cookie, rc); > > if (rc) { > ksocknal_new_packet(conn, 0); > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index d39331f..a213387 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -408,7 +408,7 @@ > } > rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > if (rc < 0) > - lnet_finalize(ni, msg, rc); > + lnet_finalize(msg, rc); > } > > static void > @@ -462,7 +462,7 @@ > > rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); > if (rc < 0) > - lnet_finalize(ni, msg, rc); > + lnet_finalize(msg, rc); > } > > static int > @@ -637,7 +637,7 @@ > CNETERR("Dropping message for %s: peer not alive\n", > libcfs_id2str(msg->msg_target)); > if (do_send) > - lnet_finalize(ni, msg, -EHOSTUNREACH); > + lnet_finalize(msg, -EHOSTUNREACH); > > lnet_net_lock(cpt); > return -EHOSTUNREACH; > @@ -650,7 +650,7 @@ > CNETERR("Aborting message for %s: LNetM[DE]Unlink() already called on the MD/ME.\n", > libcfs_id2str(msg->msg_target)); > if (do_send) > - lnet_finalize(ni, msg, -ECANCELED); > + lnet_finalize(msg, -ECANCELED); > > lnet_net_lock(cpt); > return -ECANCELED; > @@ -915,7 +915,7 @@ > lnet_ni_recv(msg->msg_rxni, msg->msg_private, NULL, > 0, 0, 0, msg->msg_hdr.payload_length); > list_del_init(&msg->msg_list); > - lnet_finalize(NULL, msg, -ECANCELED); > + lnet_finalize(msg, -ECANCELED); > } > > lnet_net_lock(cpt); > @@ -1914,7 +1914,7 @@ > libcfs_nid2str(ni->ni_nid), > libcfs_id2str(info.mi_id), rc); > > - lnet_finalize(ni, msg, rc); > + lnet_finalize(msg, rc); > } > > return 0; > @@ -2402,7 +2402,7 @@ > > free_drop: > LASSERT(!msg->msg_md); > - lnet_finalize(ni, msg, rc); > + lnet_finalize(msg, rc); > > drop: > lnet_drop_message(ni, cpt, private, payload_length); > @@ -2447,7 +2447,7 @@ > * but we still should give error code so lnet_msg_decommit() > * can skip counters operations and other checks. > */ > - lnet_finalize(msg->msg_rxni, msg, -ENOENT); > + lnet_finalize(msg, -ENOENT); > } > } > > @@ -2605,7 +2605,7 @@ > if (rc) { > CNETERR("Error sending PUT to %s: %d\n", > libcfs_id2str(target), rc); > - lnet_finalize(NULL, msg, rc); > + lnet_finalize(msg, rc); > } > > /* completion will be signalled by an event */ > @@ -2804,7 +2804,7 @@ struct lnet_msg * > if (rc < 0) { > CNETERR("Error sending GET to %s: %d\n", > libcfs_id2str(target), rc); > - lnet_finalize(NULL, msg, rc); > + lnet_finalize(msg, rc); > } > > /* completion will be signalled by an event */ > diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c > index aa28b6a..00be9ab 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c > @@ -452,7 +452,7 @@ > } > > void > -lnet_finalize(struct lnet_ni *ni, struct lnet_msg *msg, int status) > +lnet_finalize(struct lnet_msg *msg, int status) > { > struct lnet_msg_container *container; > int my_slot; > diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c > index 8167980..c8a1eb62 100644 > --- a/drivers/staging/lustre/lnet/lnet/lo.c > +++ b/drivers/staging/lustre/lnet/lnet/lo.c > @@ -62,10 +62,10 @@ > sendmsg->msg_offset, > iov_iter_count(to)); > > - lnet_finalize(ni, lntmsg, 0); > + lnet_finalize(lntmsg, 0); > } > > - lnet_finalize(ni, sendmsg, 0); > + lnet_finalize(sendmsg, 0); > return 0; > } > > diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c > index 17891f6..3841bac 100644 > --- a/drivers/staging/lustre/lnet/lnet/net_fault.c > +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c > @@ -633,7 +633,7 @@ struct delay_daemon_data { > } > > lnet_drop_message(ni, cpt, msg->msg_private, msg->msg_len); > - lnet_finalize(ni, msg, rc); > + lnet_finalize(msg, rc); > } > } > > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Wed Sep 26 23:59:59 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 09:59:59 +1000 Subject: [lustre-devel] [PATCH 02/25] lustre: lnet: Allow min stats to be reset in peers and nis In-Reply-To: <1537930097-11624-3-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> <1537930097-11624-3-git-send-email-jsimmons@infradead.org> Message-ID: <8736tvizcw.fsf@notabene.neil.brown.name> On Tue, Sep 25 2018, James Simmons wrote: > From: Doug Oucharek > > Allow writes to the peers and nis LNet procfs files to > reset the mininum stat columns. > > Signed-off-by: Doug Oucharek > WC-bug-id: https://jira.whamcloud.com/browse/LU-7214 > Reviewed-on: https://review.whamcloud.com/20470 > Reviewed-by: Olaf Weber > Reviewed-by: Amir Shehata > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > drivers/staging/lustre/lnet/lnet/router_proc.c | 69 +++++++++++++++++++++++--- > 1 file changed, 62 insertions(+), 7 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index a887ca4..4ddd35b 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -393,7 +393,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > { > const int tmpsiz = 256; > struct lnet_peer_table *ptable; > - char *tmpstr; > + char *tmpstr = NULL; > char *s; > int cpt = LNET_PROC_CPT_GET(*ppos); > int ver = LNET_PROC_VER_GET(*ppos); > @@ -402,12 +402,33 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > int rc = 0; > int len; > > - BUILD_BUG_ON(LNET_PROC_HASH_BITS < LNET_PEER_HASH_BITS); > - LASSERT(!write); > + if (write) { > + struct lnet_peer_ni *peer; > + int i; > + > + cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { > + lnet_net_lock(i); > + for (hash = 0; hash < LNET_PEER_HASH_SIZE; hash++) { > + list_for_each_entry(peer, > + &ptable->pt_hash[hash], > + lpni_hashlist) { > + peer->lpni_mintxcredits = > + peer->lpni_txcredits; > + peer->lpni_minrtrcredits = > + peer->lpni_rtrcredits; > + } > + } > + lnet_net_unlock(i); > + } > + *ppos += *lenp; > + return 0; > + } > > if (!*lenp) > return 0; > > + BUILD_BUG_ON(LNET_PROC_HASH_BITS < LNET_PEER_HASH_BITS); > + > if (cpt >= LNET_CPT_NUMBER) { > *lenp = 0; > return 0; > @@ -627,11 +648,45 @@ static int proc_lnet_nis(struct ctl_table *table, int write, > char *s; > int len; > > - LASSERT(!write); > - > if (!*lenp) > return 0; > > + if (write) { > + /* Just reset the min stat. */ > + struct lnet_net *net; > + struct lnet_ni *ni; > + > + lnet_net_lock(0); Presumably we hold lnet_net_lock(0) across the whole process to stop an EXCLUSIVE lock from being taken while the update progresses. That makes sense. So why doesn't proc_lnet_peers() above do the same thing? Is it OK if I add that to the patch? NeilBrown > + > + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { > + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { > + struct lnet_tx_queue *tq; > + int i; > + int j; > + > + cfs_percpt_for_each(tq, i, ni->ni_tx_queues) { > + for (j = 0; ni->ni_cpts && > + j < ni->ni_ncpts; j++) { > + if (i == ni->ni_cpts[j]) > + break; > + } > + > + if (j == ni->ni_ncpts) > + continue; > + > + if (i != 0) > + lnet_net_lock(i); > + tq->tq_credits_min = tq->tq_credits; > + if (i != 0) > + lnet_net_unlock(i); > + } > + } > + } > + lnet_net_unlock(0); > + *ppos += *lenp; > + return 0; > + } > + > tmpstr = kvmalloc(tmpsiz, GFP_KERNEL); > if (!tmpstr) > return -ENOMEM; > @@ -847,7 +902,7 @@ static int proc_lnet_portal_rotor(struct ctl_table *table, int write, > }, > { > .procname = "peers", > - .mode = 0444, > + .mode = 0644, > .proc_handler = &proc_lnet_peers, > }, > { > @@ -857,7 +912,7 @@ static int proc_lnet_portal_rotor(struct ctl_table *table, int write, > }, > { > .procname = "nis", > - .mode = 0444, > + .mode = 0644, > .proc_handler = &proc_lnet_nis, > }, > { > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Thu Sep 27 00:03:10 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 10:03:10 +1000 Subject: [lustre-devel] [PATCH 05/25] lustre: lnet: fix race in lnet shutdown path In-Reply-To: <1537930097-11624-6-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> <1537930097-11624-6-git-send-email-jsimmons@infradead.org> Message-ID: <87zhw3hkn5.fsf@notabene.neil.brown.name> On Tue, Sep 25 2018, James Simmons wrote: > From: Olaf Weber > > The locking changes for the lnet_net_lock made for Multi-Rail > introduce a race in the LNet shutdown path. The code keeps two > states in the_lnet.ln_shutdown: 0 means LNet is either up and > running or shut down, while 1 means lnet is shutting down. In > lnet_select_pathway() if we need to restart and drop and relock > the lnet_net_lock we can find that LNet went from running to > stopped, and not be able to tell the difference. > > Replace ln_shutdown with a three-state ln_state patterned on > ln_rc_state: states are LNET_STATE_SHUTDOWN, LNET_STATE_RUNNING, > and LNET_STATE_STOPPING. Most checks against ln_shutdown now test > ln_state against LNET_STATE_RUNNING. LNet moves to RUNNING state > in lnet_startup_lndnets(). > > Signed-off-by: Olaf Weber > WC-bug-id: https://jira.whamcloud.com/browse/LU-9119 > Reviewed-on: https://review.whamcloud.com/26690 > Reviewed-by: Doug Oucharek > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > drivers/staging/lustre/include/linux/lnet/lib-types.h | 9 +++++++-- > drivers/staging/lustre/lnet/lnet/api-ni.c | 15 ++++++++++++--- > drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 4 ++-- > drivers/staging/lustre/lnet/lnet/peer.c | 10 +++++----- > drivers/staging/lustre/lnet/lnet/router.c | 6 +++--- > 6 files changed, 30 insertions(+), 16 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 18e2665..6abac19 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -726,6 +726,11 @@ struct lnet_msg_container { > #define LNET_RC_STATE_RUNNING 1 /* started up OK */ > #define LNET_RC_STATE_STOPPING 2 /* telling thread to stop */ > > +/* LNet states */ > +#define LNET_STATE_SHUTDOWN 0 /* not started */ > +#define LNET_STATE_RUNNING 1 /* started up OK */ > +#define LNET_STATE_STOPPING 2 /* telling thread to stop */ This would be nicer as an enum ... NeilBrown > + > struct lnet { > /* CPU partition table of LNet */ > struct cfs_cpt_table *ln_cpt_table; > @@ -805,8 +810,8 @@ struct lnet { > int ln_niinit_self; > /* LNetNIInit/LNetNIFini counter */ > int ln_refcount; > - /* shutdown in progress */ > - int ln_shutdown; > + /* SHUTDOWN/RUNNING/STOPPING */ > + int ln_state; > > int ln_routing; /* am I a router? */ > lnet_pid_t ln_pid; /* requested pid */ > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 2d430d0..7c907a3 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -1277,11 +1277,11 @@ struct lnet_ni * > /* NB called holding the global mutex */ > > /* All quiet on the API front */ > - LASSERT(!the_lnet.ln_shutdown); > + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); > LASSERT(!the_lnet.ln_refcount); > > lnet_net_lock(LNET_LOCK_EX); > - the_lnet.ln_shutdown = 1; /* flag shutdown */ > + the_lnet.ln_state = LNET_STATE_STOPPING; > > while (!list_empty(&the_lnet.ln_nets)) { > /* > @@ -1309,7 +1309,7 @@ struct lnet_ni * > } > > lnet_net_lock(LNET_LOCK_EX); > - the_lnet.ln_shutdown = 0; > + the_lnet.ln_state = LNET_STATE_SHUTDOWN; > lnet_net_unlock(LNET_LOCK_EX); > } > > @@ -1583,6 +1583,15 @@ struct lnet_ni * > int rc; > int ni_count = 0; > > + /* > + * Change to running state before bringing up the LNDs. This > + * allows lnet_shutdown_lndnets() to assert that we've passed > + * through here. > + */ > + lnet_net_lock(LNET_LOCK_EX); > + the_lnet.ln_state = LNET_STATE_RUNNING; > + lnet_net_unlock(LNET_LOCK_EX); > + > while (!list_empty(netlist)) { > net = list_entry(netlist->next, struct lnet_net, net_list); > list_del_init(&net->net_list); > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index a213387..ea7e2c3 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -1242,7 +1242,7 @@ > > seq = lnet_get_dlc_seq_locked(); > > - if (the_lnet.ln_shutdown) { > + if (the_lnet.ln_state != LNET_STATE_RUNNING) { > lnet_net_unlock(cpt); > return -ESHUTDOWN; > } > diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > index d403353..6fa5bbf 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c > @@ -589,7 +589,7 @@ struct list_head * > mtable = lnet_mt_of_match(info, msg); > lnet_res_lock(mtable->mt_cpt); > > - if (the_lnet.ln_shutdown) { > + if (the_lnet.ln_state != LNET_STATE_RUNNING) { > rc = LNET_MATCHMD_DROP; > goto out1; > } > @@ -951,7 +951,7 @@ struct list_head * > list_move(&msg->msg_list, &zombies); > } > } else { > - if (the_lnet.ln_shutdown) > + if (the_lnet.ln_state != LNET_STATE_RUNNING) > CWARN("Active lazy portal %d on exit\n", portal); > else > CDEBUG(D_NET, "clearing portal %d lazy\n", portal); > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index ae3ffca..2fbf93a 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -428,7 +428,7 @@ void lnet_peer_uninit(void) > struct lnet_peer_table *ptable; > int i; > > - LASSERT(the_lnet.ln_shutdown || net); > + LASSERT(the_lnet.ln_state != LNET_STATE_SHUTDOWN || net); > /* > * If just deleting the peers for a NI, get rid of any routes these > * peers are gateways for. > @@ -458,7 +458,7 @@ void lnet_peer_uninit(void) > struct list_head *peers; > struct lnet_peer_ni *lp; > > - LASSERT(!the_lnet.ln_shutdown); > + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); > > peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; > list_for_each_entry(lp, peers, lpni_hashlist) { > @@ -1000,7 +1000,7 @@ struct lnet_peer_ni * > struct lnet_peer_ni *lpni = NULL; > int rc; > > - if (the_lnet.ln_shutdown) /* it's shutting down */ > + if (the_lnet.ln_state != LNET_STATE_RUNNING) > return ERR_PTR(-ESHUTDOWN); > > /* > @@ -1034,7 +1034,7 @@ struct lnet_peer_ni * > struct lnet_peer_ni *lpni = NULL; > int rc; > > - if (the_lnet.ln_shutdown) /* it's shutting down */ > + if (the_lnet.ln_state != LNET_STATE_RUNNING) > return ERR_PTR(-ESHUTDOWN); > > /* > @@ -1063,7 +1063,7 @@ struct lnet_peer_ni * > * Shutdown is only set under the ln_api_lock, so a single > * check here is sufficent. > */ > - if (the_lnet.ln_shutdown) { > + if (the_lnet.ln_state != LNET_STATE_RUNNING) { > lpni = ERR_PTR(-ESHUTDOWN); > goto out_mutex_unlock; > } > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index a0483f9..d3aef8b 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -252,7 +252,7 @@ struct lnet_remotenet * > struct lnet_remotenet *rnet; > struct list_head *rn_list; > > - LASSERT(!the_lnet.ln_shutdown); > + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); > > rn_list = lnet_net2rnethash(net); > list_for_each_entry(rnet, rn_list, lrn_list) { > @@ -374,7 +374,7 @@ static void lnet_shuffle_seed(void) > return rc; > } > route->lr_gateway = lpni; > - LASSERT(!the_lnet.ln_shutdown); > + LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING); > > rnet2 = lnet_find_rnet_locked(net); > if (!rnet2) { > @@ -1775,7 +1775,7 @@ int lnet_get_rtr_pool_cfg(int idx, struct lnet_ioctl_pool_cfg *pool_cfg) > > lnet_net_lock(cpt); > > - if (the_lnet.ln_shutdown) { > + if (the_lnet.ln_state != LNET_STATE_RUNNING) { > lnet_net_unlock(cpt); > return -ESHUTDOWN; > } > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Thu Sep 27 01:03:19 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 11:03:19 +1000 Subject: [lustre-devel] [PATCH 13/25] lustre: lnet: fix lnet_cpt_of_md() In-Reply-To: <1537930097-11624-14-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> <1537930097-11624-14-git-send-email-jsimmons@infradead.org> Message-ID: <87wor7hhuw.fsf@notabene.neil.brown.name> On Tue, Sep 25 2018, James Simmons wrote: > From: Amir Shehata > > The intent of this function is to get the cpt nearest to the > memory described by the MD. > > There are three scenarios that must be handled: > 1. The memory is described by an lnet_kiov_t structure > -> this describes kernel pages > 2. The memory is described by a struct kvec > -> this describes kernel logical addresses > 3. The memory is a contiguous buffer allocated via vmalloc > > For case 1 and 2 we look at the first vector which contains > the data to be DMAed, taking into consideration the msg offset. > > For case 2 we have to take the extra step of translating the kernel > logical address to a physical page using virt_to_page() macro. > > For case 3 we need to use is_vmalloc_addr() and vmalloc_to_page to > get the associated page to be able to identify the CPT. > > o2iblnd uses the same strategy when it's mapping the memory into > a scatter/gather list. Therefore, lnet_kvaddr_to_page() common > function was created to be used by both the o2iblnd and > lnet_cpt_of_md() > > kmap_to_page() performs the high memory check which > lnet_kvaddr_to_page() does. However, unlike the latter it handles > the highmem case properly instead of calling LBUG. It's not > 100% clear why the code was written that way. Since the legacy > code will need to still be maintained, adding kmap_to_page() will > not simplify the code. At worst calling kmap_to_page() might mask > some problems which would've been caught by the LBUG earlier on. > However, at the time of this fix, that LBUG has never been observed. > > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-9203 > Reviewed-on: https://review.whamcloud.com/28165 > Reviewed-by: Dmitry Eremin > Reviewed-by: Sonia Sharma > Reviewed-by: Olaf Weber > Reviewed-by: Oleg Drokin > Signed-off-by: James Simmons > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 25 +----- > drivers/staging/lustre/lnet/lnet/lib-md.c | 96 ++++++++++++++++++---- > drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- > 4 files changed, 82 insertions(+), 44 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 6bfdc9b..16e64d8 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -595,7 +595,8 @@ void lnet_copy_kiov2iter(struct iov_iter *to, > > void lnet_md_unlink(struct lnet_libmd *md); > void lnet_md_deconstruct(struct lnet_libmd *lmd, struct lnet_md *umd); > -int lnet_cpt_of_md(struct lnet_libmd *md); > +struct page *lnet_kvaddr_to_page(unsigned long vaddr); > +int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset); > > void lnet_register_lnd(struct lnet_lnd *lnd); > void lnet_unregister_lnd(struct lnet_lnd *lnd); > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > index debed17..a6b261a 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > @@ -531,29 +531,6 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > kiblnd_drop_rx(rx); /* Don't re-post rx. */ > } > > -static struct page * > -kiblnd_kvaddr_to_page(unsigned long vaddr) > -{ > - struct page *page; > - > - if (is_vmalloc_addr((void *)vaddr)) { > - page = vmalloc_to_page((void *)vaddr); > - LASSERT(page); > - return page; > - } > -#ifdef CONFIG_HIGHMEM > - if (vaddr >= PKMAP_BASE && > - vaddr < (PKMAP_BASE + LAST_PKMAP * PAGE_SIZE)) { > - /* No highmem pages only used for bulk (kiov) I/O */ > - CERROR("find page for address in highmem\n"); > - LBUG(); > - } > -#endif > - page = virt_to_page(vaddr); > - LASSERT(page); I think this would look cleaner as: page = kmap_to_page(vaddr); LASSERT(page); if (PageHighMem(page) { /* No highmem pages only used for bulk (kiov) I/O */ CERROR("find page for address in highmem\n"); LBUG(); } This avoids the #ifdef, and make the intention obvious. NeilBrown > - return page; > -} > - > static int > kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, struct kib_rdma_desc *rd, __u32 nob) > { > @@ -660,7 +637,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, > > vaddr = ((unsigned long)iov->iov_base) + offset; > page_offset = vaddr & (PAGE_SIZE - 1); > - page = kiblnd_kvaddr_to_page(vaddr); > + page = lnet_kvaddr_to_page(vaddr); > if (!page) { > CERROR("Can't find page\n"); > return -EFAULT; > diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c > index 9e26911..db5425e 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-md.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c > @@ -84,33 +84,93 @@ > kfree(md); > } > > -int > -lnet_cpt_of_md(struct lnet_libmd *md) > +struct page *lnet_kvaddr_to_page(unsigned long vaddr) > { > - int cpt = CFS_CPT_ANY; > + if (is_vmalloc_addr((void *)vaddr)) > + return vmalloc_to_page((void *)vaddr); > + > +#ifdef CONFIG_HIGHMEM > + return kmap_to_page((void *)vaddr); > +#else > + return virt_to_page(vaddr); > +#endif /* CONFIG_HIGHMEM */ > +} if !CONFIG_HIGHMEM, kmap_to_page is exactly virt_to_page, so this code should just use kmap_to_page(); > +EXPORT_SYMBOL(lnet_kvaddr_to_page); > > - if (!md) > - return CFS_CPT_ANY; > +int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset) > +{ > + int cpt = CFS_CPT_ANY; > + unsigned int niov; > > - if ((md->md_options & LNET_MD_BULK_HANDLE) != 0 && > - md->md_bulk_handle.cookie != LNET_WIRE_HANDLE_COOKIE_NONE) { > + /* > + * if the md_options has a bulk handle then we want to look at the > + * bulk md because that's the data which we will be DMAing > + */ > + if (md && (md->md_options & LNET_MD_BULK_HANDLE) != 0 && > + md->md_bulk_handle.cookie != LNET_WIRE_HANDLE_COOKIE_NONE) > md = lnet_handle2md(&md->md_bulk_handle); > > - if (!md) > - return CFS_CPT_ANY; > - } > + if (!md || md->md_niov == 0) > + return CFS_CPT_ANY; > + > + niov = md->md_niov; > > + /* > + * There are three cases to handle: > + * 1. The MD is using lnet_kiov_t > + * 2. The MD is using struct kvec > + * 3. Contiguous buffer allocated via vmalloc > + * > + * in case 2 we can use virt_to_page() macro to get the page > + * address of the memory kvec describes. > + * > + * in case 3 use is_vmalloc_addr() and vmalloc_to_page() > + * > + * The offset provided can be within the first iov/kiov entry or > + * it could go beyond it. In that case we need to make sure to > + * look at the page which actually contains the data that will be > + * DMAed. > + */ > if ((md->md_options & LNET_MD_KIOV) != 0) { > - if (md->md_iov.kiov[0].bv_page) > - cpt = cfs_cpt_of_node( > - lnet_cpt_table(), > - page_to_nid(md->md_iov.kiov[0].bv_page)); > - } else if (md->md_iov.iov[0].iov_base) { > - cpt = cfs_cpt_of_node( > - lnet_cpt_table(), > - page_to_nid(virt_to_page(md->md_iov.iov[0].iov_base))); > + struct bio_vec *kiov = md->md_iov.kiov; > + > + while (offset >= kiov->bv_len) { > + offset -= kiov->bv_len; > + niov--; > + kiov++; > + if (niov == 0) { > + CERROR("offset %d goes beyond kiov\n", offset); > + goto out; > + } > + } > + > + cpt = cfs_cpt_of_node(lnet_cpt_table(), > + page_to_nid(kiov->bv_page)); > + } else { > + struct kvec *iov = md->md_iov.iov; > + unsigned long vaddr; > + struct page *page; > + > + while (offset >= iov->iov_len) { > + offset -= iov->iov_len; > + niov--; > + iov++; > + if (niov == 0) { > + CERROR("offset %d goes beyond iov\n", offset); > + goto out; > + } > + } > + > + vaddr = ((unsigned long)iov->iov_base) + offset; > + page = lnet_kvaddr_to_page(vaddr); > + if (!page) { > + CERROR("Couldn't resolve vaddr 0x%lx to page\n", vaddr); > + goto out; > + } > + cpt = cfs_cpt_of_node(lnet_cpt_table(), page_to_nid(page)); > } > > +out: > return cpt; > } > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index f2bc97d..4d74421 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -1226,7 +1226,7 @@ > */ > cpt = lnet_net_lock_current(); > > - md_cpt = lnet_cpt_of_md(msg->msg_md); > + md_cpt = lnet_cpt_of_md(msg->msg_md, msg->msg_offset); > if (md_cpt == CFS_CPT_ANY) > md_cpt = cpt; > > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Thu Sep 27 01:14:35 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 11:14:35 +1000 Subject: [lustre-devel] [PATCH 05/25] lustre: lnet: fix race in lnet shutdown path In-Reply-To: <87zhw3hkn5.fsf@notabene.neil.brown.name> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> <1537930097-11624-6-git-send-email-jsimmons@infradead.org> <87zhw3hkn5.fsf@notabene.neil.brown.name> Message-ID: <87tvmbhhc4.fsf@notabene.neil.brown.name> On Thu, Sep 27 2018, NeilBrown wrote: >> >> +/* LNet states */ >> +#define LNET_STATE_SHUTDOWN 0 /* not started */ >> +#define LNET_STATE_RUNNING 1 /* started up OK */ >> +#define LNET_STATE_STOPPING 2 /* telling thread to stop */ > > This would be nicer as an enum ... > I've added this: From: NeilBrown Date: Thu, 27 Sep 2018 11:13:58 +1000 Subject: [PATCH] lnet: use enum for states. As these are arbitrary values, using a enum makes the purpose more obvious. Signed-off-by: NeilBrown --- .../staging/lustre/include/linux/lnet/lib-types.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h index 6abac191764d..14563bcafe61 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h @@ -722,14 +722,18 @@ struct lnet_msg_container { }; /* Router Checker states */ -#define LNET_RC_STATE_SHUTDOWN 0 /* not started */ -#define LNET_RC_STATE_RUNNING 1 /* started up OK */ -#define LNET_RC_STATE_STOPPING 2 /* telling thread to stop */ +enum lnet_rc_state { + LNET_RC_STATE_SHUTDOWN, /* not started */ + LNET_RC_STATE_RUNNING, /* started up OK */ + LNET_RC_STATE_STOPPING, /* telling thread to stop */ +}; /* LNet states */ -#define LNET_STATE_SHUTDOWN 0 /* not started */ -#define LNET_STATE_RUNNING 1 /* started up OK */ -#define LNET_STATE_STOPPING 2 /* telling thread to stop */ +enum lnet_state { + LNET_STATE_SHUTDOWN, /* not started */ + LNET_STATE_RUNNING, /* started up OK */ + LNET_STATE_STOPPING, /* telling thread to stop */ +}; struct lnet { /* CPU partition table of LNet */ @@ -793,7 +797,7 @@ struct lnet { struct lnet_ping_info *ln_ping_info; /* router checker startup/shutdown state */ - int ln_rc_state; + enum lnet_rc_state ln_rc_state; /* router checker's event queue */ struct lnet_handle_eq ln_rc_eqh; /* rcd still pending on net */ @@ -811,7 +815,7 @@ struct lnet { /* LNetNIInit/LNetNIFini counter */ int ln_refcount; /* SHUTDOWN/RUNNING/STOPPING */ - int ln_state; + enum lnet_state ln_state; int ln_routing; /* am I a router? */ lnet_pid_t ln_pid; /* requested pid */ -- 2.14.0.rc0.dirty -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Thu Sep 27 01:17:48 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 11:17:48 +1000 Subject: [lustre-devel] [PATCH 13/25] lustre: lnet: fix lnet_cpt_of_md() In-Reply-To: <87wor7hhuw.fsf@notabene.neil.brown.name> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> <1537930097-11624-14-git-send-email-jsimmons@infradead.org> <87wor7hhuw.fsf@notabene.neil.brown.name> Message-ID: <87r2hfhh6r.fsf@notabene.neil.brown.name> On Thu, Sep 27 2018, NeilBrown wrote: > On Tue, Sep 25 2018, James Simmons wrote: > >> From: Amir Shehata >> >> The intent of this function is to get the cpt nearest to the >> memory described by the MD. >> >> There are three scenarios that must be handled: >> 1. The memory is described by an lnet_kiov_t structure >> -> this describes kernel pages >> 2. The memory is described by a struct kvec >> -> this describes kernel logical addresses >> 3. The memory is a contiguous buffer allocated via vmalloc >> >> For case 1 and 2 we look at the first vector which contains >> the data to be DMAed, taking into consideration the msg offset. >> >> For case 2 we have to take the extra step of translating the kernel >> logical address to a physical page using virt_to_page() macro. >> >> For case 3 we need to use is_vmalloc_addr() and vmalloc_to_page to >> get the associated page to be able to identify the CPT. >> >> o2iblnd uses the same strategy when it's mapping the memory into >> a scatter/gather list. Therefore, lnet_kvaddr_to_page() common >> function was created to be used by both the o2iblnd and >> lnet_cpt_of_md() >> >> kmap_to_page() performs the high memory check which >> lnet_kvaddr_to_page() does. However, unlike the latter it handles >> the highmem case properly instead of calling LBUG. It's not >> 100% clear why the code was written that way. Since the legacy >> code will need to still be maintained, adding kmap_to_page() will >> not simplify the code. At worst calling kmap_to_page() might mask >> some problems which would've been caught by the LBUG earlier on. >> However, at the time of this fix, that LBUG has never been observed. >> >> Signed-off-by: Amir Shehata >> WC-bug-id: https://jira.whamcloud.com/browse/LU-9203 >> Reviewed-on: https://review.whamcloud.com/28165 >> Reviewed-by: Dmitry Eremin >> Reviewed-by: Sonia Sharma >> Reviewed-by: Olaf Weber >> Reviewed-by: Oleg Drokin >> Signed-off-by: James Simmons >> --- >> .../staging/lustre/include/linux/lnet/lib-lnet.h | 3 +- >> .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 25 +----- >> drivers/staging/lustre/lnet/lnet/lib-md.c | 96 ++++++++++++++++++---- >> drivers/staging/lustre/lnet/lnet/lib-move.c | 2 +- >> 4 files changed, 82 insertions(+), 44 deletions(-) >> >> diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h >> index 6bfdc9b..16e64d8 100644 >> --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h >> +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h >> @@ -595,7 +595,8 @@ void lnet_copy_kiov2iter(struct iov_iter *to, >> >> void lnet_md_unlink(struct lnet_libmd *md); >> void lnet_md_deconstruct(struct lnet_libmd *lmd, struct lnet_md *umd); >> -int lnet_cpt_of_md(struct lnet_libmd *md); >> +struct page *lnet_kvaddr_to_page(unsigned long vaddr); >> +int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset); >> >> void lnet_register_lnd(struct lnet_lnd *lnd); >> void lnet_unregister_lnd(struct lnet_lnd *lnd); >> diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c >> index debed17..a6b261a 100644 >> --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c >> +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c >> @@ -531,29 +531,6 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, >> kiblnd_drop_rx(rx); /* Don't re-post rx. */ >> } >> >> -static struct page * >> -kiblnd_kvaddr_to_page(unsigned long vaddr) >> -{ >> - struct page *page; >> - >> - if (is_vmalloc_addr((void *)vaddr)) { >> - page = vmalloc_to_page((void *)vaddr); >> - LASSERT(page); >> - return page; >> - } >> -#ifdef CONFIG_HIGHMEM >> - if (vaddr >= PKMAP_BASE && >> - vaddr < (PKMAP_BASE + LAST_PKMAP * PAGE_SIZE)) { >> - /* No highmem pages only used for bulk (kiov) I/O */ >> - CERROR("find page for address in highmem\n"); >> - LBUG(); >> - } >> -#endif >> - page = virt_to_page(vaddr); >> - LASSERT(page); > > I think this would look cleaner as: > > page = kmap_to_page(vaddr); > LASSERT(page); > if (PageHighMem(page) { > /* No highmem pages only used for bulk (kiov) I/O */ > CERROR("find page for address in highmem\n"); > LBUG(); > } > > This avoids the #ifdef, and make the intention obvious. Oh... that was code being deleted. Oops :-) NeilBrown > > NeilBrown > > >> - return page; >> -} >> - >> static int >> kiblnd_fmr_map_tx(struct kib_net *net, struct kib_tx *tx, struct kib_rdma_desc *rd, __u32 nob) >> { >> @@ -660,7 +637,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, >> >> vaddr = ((unsigned long)iov->iov_base) + offset; >> page_offset = vaddr & (PAGE_SIZE - 1); >> - page = kiblnd_kvaddr_to_page(vaddr); >> + page = lnet_kvaddr_to_page(vaddr); >> if (!page) { >> CERROR("Can't find page\n"); >> return -EFAULT; >> diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c >> index 9e26911..db5425e 100644 >> --- a/drivers/staging/lustre/lnet/lnet/lib-md.c >> +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c >> @@ -84,33 +84,93 @@ >> kfree(md); >> } >> >> -int >> -lnet_cpt_of_md(struct lnet_libmd *md) >> +struct page *lnet_kvaddr_to_page(unsigned long vaddr) >> { >> - int cpt = CFS_CPT_ANY; >> + if (is_vmalloc_addr((void *)vaddr)) >> + return vmalloc_to_page((void *)vaddr); >> + >> +#ifdef CONFIG_HIGHMEM >> + return kmap_to_page((void *)vaddr); >> +#else >> + return virt_to_page(vaddr); >> +#endif /* CONFIG_HIGHMEM */ >> +} > > if !CONFIG_HIGHMEM, kmap_to_page is exactly virt_to_page, so this code > should just use kmap_to_page(); > >> +EXPORT_SYMBOL(lnet_kvaddr_to_page); >> >> - if (!md) >> - return CFS_CPT_ANY; >> +int lnet_cpt_of_md(struct lnet_libmd *md, unsigned int offset) >> +{ >> + int cpt = CFS_CPT_ANY; >> + unsigned int niov; >> >> - if ((md->md_options & LNET_MD_BULK_HANDLE) != 0 && >> - md->md_bulk_handle.cookie != LNET_WIRE_HANDLE_COOKIE_NONE) { >> + /* >> + * if the md_options has a bulk handle then we want to look at the >> + * bulk md because that's the data which we will be DMAing >> + */ >> + if (md && (md->md_options & LNET_MD_BULK_HANDLE) != 0 && >> + md->md_bulk_handle.cookie != LNET_WIRE_HANDLE_COOKIE_NONE) >> md = lnet_handle2md(&md->md_bulk_handle); >> >> - if (!md) >> - return CFS_CPT_ANY; >> - } >> + if (!md || md->md_niov == 0) >> + return CFS_CPT_ANY; >> + >> + niov = md->md_niov; >> >> + /* >> + * There are three cases to handle: >> + * 1. The MD is using lnet_kiov_t >> + * 2. The MD is using struct kvec >> + * 3. Contiguous buffer allocated via vmalloc >> + * >> + * in case 2 we can use virt_to_page() macro to get the page >> + * address of the memory kvec describes. >> + * >> + * in case 3 use is_vmalloc_addr() and vmalloc_to_page() >> + * >> + * The offset provided can be within the first iov/kiov entry or >> + * it could go beyond it. In that case we need to make sure to >> + * look at the page which actually contains the data that will be >> + * DMAed. >> + */ >> if ((md->md_options & LNET_MD_KIOV) != 0) { >> - if (md->md_iov.kiov[0].bv_page) >> - cpt = cfs_cpt_of_node( >> - lnet_cpt_table(), >> - page_to_nid(md->md_iov.kiov[0].bv_page)); >> - } else if (md->md_iov.iov[0].iov_base) { >> - cpt = cfs_cpt_of_node( >> - lnet_cpt_table(), >> - page_to_nid(virt_to_page(md->md_iov.iov[0].iov_base))); >> + struct bio_vec *kiov = md->md_iov.kiov; >> + >> + while (offset >= kiov->bv_len) { >> + offset -= kiov->bv_len; >> + niov--; >> + kiov++; >> + if (niov == 0) { >> + CERROR("offset %d goes beyond kiov\n", offset); >> + goto out; >> + } >> + } >> + >> + cpt = cfs_cpt_of_node(lnet_cpt_table(), >> + page_to_nid(kiov->bv_page)); >> + } else { >> + struct kvec *iov = md->md_iov.iov; >> + unsigned long vaddr; >> + struct page *page; >> + >> + while (offset >= iov->iov_len) { >> + offset -= iov->iov_len; >> + niov--; >> + iov++; >> + if (niov == 0) { >> + CERROR("offset %d goes beyond iov\n", offset); >> + goto out; >> + } >> + } >> + >> + vaddr = ((unsigned long)iov->iov_base) + offset; >> + page = lnet_kvaddr_to_page(vaddr); >> + if (!page) { >> + CERROR("Couldn't resolve vaddr 0x%lx to page\n", vaddr); >> + goto out; >> + } >> + cpt = cfs_cpt_of_node(lnet_cpt_table(), page_to_nid(page)); >> } >> >> +out: >> return cpt; >> } >> >> diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c >> index f2bc97d..4d74421 100644 >> --- a/drivers/staging/lustre/lnet/lnet/lib-move.c >> +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c >> @@ -1226,7 +1226,7 @@ >> */ >> cpt = lnet_net_lock_current(); >> >> - md_cpt = lnet_cpt_of_md(msg->msg_md); >> + md_cpt = lnet_cpt_of_md(msg->msg_md, msg->msg_offset); >> if (md_cpt == CFS_CPT_ANY) >> md_cpt = cpt; >> >> -- >> 1.8.3.1 > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Thu Sep 27 01:19:08 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 11:19:08 +1000 Subject: [lustre-devel] [PATCH 00/25] lustre: lnet: remaining fixes for multi-rail In-Reply-To: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> Message-ID: <87o9cjhh4j.fsf@notabene.neil.brown.name> On Tue, Sep 25 2018, James Simmons wrote: > This is the remaining patches to land to 2.10 to resolve issues > found in MR testing. These patches are based on lustre-testing > commit 18c9cf20ec376d5b3d432aa3923645a12636d14b. A few fixes for > o2iblnd is also pushed. Thanks. I've applied this, making a couple of little changes I suggested in response to individual patches. NeilBrown > > Amir Shehata (10): > lustre: lnet: Normalize ioctl interface > lustre: lnet: selftest MR fix > lustre: lnet: prevent assert on ln_state > lustre: lnet: increment per NI stats > lustre: lnet: correct locking in legacy add net > lustre: lnet: fix lnet_cpt_of_md() > lustre: lnet: safe access to msg > lustre: lnet: handle empty CPTs > lustre: lnet: set LND tunables properly > lustre: lnd: pending transmits dropped silently > > Dmitry Eremin (1): > lustre: lnet: Fix lost lock > > Doug Oucharek (4): > lustre: lnet: Allow min stats to be reset in peers and nis > lustre: lnd: Turn on 2 sges by default > lustre: lnd: Don't Assert On Reconnect with MultiQP > lustre: lnd: Don't Page Align remote_addr with FastReg > > John L. Hammond (1): > lustre: ko2iblnd: allow for discontiguous fragments > > Liang Zhen (1): > lustre: o2iblnd: multiple sges for work request > > Olaf Weber (5): > lustre: lnet: remove debug ioctl > lustre: lnet: fix race in lnet shutdown path > lustre: lnet: loopback NID in lnet_select_pathway() > lustre: lnet: rename LNET_MAX_INTERFACES > lustre: socklnd: propagate errors on send failure > > Sergey Cheremencev (3): > lustre: lnet: remove ni from lnet_finalize > lustre: o2iblnd: reconnect peer for REJ_INVALID_SERVICE_ID > lustre: o2iblnd: kill timedout txs from ibp_tx_queue > > .../staging/lustre/include/linux/lnet/lib-lnet.h | 12 +- > .../staging/lustre/include/linux/lnet/lib-types.h | 11 +- > .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 3 +- > .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 67 ++++--- > .../lustre/include/uapi/linux/lnet/lnet-types.h | 2 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 79 ++++++-- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 11 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 212 +++++++++++---------- > .../lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c | 11 +- > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 61 ++++-- > .../staging/lustre/lnet/klnds/socklnd/socklnd.h | 8 +- > .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 21 +- > .../lustre/lnet/klnds/socklnd/socklnd_proto.c | 4 +- > drivers/staging/lustre/lnet/lnet/api-ni.c | 69 +++---- > drivers/staging/lustre/lnet/lnet/config.c | 10 +- > drivers/staging/lustre/lnet/lnet/lib-md.c | 96 ++++++++-- > drivers/staging/lustre/lnet/lnet/lib-move.c | 100 ++++++---- > drivers/staging/lustre/lnet/lnet/lib-msg.c | 10 +- > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 4 +- > drivers/staging/lustre/lnet/lnet/lo.c | 4 +- > drivers/staging/lustre/lnet/lnet/net_fault.c | 2 +- > drivers/staging/lustre/lnet/lnet/peer.c | 60 +++--- > drivers/staging/lustre/lnet/lnet/router.c | 6 +- > drivers/staging/lustre/lnet/lnet/router_proc.c | 69 ++++++- > drivers/staging/lustre/lnet/selftest/rpc.c | 2 +- > 25 files changed, 593 insertions(+), 341 deletions(-) > > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Thu Sep 27 03:48:43 2018 From: neilb at suse.com (NeilBrown) Date: Thu, 27 Sep 2018 13:48:43 +1000 Subject: [lustre-devel] [PATCH 0/8] lustre: obd: preprocessor cleanups In-Reply-To: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> References: <1537205481-6899-1-git-send-email-jsimmons@infradead.org> Message-ID: <87ftxvha78.fsf@notabene.neil.brown.name> On Mon, Sep 17 2018, James Simmons wrote: > The obd.h, obd_class.h, and clio headers are littered with complex > macros that are difficult to read. These macros existed to handle the > obd stats and md stats which are lacking in the linux client. Newer > versions do support md_stats so lets restore them as well as cleanup > the ugly macros. This patch set is order dependent and is based > on the first batch patch set for lustre 2.10 applied against the > lustre-testing branch. > > Ben Evans (4): > lustre: obdclass: remove CL_PAGE_INVOKE et. al. > lustre: obdclass: remove cl_for_each defines > lustre: obdclass: Code cleanup > lustre: obdclass: cleanup obd_class.h defines > > James Simmons (1): > lustre: obdclass: restore md_stats code > > John L. Hammond (3): > lustre: obd: remove obd_{get,put}ref() > lustre: obd: remove OBD ops based stats > lustre: obd: add md_stats to MDC and LMV devices Thanks. I've applied all of these. NeilBrown > > .../staging/lustre/lustre/include/lprocfs_status.h | 5 +- > drivers/staging/lustre/lustre/include/obd.h | 20 +- > drivers/staging/lustre/lustre/include/obd_class.h | 788 ++++++++++++--------- > drivers/staging/lustre/lustre/llite/file.c | 2 +- > drivers/staging/lustre/lustre/llite/llite_lib.c | 3 +- > drivers/staging/lustre/lustre/lmv/lmv_obd.c | 9 +- > drivers/staging/lustre/lustre/lmv/lproc_lmv.c | 6 + > drivers/staging/lustre/lustre/lov/lov_dev.c | 12 +- > drivers/staging/lustre/lustre/lov/lov_internal.h | 2 + > drivers/staging/lustre/lustre/lov/lov_obd.c | 44 +- > drivers/staging/lustre/lustre/lov/lov_pool.c | 10 +- > drivers/staging/lustre/lustre/lov/lov_request.c | 4 +- > drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 7 + > drivers/staging/lustre/lustre/mdc/mdc_request.c | 8 +- > drivers/staging/lustre/lustre/obdclass/Makefile | 5 +- > drivers/staging/lustre/lustre/obdclass/cl_io.c | 26 +- > drivers/staging/lustre/lustre/obdclass/cl_object.c | 21 +- > drivers/staging/lustre/lustre/obdclass/cl_page.c | 275 +++---- > drivers/staging/lustre/lustre/obdclass/class_obd.c | 1 - > drivers/staging/lustre/lustre/obdclass/genops.c | 3 - > .../staging/lustre/lustre/obdclass/kernelcomm.c | 7 +- > drivers/staging/lustre/lustre/obdclass/llog_obd.c | 4 +- > .../lustre/lustre/obdclass/lprocfs_status.c | 66 +- > drivers/staging/lustre/lustre/obdclass/obd_mount.c | 2 +- > drivers/staging/lustre/lustre/obdclass/uuid.c | 45 -- > 25 files changed, 753 insertions(+), 622 deletions(-) > delete mode 100644 drivers/staging/lustre/lustre/obdclass/uuid.c > > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From jsimmons at infradead.org Fri Sep 28 16:25:05 2018 From: jsimmons at infradead.org (James Simmons) Date: Fri, 28 Sep 2018 17:25:05 +0100 (BST) Subject: [lustre-devel] [PATCH 33/34] lnet: use BIT() macro for LNET_MD_* flags In-Reply-To: <153783763611.32103.14845537928418369718.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763611.32103.14845537928418369718.stgit@noble> Message-ID: > As these are bit flags, it aids clarity to use the BIT() > macro. Nak. BIT is not for UAPI headers. Including this will break building userland applications. > Signed-off-by: NeilBrown > --- > .../lustre/include/uapi/linux/lnet/lnet-types.h | 18 +++++++++--------- > 1 file changed, 9 insertions(+), 9 deletions(-) > > diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h > index e80ef4182e5d..62f062c0d1bf 100644 > --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h > +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-types.h > @@ -483,22 +483,22 @@ struct lnet_md { > /** > * Options for the MD structure. See lnet_md::options. > */ > -#define LNET_MD_OP_PUT (1 << 0) > +#define LNET_MD_OP_PUT BIT(0) > /** See lnet_md::options. */ > -#define LNET_MD_OP_GET (1 << 1) > +#define LNET_MD_OP_GET BIT(1) > /** See lnet_md::options. */ > -#define LNET_MD_MANAGE_REMOTE (1 << 2) > -/* unused (1 << 3) */ > +#define LNET_MD_MANAGE_REMOTE BIT(2) > +/* unused BIT(3) */ > /** See lnet_md::options. */ > -#define LNET_MD_TRUNCATE (1 << 4) > +#define LNET_MD_TRUNCATE BIT(4) > /** See lnet_md::options. */ > -#define LNET_MD_ACK_DISABLE (1 << 5) > +#define LNET_MD_ACK_DISABLE BIT(5) > /** See lnet_md::options. */ > -#define LNET_MD_IOVEC (1 << 6) > +#define LNET_MD_IOVEC BIT(6) > /** See lnet_md::options. */ > -#define LNET_MD_MAX_SIZE (1 << 7) > +#define LNET_MD_MAX_SIZE BIT(7) > /** See lnet_md::options. */ > -#define LNET_MD_KIOV (1 << 8) > +#define LNET_MD_KIOV BIT(8) > > /* For compatibility with Cray Portals */ > #define LNET_MD_PHYS 0 > > > From jsimmons at infradead.org Sat Sep 29 21:05:34 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 22:05:34 +0100 (BST) Subject: [lustre-devel] [PATCH 11/34] LU-7734 lnet: configure local NI from DLC In-Reply-To: <153783763527.32103.6166409833321456335.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763527.32103.6166409833321456335.stgit@noble> Message-ID: > From: Amir Shehata > > This patch adds the ability to configure multiple network interfaces > on the same network. This can be done via the lnetctl CLI interface > or through a YAML configuration. Refer to the multi-rail HLD for > more details on the syntax. > > It also deprecates ip2nets kernel parsing. All string parsing and > network maching now happens in the DLC userspace library. > > New IOCTLs are added for adding/deleting local NIs, to keep backwards > compatibility with older version of the DLC and lnetctl. > > The changes also include parsing and matching ip2nets syntax at the > user level and then passing down the network interfaces down to the > kernel to be configured. Nak. This patch introduces a regression in lnet_ioctl() found in module.c > Signed-off-by: Amir Shehata > Change-Id: I19ee7dc76514beb6f34de6517d19654d6468bcec > Reviewed-on: http://review.whamcloud.com/18886 > Tested-by: Maloo > Signed-off-by: NeilBrown > --- > .../lustre/include/linux/libcfs/libcfs_string.h | 12 - > .../staging/lustre/include/linux/lnet/lib-lnet.h | 13 - > .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 6 > .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 57 ++ > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 3 > drivers/staging/lustre/lnet/lnet/api-ni.c | 479 +++++++++++++++++--- > drivers/staging/lustre/lnet/lnet/config.c | 107 +++- > drivers/staging/lustre/lnet/lnet/module.c | 70 ++- > drivers/staging/lustre/lnet/lnet/peer.c | 21 + > drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 2 > drivers/staging/lustre/lustre/ptlrpc/service.c | 4 > 11 files changed, 650 insertions(+), 124 deletions(-) ..... > diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c > index 9d06664f0c17..c82d27592391 100644 > --- a/drivers/staging/lustre/lnet/lnet/module.c > +++ b/drivers/staging/lustre/lnet/lnet/module.c > @@ -92,7 +92,7 @@ lnet_unconfigure(void) > } > > static int > -lnet_dyn_configure(struct libcfs_ioctl_hdr *hdr) > +lnet_dyn_configure_net(struct libcfs_ioctl_hdr *hdr) > { > struct lnet_ioctl_config_data *conf = > (struct lnet_ioctl_config_data *)hdr; > @@ -102,19 +102,17 @@ lnet_dyn_configure(struct libcfs_ioctl_hdr *hdr) > return -EINVAL; > > mutex_lock(&lnet_config_mutex); > - if (!the_lnet.ln_niinit_self) { > + if (the_lnet.ln_niinit_self) > + rc = lnet_dyn_add_net(conf); > + else > rc = -EINVAL; > - goto out_unlock; > - } > - rc = lnet_dyn_add_ni(LNET_PID_LUSTRE, conf); > -out_unlock: > mutex_unlock(&lnet_config_mutex); > > return rc; > } > > static int > -lnet_dyn_unconfigure(struct libcfs_ioctl_hdr *hdr) > +lnet_dyn_unconfigure_net(struct libcfs_ioctl_hdr *hdr) > { > struct lnet_ioctl_config_data *conf = > (struct lnet_ioctl_config_data *)hdr; > @@ -124,12 +122,50 @@ lnet_dyn_unconfigure(struct libcfs_ioctl_hdr *hdr) > return -EINVAL; > > mutex_lock(&lnet_config_mutex); > - if (!the_lnet.ln_niinit_self) { > + if (the_lnet.ln_niinit_self) > + rc = lnet_dyn_del_net(conf->cfg_net); > + else > + rc = -EINVAL; > + mutex_unlock(&lnet_config_mutex); > + > + return rc; > +} > + > +static int > +lnet_dyn_configure_ni(struct libcfs_ioctl_hdr *hdr) > +{ > + struct lnet_ioctl_config_ni *conf = > + (struct lnet_ioctl_config_ni *)hdr; > + int rc; > + > + if (conf->lic_cfg_hdr.ioc_len < sizeof(*conf)) > + return -EINVAL; > + > + mutex_lock(&lnet_config_mutex); > + if (the_lnet.ln_niinit_self) > + rc = lnet_dyn_add_ni(conf); > + else > + rc = -EINVAL; > + mutex_unlock(&lnet_config_mutex); > + > + return rc; > +} > + > +static int > +lnet_dyn_unconfigure_ni(struct libcfs_ioctl_hdr *hdr) > +{ > + struct lnet_ioctl_config_ni *conf = > + (struct lnet_ioctl_config_ni *)hdr; > + int rc; > + > + if (conf->lic_cfg_hdr.ioc_len < sizeof(*conf)) > + return -EINVAL; > + > + mutex_lock(&lnet_config_mutex); > + if (the_lnet.ln_niinit_self) > + rc = lnet_dyn_del_ni(conf); > + else > rc = -EINVAL; > - goto out_unlock; > - } > - rc = lnet_dyn_del_ni(conf->cfg_net); > -out_unlock: > mutex_unlock(&lnet_config_mutex); > > return rc; > @@ -161,11 +197,17 @@ lnet_ioctl(struct notifier_block *nb, > break; > > case IOC_LIBCFS_ADD_NET: > - rc = lnet_dyn_configure(hdr); > + rc = lnet_dyn_configure_net(hdr); > break; > > case IOC_LIBCFS_DEL_NET: > - rc = lnet_dyn_unconfigure(hdr); > + rc = lnet_dyn_unconfigure_net(hdr); > + > + case IOC_LIBCFS_ADD_LOCAL_NI: > + return lnet_dyn_configure_ni(hdr); > + > + case IOC_LIBCFS_DEL_LOCAL_NI: > + return lnet_dyn_unconfigure_ni(hdr); > break; > > default: While the above is mostly correct for the OpenSFS branch that is not the case for the linux client version. The above code assumes we are using libc_register_ioctl() but that was replace by the block_notifier handling for ioctls instead. What we want instead is case IOC_LIBCFS_DEL_NET: rc = lnet_dyn_unconfigure_net(hdr); break; case IOC_LIBCFS_ADD_LOCAL_NI: rc = lnet_dyn_configure_ni(hdr); break; case IOC_LIBCFS_DEL_LOCAL_NI: rc = lnet_dyn_unconfigure_ni(hdr); break; that way the return value is generated by notifier_from_ioctl_errno(rc). This resolves the last bug in see in this patch set with my testing. From jsimmons at infradead.org Sat Sep 29 21:11:37 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 22:11:37 +0100 (BST) Subject: [lustre-devel] [PATCH 11/30] lustre: mdc: allow setting readdir RPC size parameter In-Reply-To: <7503F4FB-D93E-4CD1-9DF3-C00C51528E93@whamcloud.com> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-12-git-send-email-jsimmons@infradead.org> <8736u76j7g.fsf@notabene.neil.brown.name> <7503F4FB-D93E-4CD1-9DF3-C00C51528E93@whamcloud.com> Message-ID: > On Sep 18, 2018, at 09:14, NeilBrown wrote: > > > > On Mon, Sep 17 2018, James Simmons wrote: > > > >> From: Andreas Dilger > >> > >> diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h > >> index 2dbd208..cf630db 100644 > >> --- a/drivers/staging/lustre/lustre/include/lustre_net.h > >> +++ b/drivers/staging/lustre/lustre/include/lustre_net.h > >> @@ -104,15 +104,15 @@ > >> * currently supported maximum between peers at connect via ocd_brw_size. > >> */ > >> #define PTLRPC_MAX_BRW_BITS (LNET_MTU_BITS + PTLRPC_BULK_OPS_BITS) > >> -#define PTLRPC_MAX_BRW_SIZE (1 << PTLRPC_MAX_BRW_BITS) > >> +#define PTLRPC_MAX_BRW_SIZE BIT(PTLRPC_MAX_BRW_BITS) > >> #define PTLRPC_MAX_BRW_PAGES (PTLRPC_MAX_BRW_SIZE >> PAGE_SHIFT) > >> > >> -#define ONE_MB_BRW_SIZE (1 << LNET_MTU_BITS) > >> -#define MD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) > >> +#define ONE_MB_BRW_SIZE BIT(LNET_MTU_BITS) > >> +#define MD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) > >> #define MD_MAX_BRW_PAGES (MD_MAX_BRW_SIZE >> PAGE_SHIFT) > >> #define DT_MAX_BRW_SIZE PTLRPC_MAX_BRW_SIZE > >> #define DT_MAX_BRW_PAGES (DT_MAX_BRW_SIZE >> PAGE_SHIFT) > >> -#define OFD_MAX_BRW_SIZE (1 << LNET_MTU_BITS) > >> +#define OFD_MAX_BRW_SIZE BIT(LNET_MTU_BITS) > > > > Argg!! No!! Names are important. > > "SIZE" means the value is a size, a number. The bit-representation is > > largely irrelevant, it is the number that is important. > > BIT(x) returns a single bit - lots of zeros and just one '1' bit. This > > is not a number, it is a bit pattern. > > > > So settings FOO_SIZE to BIT(bar) is wrong. It is a type error. It uses > > a bit pattern when a number is expected. The C compiler won't notice, but I will. > > > > When I apply this (which probably won't be until next week), I'll just > > remove this section of the patch. > > Just to confirm, my original patch didn't have these BIT() macros in it, > and I agree with your statements, so I'm fine with you removing them again. That was my attempting to handle a checkpatch complaint with this patch. I do see your point in this. Still I like to keep the checkpatch numbers down to to remove a potential barrier to the acceptance into the fs tree. We could replace (1 << LNET_MTU_BITS) with LNET_MTU which is the same value. I will latter post a separate patch to fix those checkpatch issues up. > >> diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c > >> index 6c9fe49..d3b0445 100644 > >> --- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c > >> +++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c > >> @@ -267,27 +267,22 @@ void cl_inode_fini(struct inode *inode) > >> /** > >> * build inode number from passed @fid > >> */ > >> -__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) > >> +u64 cl_fid_build_ino(const struct lu_fid *fid, int api32) > >> { > >> if (BITS_PER_LONG == 32 || api32) > >> return fid_flatten32(fid); > >> - else > >> - return fid_flatten(fid); > >> + > >> + return fid_flatten(fid); > > > > I preferred that as it was - it makes the either/or nature more obvious. > > Kernel style generally recommends no "else" after a return, and checkpatch.pl will complain in this case. > > Cheers, Andreas > --- > Andreas Dilger > Principal Lustre Architect > Whamcloud > > > > > > > > From jsimmons at infradead.org Sat Sep 29 21:18:34 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 22:18:34 +0100 (BST) Subject: [lustre-devel] [PATCH 08/30] lustre: mgc: Remove unnecessary checks for config_log_put() In-Reply-To: <878t3r5zzr.fsf@notabene.neil.brown.name> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-9-git-send-email-jsimmons@infradead.org> <878t3r5zzr.fsf@notabene.neil.brown.name> Message-ID: > > From: Steve Guminski > > > > Make config_log_put() check if its parameter is NULL, which makes > > it is unnecessary to perform the check prior to calling it. > > This patch removes the redundant checks. > > > > Signed-off-by: Steve Guminski > > WC-bug-id: https://jira.whamcloud.com/browse/LU-9152 > > Reviewed-on: https://review.whamcloud.com/25854 > > Reviewed-by: Bob Glossman > > Reviewed-by: Andreas Dilger > > Reviewed-by: James Simmons > > Signed-off-by: James Simmons > > --- > > drivers/staging/lustre/lustre/mgc/mgc_request.c | 36 +++++++++++-------------- > > 1 file changed, 16 insertions(+), 20 deletions(-) > > > > diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c > > index 4552cc5..e6f8d9e 100644 > > --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c > > +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c > > @@ -131,6 +131,9 @@ static int config_log_get(struct config_llog_data *cld) > > */ > > static void config_log_put(struct config_llog_data *cld) > > { > > + if (unlikely(!cld)) > > + return; > > + > > I've removed the "unlikely()" call. > > Partly because use of likely/unlikely is discouraged where the > difference cannot be measured (or clearly justified some other way), > and partly because ..... I kept it in since it was in the original patch. Personally I'm not a fan either. The only time I would use it is in a case where code is executed 100k+ times a second and even then I question if you really get any boost with modern processors. > > @@ -387,6 +387,9 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, > > > > static inline void config_mark_cld_stop(struct config_llog_data *cld) > > { > > + if (!cld) > > + return; > > + > > .... there is no "unlikely()" here, and I like consistency. > > Thanks, > NeilBrown > > > > mutex_lock(&cld->cld_lock); > > spin_lock(&config_list_lock); > > cld->cld_stopping = 1; > > @@ -436,18 +439,13 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg) > > cld->cld_sptlrpc = NULL; > > mutex_unlock(&cld->cld_lock); > > > > - if (cld_recover) { > > - config_mark_cld_stop(cld_recover); > > - config_log_put(cld_recover); > > - } > > + config_mark_cld_stop(cld_recover); > > + config_log_put(cld_recover); > > > > - if (cld_params) { > > - config_mark_cld_stop(cld_params); > > - config_log_put(cld_params); > > - } > > + config_mark_cld_stop(cld_params); > > + config_log_put(cld_params); > > > > - if (cld_sptlrpc) > > - config_log_put(cld_sptlrpc); > > + config_log_put(cld_sptlrpc); > > > > /* drop the ref from the find */ > > config_log_put(cld); > > @@ -593,8 +591,7 @@ static int mgc_requeue_thread(void *data) > > cld->cld_lostlock = 0; > > spin_unlock(&config_list_lock); > > > > - if (cld_prev) > > - config_log_put(cld_prev); > > + config_log_put(cld_prev); > > cld_prev = cld; > > > > if (likely(!(rq_state & RQ_STOP))) { > > @@ -606,8 +603,7 @@ static int mgc_requeue_thread(void *data) > > } > > } > > spin_unlock(&config_list_lock); > > - if (cld_prev) > > - config_log_put(cld_prev); > > + config_log_put(cld_prev); > > > > /* Wait a bit to see if anyone else needs a requeue */ > > wait_event_idle(rq_waitq, rq_state & (RQ_NOW | RQ_STOP)); > > -- > > 1.8.3.1 > From jsimmons at infradead.org Sat Sep 29 21:30:06 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 22:30:06 +0100 (BST) Subject: [lustre-devel] [PATCH 17/30] lustre: llite: protect ll_dentry_data modification In-Reply-To: <87zhw74jvm.fsf@notabene.neil.brown.name> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-18-git-send-email-jsimmons@infradead.org> <87zhw74jvm.fsf@notabene.neil.brown.name> Message-ID: > > > From: Andriy Skulysh > > > > The ll_dentry_data bitfields modification should be protected by > > a spinlock. > > > > Signed-off-by: Andriy Skulysh > > Signed-off-by: Lai Siyao > > WC-bug-id: https://jira.whamcloud.com/browse/LU-9241 > > Seagate-bug-id: MRP-4257 > > Reviewed-on: https://review.whamcloud.com/26109 > > Reviewed-by: Niu Yawei > > Reviewed-by: Bobi Jam > > Reviewed-by: Oleg Drokin > > Signed-off-by: James Simmons > > --- > > drivers/staging/lustre/lustre/llite/llite_nfs.c | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c > > index c66072a..5e91e83 100644 > > --- a/drivers/staging/lustre/lustre/llite/llite_nfs.c > > +++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c > > @@ -171,8 +171,9 @@ struct lustre_nfs_fid { > > * we came from NFS and so opencache needs to be > > * enabled for this one > > */ > > + spin_lock(&result->d_lock); > > ll_d2d(result)->lld_nfs_dentry = 1; > > - > > + spin_unlock(&result->d_lock); > > return result; > > } > > This is a bit weird.... > I agree that having a spinlock is needed as the compiler does an R/M/W > to update the bitfield, and that could race with updats to lld_invalid > (and I think that is a good arguement to avoid bitfields in shared structures). > > However lld_nfs_dentry is never used. The only use was removed by > > Commit: c1b66fccf986 ("staging: lustre: fid: do open-by-fid by default") > > The corresponding commit upstream is > > Commit: cb85c0364fd8 ("LU-3544 fid: do open-by-fid by default") > > and that commit doesn't remove the use of lld_nfs_dentry. Maybe because > lld_nfs_dentry didn't exist then - it wasn't added until later > by 65d0add6057b138. > > So do we need to bring lld_nfs_dentry back? Ouch. That got removed by mistake by me ;-( Yes it should come back. I will create a patch to fix that. My bad. From jsimmons at infradead.org Sat Sep 29 21:33:21 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 22:33:21 +0100 (BST) Subject: [lustre-devel] [PATCH 24/30] lustre: llite: rcu-walk check should not depend on statahead In-Reply-To: <87r2hj4j9c.fsf@notabene.neil.brown.name> References: <1537205440-6656-1-git-send-email-jsimmons@infradead.org> <1537205440-6656-25-git-send-email-jsimmons@infradead.org> <87r2hj4j9c.fsf@notabene.neil.brown.name> Message-ID: > On Mon, Sep 17 2018, James Simmons wrote: > > > From: Steve Guminski > > > > Moves the check for the LOOKUP_RCU flag, so that it does not depend > > on the statahead setting. The caller is now informed if rcu-walk > > was requested but the filesystem does not support it, regardless > > of whether statahead is enabled or disabled. > > Nope, this is wrong. > > The filesystem only returns -ECHILD if it couldn't complete the request > because it would have to block. > If statahead is disabled, then it can complete the request immediately, > doesn't need to block, and so doesn't need to return -ECHILD. > > Patch deleted. Do this patch need to be reverted in the OpenSFS branch or can it be ignored? > > Signed-off-by: Steve Guminski > > WC-bug-id: https://jira.whamcloud.com/browse/LU-8891 > > Reviewed-on: https://review.whamcloud.com/24195 > > Reviewed-by: John L. Hammond > > Reviewed-by: Andreas Dilger > > Reviewed-by: Oleg Drokin > > Signed-off-by: James Simmons > > --- > > drivers/staging/lustre/lustre/llite/dcache.c | 7 +++---- > > 1 file changed, 3 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c > > index 11b82c63..ee1ba16 100644 > > --- a/drivers/staging/lustre/lustre/llite/dcache.c > > +++ b/drivers/staging/lustre/lustre/llite/dcache.c > > @@ -270,13 +270,12 @@ static int ll_revalidate_dentry(struct dentry *dentry, > > if (lookup_flags & LOOKUP_REVAL) > > return 0; > > > > - if (!dentry_may_statahead(dir, dentry)) > > - return 1; > > - > > if (lookup_flags & LOOKUP_RCU) > > return -ECHILD; > > > > - ll_statahead(dir, &dentry, !d_inode(dentry)); > > + if (dentry_may_statahead(dir, dentry)) > > + ll_statahead(dir, &dentry, !d_inode(dentry)); > > + > > return 1; > > } > > > > -- > > 1.8.3.1 > From jsimmons at infradead.org Sat Sep 29 22:35:19 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:35:19 +0100 (BST) Subject: [lustre-devel] [PATCH 00/34] Beginning of multi-rail support for drivers/staging/lustre In-Reply-To: <87in2v4c16.fsf@notabene.neil.brown.name> References: <153628058697.8267.6056114844033479774.stgit@noble> <87in2v4c16.fsf@notabene.neil.brown.name> Message-ID: > > Signed-off-by: Amir Shehata > > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > > Reviewed-on: http://review.whamcloud.com/18274 > > Reviewed-by: Doug Oucharek > > Reviewed-by: Olaf Weber > > Signed-off-by: NeilBrown > > Thanks for the suggestion. I don't like that approach exactly because > it seems to be a lie. The specific patch was not reviewed by those > people, and there is useful information which is not included there. > I have changed to patches to include: > > This is part of > Commit: 8cbb8cd3e771 ("LU-7734 lnet: Multi-Rail local NI split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18274 > Reviewed-by: Doug Oucharek > Reviewed-by: Olaf Weber > > checkpatch is not happy with the indented tags, but checkpatch is a > servant, not the master. To my knowledge their isn't really a policy about this. What I have been doing is kind of following how LTS versions of lustre have been handled. For LTS versions patches are cherry-picked and two additional lines are added: Lustre-change: Lustre-commit: The orginal reviews are keep. Also by including the original reviews the people involved with those patches are poked. The only requirement is that 2 people review again. Not everyone has to review for it to land. Once landed I don't see a clear why to tell who reviewed. In any case the above approach seems reasonable as long as the original author is preserve. The general rule is the original patch poster normally keeps authorship. Also I noticed patches recently pushed are not reaching the original authors and reviewers. We should make sure that still happens. From jsimmons at infradead.org Sat Sep 29 22:45:49 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:45:49 +0100 (BST) Subject: [lustre-devel] [PATCH 01/34] lnet: replace all lp_ fields with lpni_ In-Reply-To: <153783763488.32103.14222362329822520874.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763488.32103.14222362329822520874.stgit@noble> Message-ID: > sed -i 's/\blp_/lpni_/g' `git grep -l '\blp_' drivers/staging/lustre/lnet | grep '\.[ch]$'` > followed by some long-line cleanups. > > This is part of > Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek Reviewed-by: James Simmons > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 24 +- > .../staging/lustre/include/linux/lnet/lib-types.h | 63 +++--- > drivers/staging/lustre/lnet/lnet/lib-move.c | 146 +++++++------ > drivers/staging/lustre/lnet/lnet/peer.c | 125 ++++++----- > drivers/staging/lustre/lnet/lnet/router.c | 218 ++++++++++---------- > drivers/staging/lustre/lnet/lnet/router_proc.c | 52 ++--- > 6 files changed, 316 insertions(+), 312 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 5ee770cd7a5f..9b54a3d72290 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -79,10 +79,10 @@ extern struct lnet the_lnet; /* THE network */ > static inline int lnet_is_route_alive(struct lnet_route *route) > { > /* gateway is down */ > - if (!route->lr_gateway->lp_alive) > + if (!route->lr_gateway->lpni_alive) > return 0; > /* no NI status, assume it's alive */ > - if ((route->lr_gateway->lp_ping_feats & > + if ((route->lr_gateway->lpni_ping_feats & > LNET_PING_FEAT_NI_STATUS) == 0) > return 1; > /* has NI status, check # down NIs */ > @@ -313,8 +313,8 @@ lnet_handle2me(struct lnet_handle_me *handle) > static inline void > lnet_peer_addref_locked(struct lnet_peer *lp) > { > - LASSERT(lp->lp_refcount > 0); > - lp->lp_refcount++; > + LASSERT(lp->lpni_refcount > 0); > + lp->lpni_refcount++; > } > > void lnet_destroy_peer_locked(struct lnet_peer *lp); > @@ -322,16 +322,16 @@ void lnet_destroy_peer_locked(struct lnet_peer *lp); > static inline void > lnet_peer_decref_locked(struct lnet_peer *lp) > { > - LASSERT(lp->lp_refcount > 0); > - lp->lp_refcount--; > - if (!lp->lp_refcount) > + LASSERT(lp->lpni_refcount > 0); > + lp->lpni_refcount--; > + if (!lp->lpni_refcount) > lnet_destroy_peer_locked(lp); > } > > static inline int > lnet_isrouter(struct lnet_peer *lp) > { > - return lp->lp_rtr_refcount ? 1 : 0; > + return lp->lpni_rtr_refcount ? 1 : 0; > } > > static inline void > @@ -652,10 +652,10 @@ int lnet_get_peer_info(__u32 peer_index, __u64 *nid, > static inline void > lnet_peer_set_alive(struct lnet_peer *lp) > { > - lp->lp_last_query = ktime_get_seconds(); > - lp->lp_last_alive = lp->lp_last_query; > - if (!lp->lp_alive) > - lnet_notify_locked(lp, 0, 1, lp->lp_last_alive); > + lp->lpni_last_query = ktime_get_seconds(); > + lp->lpni_last_alive = lp->lpni_last_query; > + if (!lp->lpni_alive) > + lnet_notify_locked(lp, 0, 1, lp->lpni_last_alive); > } > > #endif > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 8bc72f25a897..59a1a2620675 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -385,61 +385,61 @@ struct lnet_rc_data { > > struct lnet_peer { > /* chain on peer hash */ > - struct list_head lp_hashlist; > + struct list_head lpni_hashlist; > /* messages blocking for tx credits */ > - struct list_head lp_txq; > + struct list_head lpni_txq; > /* messages blocking for router credits */ > - struct list_head lp_rtrq; > + struct list_head lpni_rtrq; > /* chain on router list */ > - struct list_head lp_rtr_list; > + struct list_head lpni_rtr_list; > /* # tx credits available */ > - int lp_txcredits; > + int lpni_txcredits; > /* low water mark */ > - int lp_mintxcredits; > + int lpni_mintxcredits; > /* # router credits */ > - int lp_rtrcredits; > + int lpni_rtrcredits; > /* low water mark */ > - int lp_minrtrcredits; > + int lpni_minrtrcredits; > /* alive/dead? */ > - unsigned int lp_alive:1; > + unsigned int lpni_alive:1; > /* notification outstanding? */ > - unsigned int lp_notify:1; > + unsigned int lpni_notify:1; > /* outstanding notification for LND? */ > - unsigned int lp_notifylnd:1; > + unsigned int lpni_notifylnd:1; > /* some thread is handling notification */ > - unsigned int lp_notifying:1; > + unsigned int lpni_notifying:1; > /* SEND event outstanding from ping */ > - unsigned int lp_ping_notsent; > + unsigned int lpni_ping_notsent; > /* # times router went dead<->alive */ > - int lp_alive_count; > + int lpni_alive_count; > /* ytes queued for sending */ > - long lp_txqnob; > + long lpni_txqnob; > /* time of last aliveness news */ > - time64_t lp_timestamp; > + time64_t lpni_timestamp; > /* time of last ping attempt */ > - time64_t lp_ping_timestamp; > + time64_t lpni_ping_timestamp; > /* != 0 if ping reply expected */ > - time64_t lp_ping_deadline; > + time64_t lpni_ping_deadline; > /* when I was last alive */ > - time64_t lp_last_alive; > - /* when lp_ni was queried last time */ > - time64_t lp_last_query; > + time64_t lpni_last_alive; > + /* when lpni_ni was queried last time */ > + time64_t lpni_last_query; > /* network peer is on */ > - struct lnet_net *lp_net; > + struct lnet_net *lpni_net; > /* peer's NID */ > - lnet_nid_t lp_nid; > + lnet_nid_t lpni_nid; > /* # refs */ > - int lp_refcount; > + int lpni_refcount; > /* CPT this peer attached on */ > - int lp_cpt; > + int lpni_cpt; > /* # refs from lnet_route::lr_gateway */ > - int lp_rtr_refcount; > + int lpni_rtr_refcount; > /* returned RC ping features */ > - unsigned int lp_ping_feats; > + unsigned int lpni_ping_feats; > /* routers on this peer */ > - struct list_head lp_routes; > + struct list_head lpni_routes; > /* router checker state */ > - struct lnet_rc_data *lp_rcd; > + struct lnet_rc_data *lpni_rcd; > }; > > /* peer hash size */ > @@ -464,8 +464,9 @@ struct lnet_peer_table { > * peer aliveness is enabled only on routers for peers in a network where the > * lnet_ni::ni_peertimeout has been set to a positive value > */ > -#define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing && \ > - (lp)->lp_net->net_tunables.lct_peer_timeout > 0) > +#define lnet_peer_aliveness_enabled(lp) \ > + (the_lnet.ln_routing && \ > + (lp)->lpni_net->net_tunables.lct_peer_timeout > 0) > > struct lnet_route { > /* chain on net */ > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index b75ebc236f3a..5879a109d46a 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -481,7 +481,7 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) > &msg->msg_private); > if (rc) { > CERROR("recv from %s / send to %s aborted: eager_recv failed %d\n", > - libcfs_nid2str(msg->msg_rxpeer->lp_nid), > + libcfs_nid2str(msg->msg_rxpeer->lpni_nid), > libcfs_id2str(msg->msg_target), rc); > LASSERT(rc < 0); /* required by my callers */ > } > @@ -498,14 +498,14 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > LASSERT(lnet_peer_aliveness_enabled(lp)); > LASSERT(ni->ni_net->net_lnd->lnd_query); > > - lnet_net_unlock(lp->lp_cpt); > - ni->ni_net->net_lnd->lnd_query(ni, lp->lp_nid, &last_alive); > - lnet_net_lock(lp->lp_cpt); > + lnet_net_unlock(lp->lpni_cpt); > + ni->ni_net->net_lnd->lnd_query(ni, lp->lpni_nid, &last_alive); > + lnet_net_lock(lp->lpni_cpt); > > - lp->lp_last_query = ktime_get_seconds(); > + lp->lpni_last_query = ktime_get_seconds(); > > if (last_alive) /* NI has updated timestamp */ > - lp->lp_last_alive = last_alive; > + lp->lpni_last_alive = last_alive; > } > > /* NB: always called with lnet_net_lock held */ > @@ -520,21 +520,21 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) > /* Trust lnet_notify() if it has more recent aliveness news, but > * ignore the initial assumed death (see lnet_peers_start_down()). > */ > - if (!lp->lp_alive && lp->lp_alive_count > 0 && > - lp->lp_timestamp >= lp->lp_last_alive) > + if (!lp->lpni_alive && lp->lpni_alive_count > 0 && > + lp->lpni_timestamp >= lp->lpni_last_alive) > return 0; > > - deadline = lp->lp_last_alive + > - lp->lp_net->net_tunables.lct_peer_timeout; > + deadline = lp->lpni_last_alive + > + lp->lpni_net->net_tunables.lct_peer_timeout; > alive = deadline > now; > > - /* Update obsolete lp_alive except for routers assumed to be dead > + /* Update obsolete lpni_alive except for routers assumed to be dead > * initially, because router checker would update aliveness in this > - * case, and moreover lp_last_alive at peer creation is assumed. > + * case, and moreover lpni_last_alive at peer creation is assumed. > */ > - if (alive && !lp->lp_alive && > - !(lnet_isrouter(lp) && !lp->lp_alive_count)) > - lnet_notify_locked(lp, 0, 1, lp->lp_last_alive); > + if (alive && !lp->lpni_alive && > + !(lnet_isrouter(lp) && !lp->lpni_alive_count)) > + lnet_notify_locked(lp, 0, 1, lp->lpni_last_alive); > > return alive; > } > @@ -558,19 +558,19 @@ lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) > * Peer appears dead, but we should avoid frequent NI queries (at > * most once per lnet_queryinterval seconds). > */ > - if (lp->lp_last_query) { > + if (lp->lpni_last_query) { > static const int lnet_queryinterval = 1; > time64_t next_query; > > - next_query = lp->lp_last_query + lnet_queryinterval; > + next_query = lp->lpni_last_query + lnet_queryinterval; > > if (now < next_query) { > - if (lp->lp_alive) > + if (lp->lpni_alive) > CWARN("Unexpected aliveness of peer %s: %lld < %lld (%d/%d)\n", > - libcfs_nid2str(lp->lp_nid), > + libcfs_nid2str(lp->lpni_nid), > now, next_query, > lnet_queryinterval, > - lp->lp_net->net_tunables.lct_peer_timeout); > + lp->lpni_net->net_tunables.lct_peer_timeout); > return 0; > } > } > @@ -581,7 +581,7 @@ lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) > if (lnet_peer_is_alive(lp, now)) > return 1; > > - lnet_notify_locked(lp, 0, 0, lp->lp_last_alive); > + lnet_notify_locked(lp, 0, 0, lp->lpni_last_alive); > return 0; > } > > @@ -639,19 +639,19 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) > } > > if (!msg->msg_peertxcredit) { > - LASSERT((lp->lp_txcredits < 0) == > - !list_empty(&lp->lp_txq)); > + LASSERT((lp->lpni_txcredits < 0) == > + !list_empty(&lp->lpni_txq)); > > msg->msg_peertxcredit = 1; > - lp->lp_txqnob += msg->msg_len + sizeof(struct lnet_hdr); > - lp->lp_txcredits--; > + lp->lpni_txqnob += msg->msg_len + sizeof(struct lnet_hdr); > + lp->lpni_txcredits--; > > - if (lp->lp_txcredits < lp->lp_mintxcredits) > - lp->lp_mintxcredits = lp->lp_txcredits; > + if (lp->lpni_txcredits < lp->lpni_mintxcredits) > + lp->lpni_mintxcredits = lp->lpni_txcredits; > > - if (lp->lp_txcredits < 0) { > + if (lp->lpni_txcredits < 0) { > msg->msg_tx_delayed = 1; > - list_add_tail(&msg->msg_list, &lp->lp_txq); > + list_add_tail(&msg->msg_list, &lp->lpni_txq); > return LNET_CREDIT_WAIT; > } > } > @@ -725,19 +725,19 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) > LASSERT(!do_recv || msg->msg_rx_delayed); > > if (!msg->msg_peerrtrcredit) { > - LASSERT((lp->lp_rtrcredits < 0) == > - !list_empty(&lp->lp_rtrq)); > + LASSERT((lp->lpni_rtrcredits < 0) == > + !list_empty(&lp->lpni_rtrq)); > > msg->msg_peerrtrcredit = 1; > - lp->lp_rtrcredits--; > - if (lp->lp_rtrcredits < lp->lp_minrtrcredits) > - lp->lp_minrtrcredits = lp->lp_rtrcredits; > + lp->lpni_rtrcredits--; > + if (lp->lpni_rtrcredits < lp->lpni_minrtrcredits) > + lp->lpni_minrtrcredits = lp->lpni_rtrcredits; > > - if (lp->lp_rtrcredits < 0) { > + if (lp->lpni_rtrcredits < 0) { > /* must have checked eager_recv before here */ > LASSERT(msg->msg_rx_ready_delay); > msg->msg_rx_delayed = 1; > - list_add_tail(&msg->msg_list, &lp->lp_rtrq); > + list_add_tail(&msg->msg_list, &lp->lpni_rtrq); > return LNET_CREDIT_WAIT; > } > } > @@ -811,15 +811,15 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > /* give back peer txcredits */ > msg->msg_peertxcredit = 0; > > - LASSERT((txpeer->lp_txcredits < 0) == > - !list_empty(&txpeer->lp_txq)); > + LASSERT((txpeer->lpni_txcredits < 0) == > + !list_empty(&txpeer->lpni_txq)); > > - txpeer->lp_txqnob -= msg->msg_len + sizeof(struct lnet_hdr); > - LASSERT(txpeer->lp_txqnob >= 0); > + txpeer->lpni_txqnob -= msg->msg_len + sizeof(struct lnet_hdr); > + LASSERT(txpeer->lpni_txqnob >= 0); > > - txpeer->lp_txcredits++; > - if (txpeer->lp_txcredits <= 0) { > - msg2 = list_entry(txpeer->lp_txq.next, > + txpeer->lpni_txcredits++; > + if (txpeer->lpni_txcredits <= 0) { > + msg2 = list_entry(txpeer->lpni_txq.next, > struct lnet_msg, msg_list); > list_del(&msg2->msg_list); > > @@ -939,19 +939,19 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) > /* give back peer router credits */ > msg->msg_peerrtrcredit = 0; > > - LASSERT((rxpeer->lp_rtrcredits < 0) == > - !list_empty(&rxpeer->lp_rtrq)); > + LASSERT((rxpeer->lpni_rtrcredits < 0) == > + !list_empty(&rxpeer->lpni_rtrq)); > > - rxpeer->lp_rtrcredits++; > + rxpeer->lpni_rtrcredits++; > /* > * drop all messages which are queued to be routed on that > * peer. > */ > if (!the_lnet.ln_routing) { > - lnet_drop_routed_msgs_locked(&rxpeer->lp_rtrq, > + lnet_drop_routed_msgs_locked(&rxpeer->lpni_rtrq, > msg->msg_rx_cpt); > - } else if (rxpeer->lp_rtrcredits <= 0) { > - msg2 = list_entry(rxpeer->lp_rtrq.next, > + } else if (rxpeer->lpni_rtrcredits <= 0) { > + msg2 = list_entry(rxpeer->lpni_rtrq.next, > struct lnet_msg, msg_list); > list_del(&msg2->msg_list); > > @@ -988,16 +988,16 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) > if (r1_hops > r2_hops) > return -ERANGE; > > - if (p1->lp_txqnob < p2->lp_txqnob) > + if (p1->lpni_txqnob < p2->lpni_txqnob) > return 1; > > - if (p1->lp_txqnob > p2->lp_txqnob) > + if (p1->lpni_txqnob > p2->lpni_txqnob) > return -ERANGE; > > - if (p1->lp_txcredits > p2->lp_txcredits) > + if (p1->lpni_txcredits > p2->lpni_txcredits) > return 1; > > - if (p1->lp_txcredits < p2->lp_txcredits) > + if (p1->lpni_txcredits < p2->lpni_txcredits) > return -ERANGE; > > if (r1->lr_seq - r2->lr_seq <= 0) > @@ -1014,7 +1014,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > struct lnet_route *route; > struct lnet_route *best_route; > struct lnet_route *last_route; > - struct lnet_peer *lp_best; > + struct lnet_peer *lpni_best; > struct lnet_peer *lp; > int rc; > > @@ -1026,7 +1026,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > if (!rnet) > return NULL; > > - lp_best = NULL; > + lpni_best = NULL; > best_route = NULL; > last_route = NULL; > list_for_each_entry(route, &rnet->lrn_routes, lr_list) { > @@ -1035,16 +1035,16 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > if (!lnet_is_route_alive(route)) > continue; > > - if (net && lp->lp_net != net) > + if (net && lp->lpni_net != net) > continue; > > - if (lp->lp_nid == rtr_nid) /* it's pre-determined router */ > + if (lp->lpni_nid == rtr_nid) /* it's pre-determined router */ > return lp; > > - if (!lp_best) { > + if (!lpni_best) { > best_route = route; > last_route = route; > - lp_best = lp; > + lpni_best = lp; > continue; > } > > @@ -1057,7 +1057,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > continue; > > best_route = route; > - lp_best = lp; > + lpni_best = lp; > } > > /* > @@ -1067,7 +1067,7 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > */ > if (best_route) > best_route->lr_seq = last_route->lr_seq + 1; > - return lp_best; > + return lpni_best; > } > > int > @@ -1156,7 +1156,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > /* ENOMEM or shutting down */ > return rc; > } > - LASSERT(lp->lp_net == src_ni->ni_net); > + LASSERT(lp->lpni_net == src_ni->ni_net); > } else { > /* sending to a remote network */ > lp = lnet_find_route_locked(src_ni ? src_ni->ni_net : NULL, > @@ -1176,27 +1176,27 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > * pre-determined router, this can happen if router table > * was changed when we release the lock > */ > - if (rtr_nid != lp->lp_nid) { > - cpt2 = lp->lp_cpt; > + if (rtr_nid != lp->lpni_nid) { > + cpt2 = lp->lpni_cpt; > if (cpt2 != cpt) { > lnet_net_unlock(cpt); > > - rtr_nid = lp->lp_nid; > + rtr_nid = lp->lpni_nid; > cpt = cpt2; > goto again; > } > } > > CDEBUG(D_NET, "Best route to %s via %s for %s %d\n", > - libcfs_nid2str(dst_nid), libcfs_nid2str(lp->lp_nid), > + libcfs_nid2str(dst_nid), libcfs_nid2str(lp->lpni_nid), > lnet_msgtyp2str(msg->msg_type), msg->msg_len); > > if (!src_ni) { > - src_ni = lnet_get_next_ni_locked(lp->lp_net, NULL); > + src_ni = lnet_get_next_ni_locked(lp->lpni_net, NULL); > LASSERT(src_ni); > src_nid = src_ni->ni_nid; > } else { > - LASSERT(src_ni->ni_net == lp->lp_net); > + LASSERT(src_ni->ni_net == lp->lpni_net); > } > > lnet_peer_addref_locked(lp); > @@ -1210,7 +1210,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > } > > msg->msg_target_is_router = 1; > - msg->msg_target.nid = lp->lp_nid; > + msg->msg_target.nid = lp->lpni_nid; > msg->msg_target.pid = LNET_PID_LUSTRE; > } > > @@ -1289,7 +1289,7 @@ lnet_parse_put(struct lnet_ni *ni, struct lnet_msg *msg) > info.mi_rlength = hdr->payload_length; > info.mi_roffset = hdr->msg.put.offset; > info.mi_mbits = hdr->msg.put.match_bits; > - info.mi_cpt = msg->msg_rxpeer->lp_cpt; > + info.mi_cpt = msg->msg_rxpeer->lpni_cpt; > > msg->msg_rx_ready_delay = !ni->ni_net->net_lnd->lnd_eager_recv; > ready_delay = msg->msg_rx_ready_delay; > @@ -1520,7 +1520,7 @@ lnet_parse_forward_locked(struct lnet_ni *ni, struct lnet_msg *msg) > if (!the_lnet.ln_routing) > return -ECANCELED; > > - if (msg->msg_rxpeer->lp_rtrcredits <= 0 || > + if (msg->msg_rxpeer->lpni_rtrcredits <= 0 || > lnet_msg2bufpool(msg)->rbp_credits <= 0) { > if (!ni->ni_net->net_lnd->lnd_eager_recv) { > msg->msg_rx_ready_delay = 1; > @@ -1909,7 +1909,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) > * until that's done > */ > lnet_drop_message(msg->msg_rxni, > - msg->msg_rxpeer->lp_cpt, > + msg->msg_rxpeer->lpni_cpt, > msg->msg_private, msg->msg_len); > /* > * NB: message will not generate event because w/o attached MD, > @@ -2376,7 +2376,7 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp) > hops = shortest_hops; > if (srcnidp) { > ni = lnet_get_next_ni_locked( > - shortest->lr_gateway->lp_net, > + shortest->lr_gateway->lpni_net, > NULL); > *srcnidp = ni->ni_nid; > } > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index 42bc35010f64..619d016b1d89 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -111,10 +111,10 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, > > for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { > list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], > - lp_hashlist) { > - if (ni && ni->ni_net != lp->lp_net) > + lpni_hashlist) { > + if (ni && ni->ni_net != lp->lpni_net) > continue; > - list_del_init(&lp->lp_hashlist); > + list_del_init(&lp->lpni_hashlist); > /* Lose hash table's ref */ > ptable->pt_zombies++; > lnet_peer_decref_locked(lp); > @@ -148,22 +148,22 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, > { > struct lnet_peer *lp; > struct lnet_peer *tmp; > - lnet_nid_t lp_nid; > + lnet_nid_t lpni_nid; > int i; > > for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { > list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], > - lp_hashlist) { > - if (ni->ni_net != lp->lp_net) > + lpni_hashlist) { > + if (ni->ni_net != lp->lpni_net) > continue; > > - if (!lp->lp_rtr_refcount) > + if (!lp->lpni_rtr_refcount) > continue; > > - lp_nid = lp->lp_nid; > + lpni_nid = lp->lpni_nid; > > lnet_net_unlock(cpt_locked); > - lnet_del_route(LNET_NIDNET(LNET_NID_ANY), lp_nid); > + lnet_del_route(LNET_NIDNET(LNET_NID_ANY), lpni_nid); > lnet_net_lock(cpt_locked); > } > } > @@ -209,8 +209,8 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > } > > while (!list_empty(&deathrow)) { > - lp = list_entry(deathrow.next, struct lnet_peer, lp_hashlist); > - list_del(&lp->lp_hashlist); > + lp = list_entry(deathrow.next, struct lnet_peer, lpni_hashlist); > + list_del(&lp->lpni_hashlist); > kfree(lp); > } > } > @@ -220,19 +220,19 @@ lnet_destroy_peer_locked(struct lnet_peer *lp) > { > struct lnet_peer_table *ptable; > > - LASSERT(!lp->lp_refcount); > - LASSERT(!lp->lp_rtr_refcount); > - LASSERT(list_empty(&lp->lp_txq)); > - LASSERT(list_empty(&lp->lp_hashlist)); > - LASSERT(!lp->lp_txqnob); > + LASSERT(!lp->lpni_refcount); > + LASSERT(!lp->lpni_rtr_refcount); > + LASSERT(list_empty(&lp->lpni_txq)); > + LASSERT(list_empty(&lp->lpni_hashlist)); > + LASSERT(!lp->lpni_txqnob); > > - ptable = the_lnet.ln_peer_tables[lp->lp_cpt]; > + ptable = the_lnet.ln_peer_tables[lp->lpni_cpt]; > LASSERT(ptable->pt_number > 0); > ptable->pt_number--; > > - lp->lp_net = NULL; > + lp->lpni_net = NULL; > > - list_add(&lp->lp_hashlist, &ptable->pt_deathrow); > + list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); > LASSERT(ptable->pt_zombies > 0); > ptable->pt_zombies--; > } > @@ -246,8 +246,8 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) > LASSERT(!the_lnet.ln_shutdown); > > peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; > - list_for_each_entry(lp, peers, lp_hashlist) { > - if (lp->lp_nid == nid) { > + list_for_each_entry(lp, peers, lpni_hashlist) { > + if (lp->lpni_nid == nid) { > lnet_peer_addref_locked(lp); > return lp; > } > @@ -281,8 +281,8 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > > if (!list_empty(&ptable->pt_deathrow)) { > lp = list_entry(ptable->pt_deathrow.next, > - struct lnet_peer, lp_hashlist); > - list_del(&lp->lp_hashlist); > + struct lnet_peer, lpni_hashlist); > + list_del(&lp->lpni_hashlist); > } > > /* > @@ -303,24 +303,24 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > goto out; > } > > - INIT_LIST_HEAD(&lp->lp_txq); > - INIT_LIST_HEAD(&lp->lp_rtrq); > - INIT_LIST_HEAD(&lp->lp_routes); > - > - lp->lp_notify = 0; > - lp->lp_notifylnd = 0; > - lp->lp_notifying = 0; > - lp->lp_alive_count = 0; > - lp->lp_timestamp = 0; > - lp->lp_alive = !lnet_peers_start_down(); /* 1 bit!! */ > - lp->lp_last_alive = ktime_get_seconds(); /* assumes alive */ > - lp->lp_last_query = 0; /* haven't asked NI yet */ > - lp->lp_ping_timestamp = 0; > - lp->lp_ping_feats = LNET_PING_FEAT_INVAL; > - lp->lp_nid = nid; > - lp->lp_cpt = cpt2; > - lp->lp_refcount = 2; /* 1 for caller; 1 for hash */ > - lp->lp_rtr_refcount = 0; > + INIT_LIST_HEAD(&lp->lpni_txq); > + INIT_LIST_HEAD(&lp->lpni_rtrq); > + INIT_LIST_HEAD(&lp->lpni_routes); > + > + lp->lpni_notify = 0; > + lp->lpni_notifylnd = 0; > + lp->lpni_notifying = 0; > + lp->lpni_alive_count = 0; > + lp->lpni_timestamp = 0; > + lp->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ > + lp->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ > + lp->lpni_last_query = 0; /* haven't asked NI yet */ > + lp->lpni_ping_timestamp = 0; > + lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; > + lp->lpni_nid = nid; > + lp->lpni_cpt = cpt2; > + lp->lpni_refcount = 2; /* 1 for caller; 1 for hash */ > + lp->lpni_rtr_refcount = 0; > > lnet_net_lock(cpt); > > @@ -335,13 +335,14 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > goto out; > } > > - lp->lp_net = lnet_get_net_locked(LNET_NIDNET(lp->lp_nid)); > - lp->lp_txcredits = > - lp->lp_mintxcredits = lp->lp_net->net_tunables.lct_peer_tx_credits; > - lp->lp_rtrcredits = > - lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_net); > + lp->lpni_net = lnet_get_net_locked(LNET_NIDNET(lp->lpni_nid)); > + lp->lpni_txcredits = > + lp->lpni_mintxcredits = > + lp->lpni_net->net_tunables.lct_peer_tx_credits; > + lp->lpni_rtrcredits = > + lp->lpni_minrtrcredits = lnet_peer_buffer_credits(lp->lpni_net); > > - list_add_tail(&lp->lp_hashlist, > + list_add_tail(&lp->lpni_hashlist, > &ptable->pt_hash[lnet_nid2peerhash(nid)]); > ptable->pt_version++; > *lpp = lp; > @@ -349,7 +350,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > return 0; > out: > if (lp) > - list_add(&lp->lp_hashlist, &ptable->pt_deathrow); > + list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); > ptable->pt_number--; > return rc; > } > @@ -373,13 +374,13 @@ lnet_debug_peer(lnet_nid_t nid) > } > > if (lnet_isrouter(lp) || lnet_peer_aliveness_enabled(lp)) > - aliveness = lp->lp_alive ? "up" : "down"; > + aliveness = lp->lpni_alive ? "up" : "down"; > > CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", > - libcfs_nid2str(lp->lp_nid), lp->lp_refcount, > - aliveness, lp->lp_net->net_tunables.lct_peer_tx_credits, > - lp->lp_rtrcredits, lp->lp_minrtrcredits, > - lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob); > + libcfs_nid2str(lp->lpni_nid), lp->lpni_refcount, > + aliveness, lp->lpni_net->net_tunables.lct_peer_tx_credits, > + lp->lpni_rtrcredits, lp->lpni_minrtrcredits, > + lp->lpni_txcredits, lp->lpni_mintxcredits, lp->lpni_txqnob); > > lnet_peer_decref_locked(lp); > > @@ -420,7 +421,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, > for (j = 0; j < LNET_PEER_HASH_SIZE && !found; j++) { > struct list_head *peers = &peer_table->pt_hash[j]; > > - list_for_each_entry(lp, peers, lp_hashlist) { > + list_for_each_entry(lp, peers, lpni_hashlist) { > if (peer_index-- > 0) > continue; > > @@ -428,16 +429,16 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, > if (lnet_isrouter(lp) || > lnet_peer_aliveness_enabled(lp)) > snprintf(aliveness, LNET_MAX_STR_LEN, > - lp->lp_alive ? "up" : "down"); > + lp->lpni_alive ? "up" : "down"); > > - *nid = lp->lp_nid; > - *refcount = lp->lp_refcount; > + *nid = lp->lpni_nid; > + *refcount = lp->lpni_refcount; > *ni_peer_tx_credits = > - lp->lp_net->net_tunables.lct_peer_tx_credits; > - *peer_tx_credits = lp->lp_txcredits; > - *peer_rtr_credits = lp->lp_rtrcredits; > - *peer_min_rtr_credits = lp->lp_mintxcredits; > - *peer_tx_qnob = lp->lp_txqnob; > + lp->lpni_net->net_tunables.lct_peer_tx_credits; > + *peer_tx_credits = lp->lpni_txcredits; > + *peer_rtr_credits = lp->lpni_rtrcredits; > + *peer_min_rtr_credits = lp->lpni_mintxcredits; > + *peer_tx_qnob = lp->lpni_txqnob; > > found = true; > } > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 2bbd1cf86a8c..2be1ffb6b720 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -103,30 +103,30 @@ void > lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, > time64_t when) > { > - if (lp->lp_timestamp > when) { /* out of date information */ > + if (lp->lpni_timestamp > when) { /* out of date information */ > CDEBUG(D_NET, "Out of date\n"); > return; > } > > - lp->lp_timestamp = when; /* update timestamp */ > - lp->lp_ping_deadline = 0; /* disable ping timeout */ > + lp->lpni_timestamp = when; /* update timestamp */ > + lp->lpni_ping_deadline = 0; /* disable ping timeout */ > > - if (lp->lp_alive_count && /* got old news */ > - (!lp->lp_alive) == (!alive)) { /* new date for old news */ > + if (lp->lpni_alive_count && /* got old news */ > + (!lp->lpni_alive) == (!alive)) { /* new date for old news */ > CDEBUG(D_NET, "Old news\n"); > return; > } > > /* Flag that notification is outstanding */ > > - lp->lp_alive_count++; > - lp->lp_alive = !(!alive); /* 1 bit! */ > - lp->lp_notify = 1; > - lp->lp_notifylnd |= notifylnd; > - if (lp->lp_alive) > - lp->lp_ping_feats = LNET_PING_FEAT_INVAL; /* reset */ > + lp->lpni_alive_count++; > + lp->lpni_alive = !(!alive); /* 1 bit! */ > + lp->lpni_notify = 1; > + lp->lpni_notifylnd |= notifylnd; > + if (lp->lpni_alive) > + lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; /* reset */ > > - CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lp_nid), alive); > + CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lpni_nid), alive); > } > > static void > @@ -140,55 +140,56 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > * NB individual events can be missed; the only guarantee is that you > * always get the most recent news > */ > - if (lp->lp_notifying || !ni) > + if (lp->lpni_notifying || !ni) > return; > > - lp->lp_notifying = 1; > + lp->lpni_notifying = 1; > > - while (lp->lp_notify) { > - alive = lp->lp_alive; > - notifylnd = lp->lp_notifylnd; > + while (lp->lpni_notify) { > + alive = lp->lpni_alive; > + notifylnd = lp->lpni_notifylnd; > > - lp->lp_notifylnd = 0; > - lp->lp_notify = 0; > + lp->lpni_notifylnd = 0; > + lp->lpni_notify = 0; > > if (notifylnd && ni->ni_net->net_lnd->lnd_notify) { > - lnet_net_unlock(lp->lp_cpt); > + lnet_net_unlock(lp->lpni_cpt); > > /* > * A new notification could happen now; I'll handle it > * when control returns to me > */ > - ni->ni_net->net_lnd->lnd_notify(ni, lp->lp_nid, alive); > + ni->ni_net->net_lnd->lnd_notify(ni, lp->lpni_nid, > + alive); > > - lnet_net_lock(lp->lp_cpt); > + lnet_net_lock(lp->lpni_cpt); > } > } > > - lp->lp_notifying = 0; > + lp->lpni_notifying = 0; > } > > static void > lnet_rtr_addref_locked(struct lnet_peer *lp) > { > - LASSERT(lp->lp_refcount > 0); > - LASSERT(lp->lp_rtr_refcount >= 0); > + LASSERT(lp->lpni_refcount > 0); > + LASSERT(lp->lpni_rtr_refcount >= 0); > > /* lnet_net_lock must be exclusively locked */ > - lp->lp_rtr_refcount++; > - if (lp->lp_rtr_refcount == 1) { > + lp->lpni_rtr_refcount++; > + if (lp->lpni_rtr_refcount == 1) { > struct list_head *pos; > > /* a simple insertion sort */ > list_for_each_prev(pos, &the_lnet.ln_routers) { > struct lnet_peer *rtr; > > - rtr = list_entry(pos, struct lnet_peer, lp_rtr_list); > - if (rtr->lp_nid < lp->lp_nid) > + rtr = list_entry(pos, struct lnet_peer, lpni_rtr_list); > + if (rtr->lpni_nid < lp->lpni_nid) > break; > } > > - list_add(&lp->lp_rtr_list, pos); > + list_add(&lp->lpni_rtr_list, pos); > /* addref for the_lnet.ln_routers */ > lnet_peer_addref_locked(lp); > the_lnet.ln_routers_version++; > @@ -198,21 +199,21 @@ lnet_rtr_addref_locked(struct lnet_peer *lp) > static void > lnet_rtr_decref_locked(struct lnet_peer *lp) > { > - LASSERT(lp->lp_refcount > 0); > - LASSERT(lp->lp_rtr_refcount > 0); > + LASSERT(lp->lpni_refcount > 0); > + LASSERT(lp->lpni_rtr_refcount > 0); > > /* lnet_net_lock must be exclusively locked */ > - lp->lp_rtr_refcount--; > - if (!lp->lp_rtr_refcount) { > - LASSERT(list_empty(&lp->lp_routes)); > + lp->lpni_rtr_refcount--; > + if (!lp->lpni_rtr_refcount) { > + LASSERT(list_empty(&lp->lpni_routes)); > > - if (lp->lp_rcd) { > - list_add(&lp->lp_rcd->rcd_list, > + if (lp->lpni_rcd) { > + list_add(&lp->lpni_rcd->rcd_list, > &the_lnet.ln_rcd_deathrow); > - lp->lp_rcd = NULL; > + lp->lpni_rcd = NULL; > } > > - list_del(&lp->lp_rtr_list); > + list_del(&lp->lpni_rtr_list); > /* decref for the_lnet.ln_routers */ > lnet_peer_decref_locked(lp); > the_lnet.ln_routers_version++; > @@ -279,7 +280,7 @@ lnet_add_route_to_rnet(struct lnet_remotenet *rnet, struct lnet_route *route) > offset--; > } > list_add(&route->lr_list, e); > - list_add(&route->lr_gwlist, &route->lr_gateway->lp_routes); > + list_add(&route->lr_gwlist, &route->lr_gateway->lpni_routes); > > the_lnet.ln_remote_nets_version++; > lnet_rtr_addref_locked(route->lr_gateway); > @@ -364,14 +365,14 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > } > > /* our lookups must be true */ > - LASSERT(route2->lr_gateway->lp_nid != gateway); > + LASSERT(route2->lr_gateway->lpni_nid != gateway); > } > > if (add_route) { > lnet_peer_addref_locked(route->lr_gateway); /* +1 for notify */ > lnet_add_route_to_rnet(rnet2, route); > > - ni = lnet_get_next_ni_locked(route->lr_gateway->lp_net, NULL); > + ni = lnet_get_next_ni_locked(route->lr_gateway->lpni_net, NULL); > lnet_net_unlock(LNET_LOCK_EX); > > /* XXX Assume alive */ > @@ -426,12 +427,12 @@ lnet_check_routes(void) > continue; > } > > - if (route->lr_gateway->lp_net == > - route2->lr_gateway->lp_net) > + if (route->lr_gateway->lpni_net == > + route2->lr_gateway->lpni_net) > continue; > > - nid1 = route->lr_gateway->lp_nid; > - nid2 = route2->lr_gateway->lp_nid; > + nid1 = route->lr_gateway->lpni_nid; > + nid2 = route2->lr_gateway->lpni_nid; > net = rnet->lrn_net; > > lnet_net_unlock(cpt); > @@ -481,7 +482,7 @@ lnet_del_route(__u32 net, lnet_nid_t gw_nid) > list_for_each_entry(route, &rnet->lrn_routes, lr_list) { > gateway = route->lr_gateway; > if (!(gw_nid == LNET_NID_ANY || > - gw_nid == gateway->lp_nid)) > + gw_nid == gateway->lpni_nid)) > continue; > > list_del(&route->lr_list); > @@ -575,7 +576,7 @@ lnet_get_route(int idx, __u32 *net, __u32 *hops, > *net = rnet->lrn_net; > *hops = route->lr_hops; > *priority = route->lr_priority; > - *gateway = route->lr_gateway->lp_nid; > + *gateway = route->lr_gateway->lpni_nid; > *alive = lnet_is_route_alive(route); > lnet_net_unlock(cpt); > return 0; > @@ -616,7 +617,7 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) > struct lnet_peer *gw = rcd->rcd_gateway; > struct lnet_route *rte; > > - if (!gw->lp_alive) > + if (!gw->lpni_alive) > return; > > if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) > @@ -625,27 +626,27 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) > /* NB always racing with network! */ > if (info->pi_magic != LNET_PROTO_PING_MAGIC) { > CDEBUG(D_NET, "%s: Unexpected magic %08x\n", > - libcfs_nid2str(gw->lp_nid), info->pi_magic); > - gw->lp_ping_feats = LNET_PING_FEAT_INVAL; > + libcfs_nid2str(gw->lpni_nid), info->pi_magic); > + gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; > return; > } > > - gw->lp_ping_feats = info->pi_features; > - if (!(gw->lp_ping_feats & LNET_PING_FEAT_MASK)) { > + gw->lpni_ping_feats = info->pi_features; > + if (!(gw->lpni_ping_feats & LNET_PING_FEAT_MASK)) { > CDEBUG(D_NET, "%s: Unexpected features 0x%x\n", > - libcfs_nid2str(gw->lp_nid), gw->lp_ping_feats); > + libcfs_nid2str(gw->lpni_nid), gw->lpni_ping_feats); > return; /* nothing I can understand */ > } > > - if (!(gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS)) > + if (!(gw->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS)) > return; /* can't carry NI status info */ > > - list_for_each_entry(rte, &gw->lp_routes, lr_gwlist) { > + list_for_each_entry(rte, &gw->lpni_routes, lr_gwlist) { > int down = 0; > int up = 0; > int i; > > - if (gw->lp_ping_feats & LNET_PING_FEAT_RTE_DISABLED) { > + if (gw->lpni_ping_feats & LNET_PING_FEAT_RTE_DISABLED) { > rte->lr_downis = 1; > continue; > } > @@ -656,8 +657,8 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) > > if (nid == LNET_NID_ANY) { > CDEBUG(D_NET, "%s: unexpected LNET_NID_ANY\n", > - libcfs_nid2str(gw->lp_nid)); > - gw->lp_ping_feats = LNET_PING_FEAT_INVAL; > + libcfs_nid2str(gw->lpni_nid)); > + gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; > return; > } > > @@ -678,8 +679,8 @@ lnet_parse_rc_info(struct lnet_rc_data *rcd) > } > > CDEBUG(D_NET, "%s: Unexpected status 0x%x\n", > - libcfs_nid2str(gw->lp_nid), stat->ns_status); > - gw->lp_ping_feats = LNET_PING_FEAT_INVAL; > + libcfs_nid2str(gw->lpni_nid), stat->ns_status); > + gw->lpni_ping_feats = LNET_PING_FEAT_INVAL; > return; > } > > @@ -722,14 +723,14 @@ lnet_router_checker_event(struct lnet_event *event) > * places need to hold both locks at the same time, please take > * care of lock ordering > */ > - lnet_net_lock(lp->lp_cpt); > - if (!lnet_isrouter(lp) || lp->lp_rcd != rcd) { > + lnet_net_lock(lp->lpni_cpt); > + if (!lnet_isrouter(lp) || lp->lpni_rcd != rcd) { > /* ignore if no longer a router or rcd is replaced */ > goto out; > } > > if (event->type == LNET_EVENT_SEND) { > - lp->lp_ping_notsent = 0; > + lp->lpni_ping_notsent = 0; > if (!event->status) > goto out; > } > @@ -753,7 +754,7 @@ lnet_router_checker_event(struct lnet_event *event) > lnet_parse_rc_info(rcd); > > out: > - lnet_net_unlock(lp->lp_cpt); > + lnet_net_unlock(lp->lpni_cpt); > } > > static void > @@ -768,8 +769,8 @@ lnet_wait_known_routerstate(void) > int cpt = lnet_net_lock_current(); > > all_known = 1; > - list_for_each_entry(rtr, &the_lnet.ln_routers, lp_rtr_list) { > - if (!rtr->lp_alive_count) { > + list_for_each_entry(rtr, &the_lnet.ln_routers, lpni_rtr_list) { > + if (!rtr->lpni_alive_count) { > all_known = 0; > break; > } > @@ -789,8 +790,8 @@ lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) > { > struct lnet_route *rte; > > - if ((gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS)) { > - list_for_each_entry(rte, &gw->lp_routes, lr_gwlist) { > + if ((gw->lpni_ping_feats & LNET_PING_FEAT_NI_STATUS)) { > + list_for_each_entry(rte, &gw->lpni_routes, lr_gwlist) { > if (rte->lr_net == net) { > rte->lr_downis = 0; > break; > @@ -849,7 +850,7 @@ lnet_destroy_rc_data(struct lnet_rc_data *rcd) > LASSERT(LNetMDHandleIsInvalid(rcd->rcd_mdh)); > > if (rcd->rcd_gateway) { > - int cpt = rcd->rcd_gateway->lp_cpt; > + int cpt = rcd->rcd_gateway->lpni_cpt; > > lnet_net_lock(cpt); > lnet_peer_decref_locked(rcd->rcd_gateway); > @@ -870,7 +871,7 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) > int rc; > int i; > > - lnet_net_unlock(gateway->lp_cpt); > + lnet_net_unlock(gateway->lpni_cpt); > > rcd = kzalloc(sizeof(*rcd), GFP_NOFS); > if (!rcd) > @@ -904,17 +905,17 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) > } > LASSERT(!rc); > > - lnet_net_lock(gateway->lp_cpt); > + lnet_net_lock(gateway->lpni_cpt); > /* router table changed or someone has created rcd for this gateway */ > - if (!lnet_isrouter(gateway) || gateway->lp_rcd) { > - lnet_net_unlock(gateway->lp_cpt); > + if (!lnet_isrouter(gateway) || gateway->lpni_rcd) { > + lnet_net_unlock(gateway->lpni_cpt); > goto out; > } > > lnet_peer_addref_locked(gateway); > rcd->rcd_gateway = gateway; > - gateway->lp_rcd = rcd; > - gateway->lp_ping_notsent = 0; > + gateway->lpni_rcd = rcd; > + gateway->lpni_ping_notsent = 0; > > return rcd; > > @@ -927,8 +928,8 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) > lnet_destroy_rc_data(rcd); > } > > - lnet_net_lock(gateway->lp_cpt); > - return gateway->lp_rcd; > + lnet_net_lock(gateway->lpni_cpt); > + return gateway->lpni_rcd; > } > > static int > @@ -936,7 +937,7 @@ lnet_router_check_interval(struct lnet_peer *rtr) > { > int secs; > > - secs = rtr->lp_alive ? live_router_check_interval : > + secs = rtr->lpni_alive ? live_router_check_interval : > dead_router_check_interval; > if (secs < 0) > secs = 0; > @@ -954,12 +955,12 @@ lnet_ping_router_locked(struct lnet_peer *rtr) > > lnet_peer_addref_locked(rtr); > > - if (rtr->lp_ping_deadline && /* ping timed out? */ > - now > rtr->lp_ping_deadline) > + if (rtr->lpni_ping_deadline && /* ping timed out? */ > + now > rtr->lpni_ping_deadline) > lnet_notify_locked(rtr, 1, 0, now); > > /* Run any outstanding notifications */ > - ni = lnet_get_next_ni_locked(rtr->lp_net, NULL); > + ni = lnet_get_next_ni_locked(rtr->lpni_net, NULL); > lnet_ni_notify_locked(ni, rtr); > > if (!lnet_isrouter(rtr) || > @@ -969,8 +970,8 @@ lnet_ping_router_locked(struct lnet_peer *rtr) > return; > } > > - rcd = rtr->lp_rcd ? > - rtr->lp_rcd : lnet_create_rc_data_locked(rtr); > + rcd = rtr->lpni_rcd ? > + rtr->lpni_rcd : lnet_create_rc_data_locked(rtr); > > if (!rcd) > return; > @@ -978,39 +979,40 @@ lnet_ping_router_locked(struct lnet_peer *rtr) > secs = lnet_router_check_interval(rtr); > > CDEBUG(D_NET, > - "rtr %s %lldd: deadline %lld ping_notsent %d alive %d alive_count %d lp_ping_timestamp %lld\n", > - libcfs_nid2str(rtr->lp_nid), secs, > - rtr->lp_ping_deadline, rtr->lp_ping_notsent, > - rtr->lp_alive, rtr->lp_alive_count, rtr->lp_ping_timestamp); > - > - if (secs && !rtr->lp_ping_notsent && > - now > rtr->lp_ping_timestamp + secs) { > + "rtr %s %lldd: deadline %lld ping_notsent %d alive %d alive_count %d lpni_ping_timestamp %lld\n", > + libcfs_nid2str(rtr->lpni_nid), secs, > + rtr->lpni_ping_deadline, rtr->lpni_ping_notsent, > + rtr->lpni_alive, rtr->lpni_alive_count, > + rtr->lpni_ping_timestamp); > + > + if (secs && !rtr->lpni_ping_notsent && > + now > rtr->lpni_ping_timestamp + secs) { > int rc; > struct lnet_process_id id; > struct lnet_handle_md mdh; > > - id.nid = rtr->lp_nid; > + id.nid = rtr->lpni_nid; > id.pid = LNET_PID_LUSTRE; > CDEBUG(D_NET, "Check: %s\n", libcfs_id2str(id)); > > - rtr->lp_ping_notsent = 1; > - rtr->lp_ping_timestamp = now; > + rtr->lpni_ping_notsent = 1; > + rtr->lpni_ping_timestamp = now; > > mdh = rcd->rcd_mdh; > > - if (!rtr->lp_ping_deadline) { > - rtr->lp_ping_deadline = ktime_get_seconds() + > + if (!rtr->lpni_ping_deadline) { > + rtr->lpni_ping_deadline = ktime_get_seconds() + > router_ping_timeout; > } > > - lnet_net_unlock(rtr->lp_cpt); > + lnet_net_unlock(rtr->lpni_cpt); > > rc = LNetGet(LNET_NID_ANY, mdh, id, LNET_RESERVED_PORTAL, > LNET_PROTO_PING_MATCHBITS, 0); > > - lnet_net_lock(rtr->lp_cpt); > + lnet_net_lock(rtr->lpni_cpt); > if (rc) > - rtr->lp_ping_notsent = 0; /* no event pending */ > + rtr->lpni_ping_notsent = 0; /* no event pending */ > } > > lnet_peer_decref_locked(rtr); > @@ -1106,14 +1108,14 @@ lnet_prune_rc_data(int wait_unlink) > if (the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) { > /* router checker is stopping, prune all */ > list_for_each_entry(lp, &the_lnet.ln_routers, > - lp_rtr_list) { > - if (!lp->lp_rcd) > + lpni_rtr_list) { > + if (!lp->lpni_rcd) > continue; > > - LASSERT(list_empty(&lp->lp_rcd->rcd_list)); > - list_add(&lp->lp_rcd->rcd_list, > + LASSERT(list_empty(&lp->lpni_rcd->rcd_list)); > + list_add(&lp->lpni_rcd->rcd_list, > &the_lnet.ln_rcd_deathrow); > - lp->lp_rcd = NULL; > + lp->lpni_rcd = NULL; > } > } > > @@ -1206,8 +1208,8 @@ lnet_router_checker(void *arg) > rescan: > version = the_lnet.ln_routers_version; > > - list_for_each_entry(rtr, &the_lnet.ln_routers, lp_rtr_list) { > - cpt2 = rtr->lp_cpt; > + list_for_each_entry(rtr, &the_lnet.ln_routers, lpni_rtr_list) { > + cpt2 = rtr->lpni_cpt; > if (cpt != cpt2) { > lnet_net_unlock(cpt); > cpt = cpt2; > @@ -1745,8 +1747,8 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) > * call us with when == _time_when_the_node_was_booted_ if > * no connections were successfully established > */ > - if (ni && !alive && when < lp->lp_last_alive) > - when = lp->lp_last_alive; > + if (ni && !alive && when < lp->lpni_last_alive) > + when = lp->lpni_last_alive; > > lnet_notify_locked(lp, !ni, alive, when); > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 52714b898aac..01c9ad44266f 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -214,7 +214,7 @@ static int proc_lnet_routes(struct ctl_table *table, int write, > __u32 net = rnet->lrn_net; > __u32 hops = route->lr_hops; > unsigned int priority = route->lr_priority; > - lnet_nid_t nid = route->lr_gateway->lp_nid; > + lnet_nid_t nid = route->lr_gateway->lpni_nid; > int alive = lnet_is_route_alive(route); > > s += snprintf(s, tmpstr + tmpsiz - s, > @@ -306,7 +306,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, > while (r != &the_lnet.ln_routers) { > struct lnet_peer *lp; > > - lp = list_entry(r, struct lnet_peer, lp_rtr_list); > + lp = list_entry(r, struct lnet_peer, lpni_rtr_list); > if (!skip) { > peer = lp; > break; > @@ -317,21 +317,21 @@ static int proc_lnet_routers(struct ctl_table *table, int write, > } > > if (peer) { > - lnet_nid_t nid = peer->lp_nid; > + lnet_nid_t nid = peer->lpni_nid; > time64_t now = ktime_get_seconds(); > - time64_t deadline = peer->lp_ping_deadline; > - int nrefs = peer->lp_refcount; > - int nrtrrefs = peer->lp_rtr_refcount; > - int alive_cnt = peer->lp_alive_count; > - int alive = peer->lp_alive; > - int pingsent = !peer->lp_ping_notsent; > - time64_t last_ping = now - peer->lp_ping_timestamp; > + time64_t deadline = peer->lpni_ping_deadline; > + int nrefs = peer->lpni_refcount; > + int nrtrrefs = peer->lpni_rtr_refcount; > + int alive_cnt = peer->lpni_alive_count; > + int alive = peer->lpni_alive; > + int pingsent = !peer->lpni_ping_notsent; > + time64_t last_ping = now - peer->lpni_ping_timestamp; > int down_ni = 0; > struct lnet_route *rtr; > > - if ((peer->lp_ping_feats & > + if ((peer->lpni_ping_feats & > LNET_PING_FEAT_NI_STATUS)) { > - list_for_each_entry(rtr, &peer->lp_routes, > + list_for_each_entry(rtr, &peer->lpni_routes, > lr_gwlist) { > /* > * downis on any route should be the > @@ -452,16 +452,16 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > struct lnet_peer *lp; > > lp = list_entry(p, struct lnet_peer, > - lp_hashlist); > + lpni_hashlist); > if (!skip) { > peer = lp; > > /* > * minor optimization: start from idx+1 > * on next iteration if we've just > - * drained lp_hashlist > + * drained lpni_hashlist > */ > - if (lp->lp_hashlist.next == > + if (lp->lpni_hashlist.next == > &ptable->pt_hash[hash]) { > hoff = 1; > hash++; > @@ -473,7 +473,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > } > > skip--; > - p = lp->lp_hashlist.next; > + p = lp->lpni_hashlist.next; > } > > if (peer) > @@ -485,25 +485,25 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > } > > if (peer) { > - lnet_nid_t nid = peer->lp_nid; > - int nrefs = peer->lp_refcount; > + lnet_nid_t nid = peer->lpni_nid; > + int nrefs = peer->lpni_refcount; > time64_t lastalive = -1; > char *aliveness = "NA"; > - int maxcr = peer->lp_net->net_tunables.lct_peer_tx_credits; > - int txcr = peer->lp_txcredits; > - int mintxcr = peer->lp_mintxcredits; > - int rtrcr = peer->lp_rtrcredits; > - int minrtrcr = peer->lp_minrtrcredits; > - int txqnob = peer->lp_txqnob; > + int maxcr = peer->lpni_net->net_tunables.lct_peer_tx_credits; > + int txcr = peer->lpni_txcredits; > + int mintxcr = peer->lpni_mintxcredits; > + int rtrcr = peer->lpni_rtrcredits; > + int minrtrcr = peer->lpni_minrtrcredits; > + int txqnob = peer->lpni_txqnob; > > if (lnet_isrouter(peer) || > lnet_peer_aliveness_enabled(peer)) > - aliveness = peer->lp_alive ? "up" : "down"; > + aliveness = peer->lpni_alive ? "up" : "down"; > > if (lnet_peer_aliveness_enabled(peer)) { > time64_t now = ktime_get_seconds(); > > - lastalive = now - peer->lp_last_alive; > + lastalive = now - peer->lpni_last_alive; > > /* No need to mess up peers contents with > * arbitrarily long integers - it suffices to > > > From jsimmons at infradead.org Sat Sep 29 22:47:01 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:47:01 +0100 (BST) Subject: [lustre-devel] [PATCH 02/34] lnet: change struct lnet_peer to struct lnet_peer_ni In-Reply-To: <153783763493.32103.9862696546795848039.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763493.32103.9862696546795848039.stgit@noble> Message-ID: > Also remove the typedef > > sed -i -e 's/struct lnet_peer\b/struct lnet_peer_ni/g' -e 's/lnet_peer_t\b/struct lnet_peer_ni/g' `git ls-files lnet` > > Then edit lib-types.h to remove the typedef, and clean up some long lines. > > This is part of > Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek Sigh, I missed some typedef. Thanks for finding them. Reviewed-by: James Simmons > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 20 ++++++----- > .../staging/lustre/include/linux/lnet/lib-types.h | 10 +++--- > drivers/staging/lustre/lnet/lnet/lib-move.c | 26 +++++++-------- > drivers/staging/lustre/lnet/lnet/peer.c | 31 +++++++++--------- > drivers/staging/lustre/lnet/lnet/router.c | 35 ++++++++++---------- > drivers/staging/lustre/lnet/lnet/router_proc.c | 12 +++---- > 6 files changed, 68 insertions(+), 66 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 9b54a3d72290..ef53638e20f6 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -311,16 +311,16 @@ lnet_handle2me(struct lnet_handle_me *handle) > } > > static inline void > -lnet_peer_addref_locked(struct lnet_peer *lp) > +lnet_peer_addref_locked(struct lnet_peer_ni *lp) > { > LASSERT(lp->lpni_refcount > 0); > lp->lpni_refcount++; > } > > -void lnet_destroy_peer_locked(struct lnet_peer *lp); > +void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); > > static inline void > -lnet_peer_decref_locked(struct lnet_peer *lp) > +lnet_peer_decref_locked(struct lnet_peer_ni *lp) > { > LASSERT(lp->lpni_refcount > 0); > lp->lpni_refcount--; > @@ -329,7 +329,7 @@ lnet_peer_decref_locked(struct lnet_peer *lp) > } > > static inline int > -lnet_isrouter(struct lnet_peer *lp) > +lnet_isrouter(struct lnet_peer_ni *lp) > { > return lp->lpni_rtr_refcount ? 1 : 0; > } > @@ -410,7 +410,7 @@ void lnet_lib_exit(void); > > int lnet_notify(struct lnet_ni *ni, lnet_nid_t peer, int alive, > time64_t when); > -void lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, > +void lnet_notify_locked(struct lnet_peer_ni *lp, int notifylnd, int alive, > time64_t when); > int lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway_nid, > unsigned int priority); > @@ -624,7 +624,7 @@ int lnet_peer_buffer_credits(struct lnet_net *net); > > int lnet_router_checker_start(void); > void lnet_router_checker_stop(void); > -void lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net); > +void lnet_router_ni_update_locked(struct lnet_peer_ni *gw, __u32 net); > void lnet_swap_pinginfo(struct lnet_ping_info *info); > > int lnet_parse_ip2nets(char **networksp, char *ip2nets); > @@ -635,9 +635,9 @@ bool lnet_net_unique(__u32 net_id, struct list_head *nilist, > struct lnet_net **net); > bool lnet_ni_unique_net(struct list_head *nilist, char *iface); > > -int lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt); > -struct lnet_peer *lnet_find_peer_locked(struct lnet_peer_table *ptable, > - lnet_nid_t nid); > +int lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); > +struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, > + lnet_nid_t nid); > void lnet_peer_tables_cleanup(struct lnet_ni *ni); > void lnet_peer_tables_destroy(void); > int lnet_peer_tables_create(void); > @@ -650,7 +650,7 @@ int lnet_get_peer_info(__u32 peer_index, __u64 *nid, > __u32 *peer_tx_qnob); > > static inline void > -lnet_peer_set_alive(struct lnet_peer *lp) > +lnet_peer_set_alive(struct lnet_peer_ni *lp) > { > lp->lpni_last_query = ktime_get_seconds(); > lp->lpni_last_alive = lp->lpni_last_query; > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 59a1a2620675..4b26801d7d29 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -93,8 +93,8 @@ struct lnet_msg { > unsigned int msg_onactivelist:1; /* on the activelist */ > unsigned int msg_rdma_get:1; > > - struct lnet_peer *msg_txpeer; /* peer I'm sending to */ > - struct lnet_peer *msg_rxpeer; /* peer I received from */ > + struct lnet_peer_ni *msg_txpeer; /* peer I'm sending to */ > + struct lnet_peer_ni *msg_rxpeer; /* peer I received from */ > > void *msg_private; > struct lnet_libmd *msg_md; > @@ -378,12 +378,12 @@ struct lnet_rc_data { > /* ping buffer MD */ > struct lnet_handle_md rcd_mdh; > /* reference to gateway */ > - struct lnet_peer *rcd_gateway; > + struct lnet_peer_ni *rcd_gateway; > /* ping buffer */ > struct lnet_ping_info *rcd_pinginfo; > }; > > -struct lnet_peer { > +struct lnet_peer_ni { > /* chain on peer hash */ > struct list_head lpni_hashlist; > /* messages blocking for tx credits */ > @@ -474,7 +474,7 @@ struct lnet_route { > /* chain on gateway */ > struct list_head lr_gwlist; > /* router node */ > - struct lnet_peer *lr_gateway; > + struct lnet_peer_ni *lr_gateway; > /* remote network number */ > __u32 lr_net; > /* sequence for round-robin */ > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index 5879a109d46a..4425406e441b 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -491,7 +491,7 @@ lnet_ni_eager_recv(struct lnet_ni *ni, struct lnet_msg *msg) > > /* NB: caller shall hold a ref on 'lp' as I'd drop lnet_net_lock */ > static void > -lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > +lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) > { > time64_t last_alive = 0; > > @@ -510,7 +510,7 @@ lnet_ni_query_locked(struct lnet_ni *ni, struct lnet_peer *lp) > > /* NB: always called with lnet_net_lock held */ > static inline int > -lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) > +lnet_peer_is_alive(struct lnet_peer_ni *lp, unsigned long now) > { > int alive; > time64_t deadline; > @@ -544,7 +544,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now) > * may drop the lnet_net_lock > */ > static int > -lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) > +lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) > { > time64_t now = ktime_get_seconds(); > > @@ -599,7 +599,7 @@ lnet_peer_alive_locked(struct lnet_ni *ni, struct lnet_peer *lp) > static int > lnet_post_send_locked(struct lnet_msg *msg, int do_send) > { > - struct lnet_peer *lp = msg->msg_txpeer; > + struct lnet_peer_ni *lp = msg->msg_txpeer; > struct lnet_ni *ni = msg->msg_txni; > int cpt = msg->msg_tx_cpt; > struct lnet_tx_queue *tq = ni->ni_tx_queues[cpt]; > @@ -710,7 +710,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) > * I return LNET_CREDIT_WAIT if msg blocked and LNET_CREDIT_OK if > * received or OK to receive > */ > - struct lnet_peer *lp = msg->msg_rxpeer; > + struct lnet_peer_ni *lp = msg->msg_rxpeer; > struct lnet_rtrbufpool *rbp; > struct lnet_rtrbuf *rb; > > @@ -780,7 +780,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv) > void > lnet_return_tx_credits_locked(struct lnet_msg *msg) > { > - struct lnet_peer *txpeer = msg->msg_txpeer; > + struct lnet_peer_ni *txpeer = msg->msg_txpeer; > struct lnet_msg *msg2; > struct lnet_ni *txni = msg->msg_txni; > > @@ -881,7 +881,7 @@ lnet_drop_routed_msgs_locked(struct list_head *list, int cpt) > void > lnet_return_rx_credits_locked(struct lnet_msg *msg) > { > - struct lnet_peer *rxpeer = msg->msg_rxpeer; > + struct lnet_peer_ni *rxpeer = msg->msg_rxpeer; > struct lnet_ni *rxni = msg->msg_rxni; > struct lnet_msg *msg2; > > @@ -971,8 +971,8 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) > static int > lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) > { > - struct lnet_peer *p1 = r1->lr_gateway; > - struct lnet_peer *p2 = r2->lr_gateway; > + struct lnet_peer_ni *p1 = r1->lr_gateway; > + struct lnet_peer_ni *p2 = r2->lr_gateway; > int r1_hops = (r1->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r1->lr_hops; > int r2_hops = (r2->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r2->lr_hops; > > @@ -1006,7 +1006,7 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2) > return -ERANGE; > } > > -static struct lnet_peer * > +static struct lnet_peer_ni * > lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > lnet_nid_t rtr_nid) > { > @@ -1014,8 +1014,8 @@ lnet_find_route_locked(struct lnet_net *net, lnet_nid_t target, > struct lnet_route *route; > struct lnet_route *best_route; > struct lnet_route *last_route; > - struct lnet_peer *lpni_best; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lpni_best; > + struct lnet_peer_ni *lp; > int rc; > > /* > @@ -1076,7 +1076,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > lnet_nid_t dst_nid = msg->msg_target.nid; > struct lnet_ni *src_ni; > struct lnet_ni *local_ni; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > int cpt; > int cpt2; > int rc; > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index 619d016b1d89..67614309f242 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -106,8 +106,8 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, > struct lnet_peer_table *ptable) > { > int i; > - struct lnet_peer *lp; > - struct lnet_peer *tmp; > + struct lnet_peer_ni *lp; > + struct lnet_peer_ni *tmp; > > for (i = 0; i < LNET_PEER_HASH_SIZE; i++) { > list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i], > @@ -146,8 +146,8 @@ lnet_peer_table_del_rtrs_locked(struct lnet_ni *ni, > struct lnet_peer_table *ptable, > int cpt_locked) > { > - struct lnet_peer *lp; > - struct lnet_peer *tmp; > + struct lnet_peer_ni *lp; > + struct lnet_peer_ni *tmp; > lnet_nid_t lpni_nid; > int i; > > @@ -174,7 +174,7 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > { > struct lnet_peer_table *ptable; > struct list_head deathrow; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > int i; > > INIT_LIST_HEAD(&deathrow); > @@ -209,14 +209,15 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > } > > while (!list_empty(&deathrow)) { > - lp = list_entry(deathrow.next, struct lnet_peer, lpni_hashlist); > + lp = list_entry(deathrow.next, struct lnet_peer_ni, > + lpni_hashlist); > list_del(&lp->lpni_hashlist); > kfree(lp); > } > } > > void > -lnet_destroy_peer_locked(struct lnet_peer *lp) > +lnet_destroy_peer_locked(struct lnet_peer_ni *lp) > { > struct lnet_peer_table *ptable; > > @@ -237,11 +238,11 @@ lnet_destroy_peer_locked(struct lnet_peer *lp) > ptable->pt_zombies--; > } > > -struct lnet_peer * > +struct lnet_peer_ni * > lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) > { > struct list_head *peers; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > > LASSERT(!the_lnet.ln_shutdown); > > @@ -257,11 +258,11 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) > } > > int > -lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > +lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) > { > struct lnet_peer_table *ptable; > - struct lnet_peer *lp = NULL; > - struct lnet_peer *lp2; > + struct lnet_peer_ni *lp = NULL; > + struct lnet_peer_ni *lp2; > int cpt2; > int rc = 0; > > @@ -281,7 +282,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) > > if (!list_empty(&ptable->pt_deathrow)) { > lp = list_entry(ptable->pt_deathrow.next, > - struct lnet_peer, lpni_hashlist); > + struct lnet_peer_ni, lpni_hashlist); > list_del(&lp->lpni_hashlist); > } > > @@ -359,7 +360,7 @@ void > lnet_debug_peer(lnet_nid_t nid) > { > char *aliveness = "NA"; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > int rc; > int cpt; > > @@ -396,7 +397,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, > __u32 *peer_tx_qnob) > { > struct lnet_peer_table *peer_table; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > bool found = false; > int lncpt, j; > > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 2be1ffb6b720..31685406dcc3 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -100,7 +100,7 @@ lnet_peers_start_down(void) > } > > void > -lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, > +lnet_notify_locked(struct lnet_peer_ni *lp, int notifylnd, int alive, > time64_t when) > { > if (lp->lpni_timestamp > when) { /* out of date information */ > @@ -130,7 +130,7 @@ lnet_notify_locked(struct lnet_peer *lp, int notifylnd, int alive, > } > > static void > -lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > +lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) > { > int alive; > int notifylnd; > @@ -170,7 +170,7 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer *lp) > } > > static void > -lnet_rtr_addref_locked(struct lnet_peer *lp) > +lnet_rtr_addref_locked(struct lnet_peer_ni *lp) > { > LASSERT(lp->lpni_refcount > 0); > LASSERT(lp->lpni_rtr_refcount >= 0); > @@ -182,9 +182,10 @@ lnet_rtr_addref_locked(struct lnet_peer *lp) > > /* a simple insertion sort */ > list_for_each_prev(pos, &the_lnet.ln_routers) { > - struct lnet_peer *rtr; > + struct lnet_peer_ni *rtr; > > - rtr = list_entry(pos, struct lnet_peer, lpni_rtr_list); > + rtr = list_entry(pos, struct lnet_peer_ni, > + lpni_rtr_list); > if (rtr->lpni_nid < lp->lpni_nid) > break; > } > @@ -197,7 +198,7 @@ lnet_rtr_addref_locked(struct lnet_peer *lp) > } > > static void > -lnet_rtr_decref_locked(struct lnet_peer *lp) > +lnet_rtr_decref_locked(struct lnet_peer_ni *lp) > { > LASSERT(lp->lpni_refcount > 0); > LASSERT(lp->lpni_rtr_refcount > 0); > @@ -453,7 +454,7 @@ lnet_check_routes(void) > int > lnet_del_route(__u32 net, lnet_nid_t gw_nid) > { > - struct lnet_peer *gateway; > + struct lnet_peer_ni *gateway; > struct lnet_remotenet *rnet; > struct lnet_route *route; > int rc = -ENOENT; > @@ -614,7 +615,7 @@ static void > lnet_parse_rc_info(struct lnet_rc_data *rcd) > { > struct lnet_ping_info *info = rcd->rcd_pinginfo; > - struct lnet_peer *gw = rcd->rcd_gateway; > + struct lnet_peer_ni *gw = rcd->rcd_gateway; > struct lnet_route *rte; > > if (!gw->lpni_alive) > @@ -703,7 +704,7 @@ static void > lnet_router_checker_event(struct lnet_event *event) > { > struct lnet_rc_data *rcd = event->md.user_ptr; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > > LASSERT(rcd); > > @@ -760,7 +761,7 @@ lnet_router_checker_event(struct lnet_event *event) > static void > lnet_wait_known_routerstate(void) > { > - struct lnet_peer *rtr; > + struct lnet_peer_ni *rtr; > int all_known; > > LASSERT(the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING); > @@ -786,7 +787,7 @@ lnet_wait_known_routerstate(void) > } > > void > -lnet_router_ni_update_locked(struct lnet_peer *gw, __u32 net) > +lnet_router_ni_update_locked(struct lnet_peer_ni *gw, __u32 net) > { > struct lnet_route *rte; > > @@ -863,7 +864,7 @@ lnet_destroy_rc_data(struct lnet_rc_data *rcd) > } > > static struct lnet_rc_data * > -lnet_create_rc_data_locked(struct lnet_peer *gateway) > +lnet_create_rc_data_locked(struct lnet_peer_ni *gateway) > { > struct lnet_rc_data *rcd = NULL; > struct lnet_ping_info *pi; > @@ -933,7 +934,7 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) > } > > static int > -lnet_router_check_interval(struct lnet_peer *rtr) > +lnet_router_check_interval(struct lnet_peer_ni *rtr) > { > int secs; > > @@ -946,7 +947,7 @@ lnet_router_check_interval(struct lnet_peer *rtr) > } > > static void > -lnet_ping_router_locked(struct lnet_peer *rtr) > +lnet_ping_router_locked(struct lnet_peer_ni *rtr) > { > struct lnet_rc_data *rcd = NULL; > time64_t now = ktime_get_seconds(); > @@ -1092,7 +1093,7 @@ lnet_prune_rc_data(int wait_unlink) > { > struct lnet_rc_data *rcd; > struct lnet_rc_data *tmp; > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > struct list_head head; > int i = 2; > > @@ -1197,7 +1198,7 @@ lnet_router_checker_active(void) > static int > lnet_router_checker(void *arg) > { > - struct lnet_peer *rtr; > + struct lnet_peer_ni *rtr; > > while (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING) { > __u64 version; > @@ -1693,7 +1694,7 @@ lnet_rtrpools_disable(void) > int > lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) > { > - struct lnet_peer *lp = NULL; > + struct lnet_peer_ni *lp = NULL; > time64_t now = ktime_get_seconds(); > int cpt = lnet_cpt_of_nid(nid, ni); > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 01c9ad44266f..d0340707feaa 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -289,7 +289,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, > *ppos = LNET_PROC_POS_MAKE(0, ver, 0, off); > } else { > struct list_head *r; > - struct lnet_peer *peer = NULL; > + struct lnet_peer_ni *peer = NULL; > int skip = off - 1; > > lnet_net_lock(0); > @@ -304,9 +304,9 @@ static int proc_lnet_routers(struct ctl_table *table, int write, > r = the_lnet.ln_routers.next; > > while (r != &the_lnet.ln_routers) { > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > > - lp = list_entry(r, struct lnet_peer, lpni_rtr_list); > + lp = list_entry(r, struct lnet_peer_ni, lpni_rtr_list); > if (!skip) { > peer = lp; > break; > @@ -425,7 +425,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > > hoff++; > } else { > - struct lnet_peer *peer; > + struct lnet_peer_ni *peer; > struct list_head *p; > int skip; > again: > @@ -449,9 +449,9 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > p = ptable->pt_hash[hash].next; > > while (p != &ptable->pt_hash[hash]) { > - struct lnet_peer *lp; > + struct lnet_peer_ni *lp; > > - lp = list_entry(p, struct lnet_peer, > + lp = list_entry(p, struct lnet_peer_ni, > lpni_hashlist); > if (!skip) { > peer = lp; > > > From jsimmons at infradead.org Sat Sep 29 22:47:33 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:47:33 +0100 (BST) Subject: [lustre-devel] [PATCH 03/34] lnet: Change lpni_refcount to atomic_t In-Reply-To: <153783763497.32103.13856612081166369948.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763497.32103.13856612081166369948.stgit@noble> Message-ID: > This is part of > Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek Reviewed-by: James Simmons > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 10 +++++----- > .../staging/lustre/include/linux/lnet/lib-types.h | 2 +- > drivers/staging/lustre/lnet/lnet/peer.c | 8 ++++---- > drivers/staging/lustre/lnet/lnet/router.c | 4 ++-- > drivers/staging/lustre/lnet/lnet/router_proc.c | 4 ++-- > 5 files changed, 14 insertions(+), 14 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index ef53638e20f6..88e010aa3f68 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -313,8 +313,8 @@ lnet_handle2me(struct lnet_handle_me *handle) > static inline void > lnet_peer_addref_locked(struct lnet_peer_ni *lp) > { > - LASSERT(lp->lpni_refcount > 0); > - lp->lpni_refcount++; > + LASSERT(atomic_read(&lp->lpni_refcount) > 0); > + atomic_inc(&lp->lpni_refcount); > } > > void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); > @@ -322,9 +322,9 @@ void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); > static inline void > lnet_peer_decref_locked(struct lnet_peer_ni *lp) > { > - LASSERT(lp->lpni_refcount > 0); > - lp->lpni_refcount--; > - if (!lp->lpni_refcount) > + LASSERT(atomic_read(&lp->lpni_refcount) > 0); > + atomic_dec(&lp->lpni_refcount); > + if (atomic_read(&lp->lpni_refcount) == 0) > lnet_destroy_peer_locked(lp); > } > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 4b26801d7d29..9a2cf319dba9 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -429,7 +429,7 @@ struct lnet_peer_ni { > /* peer's NID */ > lnet_nid_t lpni_nid; > /* # refs */ > - int lpni_refcount; > + atomic_t lpni_refcount; > /* CPT this peer attached on */ > int lpni_cpt; > /* # refs from lnet_route::lr_gateway */ > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index 67614309f242..7475678ea184 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -221,7 +221,7 @@ lnet_destroy_peer_locked(struct lnet_peer_ni *lp) > { > struct lnet_peer_table *ptable; > > - LASSERT(!lp->lpni_refcount); > + LASSERT(atomic_read(&lp->lpni_refcount) == 0); > LASSERT(!lp->lpni_rtr_refcount); > LASSERT(list_empty(&lp->lpni_txq)); > LASSERT(list_empty(&lp->lpni_hashlist)); > @@ -320,7 +320,7 @@ lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) > lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; > lp->lpni_nid = nid; > lp->lpni_cpt = cpt2; > - lp->lpni_refcount = 2; /* 1 for caller; 1 for hash */ > + atomic_set(&lp->lpni_refcount, 2); /* 1 for caller; 1 for hash */ > lp->lpni_rtr_refcount = 0; > > lnet_net_lock(cpt); > @@ -378,7 +378,7 @@ lnet_debug_peer(lnet_nid_t nid) > aliveness = lp->lpni_alive ? "up" : "down"; > > CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n", > - libcfs_nid2str(lp->lpni_nid), lp->lpni_refcount, > + libcfs_nid2str(lp->lpni_nid), atomic_read(&lp->lpni_refcount), > aliveness, lp->lpni_net->net_tunables.lct_peer_tx_credits, > lp->lpni_rtrcredits, lp->lpni_minrtrcredits, > lp->lpni_txcredits, lp->lpni_mintxcredits, lp->lpni_txqnob); > @@ -433,7 +433,7 @@ lnet_get_peer_info(__u32 peer_index, __u64 *nid, > lp->lpni_alive ? "up" : "down"); > > *nid = lp->lpni_nid; > - *refcount = lp->lpni_refcount; > + *refcount = atomic_read(&lp->lpni_refcount); > *ni_peer_tx_credits = > lp->lpni_net->net_tunables.lct_peer_tx_credits; > *peer_tx_credits = lp->lpni_txcredits; > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index 31685406dcc3..bfd4b22cc28a 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -172,7 +172,7 @@ lnet_ni_notify_locked(struct lnet_ni *ni, struct lnet_peer_ni *lp) > static void > lnet_rtr_addref_locked(struct lnet_peer_ni *lp) > { > - LASSERT(lp->lpni_refcount > 0); > + LASSERT(atomic_read(&lp->lpni_refcount) > 0); > LASSERT(lp->lpni_rtr_refcount >= 0); > > /* lnet_net_lock must be exclusively locked */ > @@ -200,7 +200,7 @@ lnet_rtr_addref_locked(struct lnet_peer_ni *lp) > static void > lnet_rtr_decref_locked(struct lnet_peer_ni *lp) > { > - LASSERT(lp->lpni_refcount > 0); > + LASSERT(atomic_read(&lp->lpni_refcount) > 0); > LASSERT(lp->lpni_rtr_refcount > 0); > > /* lnet_net_lock must be exclusively locked */ > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index d0340707feaa..12a4b1708d3c 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -320,7 +320,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, > lnet_nid_t nid = peer->lpni_nid; > time64_t now = ktime_get_seconds(); > time64_t deadline = peer->lpni_ping_deadline; > - int nrefs = peer->lpni_refcount; > + int nrefs = atomic_read(&peer->lpni_refcount); > int nrtrrefs = peer->lpni_rtr_refcount; > int alive_cnt = peer->lpni_alive_count; > int alive = peer->lpni_alive; > @@ -486,7 +486,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, > > if (peer) { > lnet_nid_t nid = peer->lpni_nid; > - int nrefs = peer->lpni_refcount; > + int nrefs = atomic_read(&peer->lpni_refcount); > time64_t lastalive = -1; > char *aliveness = "NA"; > int maxcr = peer->lpni_net->net_tunables.lct_peer_tx_credits; > > > From jsimmons at infradead.org Sat Sep 29 22:47:58 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:47:58 +0100 (BST) Subject: [lustre-devel] [PATCH 04/34] lnet: change some function names - add 'ni'. In-Reply-To: <153783763501.32103.12514510583840060159.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763501.32103.12514510583840060159.stgit@noble> Message-ID: > sed -i 's/lnet_peer_addref_locked/lnet_peer_ni_addref_locked/g' `git grep -l lnet_peer_addref_locked lnet/` > sed -i 's/lnet_destroy_peer_locked/lnet_destroy_peer_ni_locked/g' `git grep -l lnet_destroy_peer_locked lnet/` > sed -i 's/lnet_peer_decref_locked/lnet_peer_ni_decref_locked/g' `git grep -l lnet_peer_decref_locked lnet/` > sed -i 's/lnet_nid2peer_locked/lnet_nid2peerni_locked/g' `git grep -l lnet_nid2peer_locked lnet/` > > This is part of > Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek Reviewed-by: James Simmons > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 10 ++++---- > drivers/staging/lustre/lnet/lnet/lib-move.c | 10 ++++---- > drivers/staging/lustre/lnet/lnet/peer.c | 12 +++++----- > drivers/staging/lustre/lnet/lnet/router.c | 24 ++++++++++---------- > 4 files changed, 28 insertions(+), 28 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 88e010aa3f68..a1c581069eb1 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -311,21 +311,21 @@ lnet_handle2me(struct lnet_handle_me *handle) > } > > static inline void > -lnet_peer_addref_locked(struct lnet_peer_ni *lp) > +lnet_peer_ni_addref_locked(struct lnet_peer_ni *lp) > { > LASSERT(atomic_read(&lp->lpni_refcount) > 0); > atomic_inc(&lp->lpni_refcount); > } > > -void lnet_destroy_peer_locked(struct lnet_peer_ni *lp); > +void lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp); > > static inline void > -lnet_peer_decref_locked(struct lnet_peer_ni *lp) > +lnet_peer_ni_decref_locked(struct lnet_peer_ni *lp) > { > LASSERT(atomic_read(&lp->lpni_refcount) > 0); > atomic_dec(&lp->lpni_refcount); > if (atomic_read(&lp->lpni_refcount) == 0) > - lnet_destroy_peer_locked(lp); > + lnet_destroy_peer_ni_locked(lp); > } > > static inline int > @@ -635,7 +635,7 @@ bool lnet_net_unique(__u32 net_id, struct list_head *nilist, > struct lnet_net **net); > bool lnet_ni_unique_net(struct list_head *nilist, char *iface); > > -int lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); > +int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); > struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, > lnet_nid_t nid); > void lnet_peer_tables_cleanup(struct lnet_ni *ni); > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index 4425406e441b..edbec7e9ed7e 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -837,7 +837,7 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg) > > if (txpeer) { > msg->msg_txpeer = NULL; > - lnet_peer_decref_locked(txpeer); > + lnet_peer_ni_decref_locked(txpeer); > } > } > > @@ -964,7 +964,7 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg) > } > if (rxpeer) { > msg->msg_rxpeer = NULL; > - lnet_peer_decref_locked(rxpeer); > + lnet_peer_ni_decref_locked(rxpeer); > } > } > > @@ -1148,7 +1148,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > return 0; > } > > - rc = lnet_nid2peer_locked(&lp, dst_nid, cpt); > + rc = lnet_nid2peerni_locked(&lp, dst_nid, cpt); > if (rc) { > lnet_net_unlock(cpt); > LCONSOLE_WARN("Error %d finding peer %s\n", rc, > @@ -1199,7 +1199,7 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) > LASSERT(src_ni->ni_net == lp->lpni_net); > } > > - lnet_peer_addref_locked(lp); > + lnet_peer_ni_addref_locked(lp); > > LASSERT(src_nid != LNET_NID_ANY); > lnet_msg_commit(msg, cpt); > @@ -1810,7 +1810,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, > } > > lnet_net_lock(cpt); > - rc = lnet_nid2peer_locked(&msg->msg_rxpeer, from_nid, cpt); > + rc = lnet_nid2peerni_locked(&msg->msg_rxpeer, from_nid, cpt); > if (rc) { > lnet_net_unlock(cpt); > CERROR("%s, src %s: Dropping %s (error %d looking up sender)\n", > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index 7475678ea184..fcfad77b9f2c 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -117,7 +117,7 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, > list_del_init(&lp->lpni_hashlist); > /* Lose hash table's ref */ > ptable->pt_zombies++; > - lnet_peer_decref_locked(lp); > + lnet_peer_ni_decref_locked(lp); > } > } > } > @@ -217,7 +217,7 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > } > > void > -lnet_destroy_peer_locked(struct lnet_peer_ni *lp) > +lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp) > { > struct lnet_peer_table *ptable; > > @@ -249,7 +249,7 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) > peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; > list_for_each_entry(lp, peers, lpni_hashlist) { > if (lp->lpni_nid == nid) { > - lnet_peer_addref_locked(lp); > + lnet_peer_ni_addref_locked(lp); > return lp; > } > } > @@ -258,7 +258,7 @@ lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) > } > > int > -lnet_nid2peer_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) > +lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) > { > struct lnet_peer_table *ptable; > struct lnet_peer_ni *lp = NULL; > @@ -367,7 +367,7 @@ lnet_debug_peer(lnet_nid_t nid) > cpt = lnet_cpt_of_nid(nid, NULL); > lnet_net_lock(cpt); > > - rc = lnet_nid2peer_locked(&lp, nid, cpt); > + rc = lnet_nid2peerni_locked(&lp, nid, cpt); > if (rc) { > lnet_net_unlock(cpt); > CDEBUG(D_WARNING, "No peer %s\n", libcfs_nid2str(nid)); > @@ -383,7 +383,7 @@ lnet_debug_peer(lnet_nid_t nid) > lp->lpni_rtrcredits, lp->lpni_minrtrcredits, > lp->lpni_txcredits, lp->lpni_mintxcredits, lp->lpni_txqnob); > > - lnet_peer_decref_locked(lp); > + lnet_peer_ni_decref_locked(lp); > > lnet_net_unlock(cpt); > } > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index bfd4b22cc28a..ba2b2b930576 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -192,7 +192,7 @@ lnet_rtr_addref_locked(struct lnet_peer_ni *lp) > > list_add(&lp->lpni_rtr_list, pos); > /* addref for the_lnet.ln_routers */ > - lnet_peer_addref_locked(lp); > + lnet_peer_ni_addref_locked(lp); > the_lnet.ln_routers_version++; > } > } > @@ -216,7 +216,7 @@ lnet_rtr_decref_locked(struct lnet_peer_ni *lp) > > list_del(&lp->lpni_rtr_list); > /* decref for the_lnet.ln_routers */ > - lnet_peer_decref_locked(lp); > + lnet_peer_ni_decref_locked(lp); > the_lnet.ln_routers_version++; > } > } > @@ -332,7 +332,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > > lnet_net_lock(LNET_LOCK_EX); > > - rc = lnet_nid2peer_locked(&route->lr_gateway, gateway, LNET_LOCK_EX); > + rc = lnet_nid2peerni_locked(&route->lr_gateway, gateway, LNET_LOCK_EX); > if (rc) { > lnet_net_unlock(LNET_LOCK_EX); > > @@ -370,7 +370,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > } > > if (add_route) { > - lnet_peer_addref_locked(route->lr_gateway); /* +1 for notify */ > + lnet_peer_ni_addref_locked(route->lr_gateway); /* +1 for notify */ > lnet_add_route_to_rnet(rnet2, route); > > ni = lnet_get_next_ni_locked(route->lr_gateway->lpni_net, NULL); > @@ -384,7 +384,7 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, > } > > /* -1 for notify or !add_route */ > - lnet_peer_decref_locked(route->lr_gateway); > + lnet_peer_ni_decref_locked(route->lr_gateway); > lnet_net_unlock(LNET_LOCK_EX); > rc = 0; > > @@ -496,7 +496,7 @@ lnet_del_route(__u32 net, lnet_nid_t gw_nid) > rnet = NULL; > > lnet_rtr_decref_locked(gateway); > - lnet_peer_decref_locked(gateway); > + lnet_peer_ni_decref_locked(gateway); > > lnet_net_unlock(LNET_LOCK_EX); > > @@ -854,7 +854,7 @@ lnet_destroy_rc_data(struct lnet_rc_data *rcd) > int cpt = rcd->rcd_gateway->lpni_cpt; > > lnet_net_lock(cpt); > - lnet_peer_decref_locked(rcd->rcd_gateway); > + lnet_peer_ni_decref_locked(rcd->rcd_gateway); > lnet_net_unlock(cpt); > } > > @@ -913,7 +913,7 @@ lnet_create_rc_data_locked(struct lnet_peer_ni *gateway) > goto out; > } > > - lnet_peer_addref_locked(gateway); > + lnet_peer_ni_addref_locked(gateway); > rcd->rcd_gateway = gateway; > gateway->lpni_rcd = rcd; > gateway->lpni_ping_notsent = 0; > @@ -954,7 +954,7 @@ lnet_ping_router_locked(struct lnet_peer_ni *rtr) > time64_t secs; > struct lnet_ni *ni; > > - lnet_peer_addref_locked(rtr); > + lnet_peer_ni_addref_locked(rtr); > > if (rtr->lpni_ping_deadline && /* ping timed out? */ > now > rtr->lpni_ping_deadline) > @@ -967,7 +967,7 @@ lnet_ping_router_locked(struct lnet_peer_ni *rtr) > if (!lnet_isrouter(rtr) || > the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) { > /* router table changed or router checker is shutting down */ > - lnet_peer_decref_locked(rtr); > + lnet_peer_ni_decref_locked(rtr); > return; > } > > @@ -1016,7 +1016,7 @@ lnet_ping_router_locked(struct lnet_peer_ni *rtr) > rtr->lpni_ping_notsent = 0; /* no event pending */ > } > > - lnet_peer_decref_locked(rtr); > + lnet_peer_ni_decref_locked(rtr); > } > > int > @@ -1756,7 +1756,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) > if (ni) > lnet_ni_notify_locked(ni, lp); > > - lnet_peer_decref_locked(lp); > + lnet_peer_ni_decref_locked(lp); > > lnet_net_unlock(cpt); > return 0; > > > From jsimmons at infradead.org Sat Sep 29 22:48:27 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:48:27 +0100 (BST) Subject: [lustre-devel] [PATCH 05/34] lnet: make lnet_nid_cpt_hash non-static. In-Reply-To: <153783763504.32103.13261120162709788445.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763504.32103.13261120162709788445.stgit@noble> Message-ID: > Future patch will need this. > > This is part of > Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek Reviewed-by: James Simmons > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + > drivers/staging/lustre/lnet/lnet/api-ni.c | 2 +- > 2 files changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index a1c581069eb1..f925e3cd64ca 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -395,6 +395,7 @@ lnet_net2rnethash(__u32 net) > extern struct lnet_lnd the_lolnd; > extern int avoid_asym_router_failure; > > +unsigned int lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number); > int lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni); > int lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni); > struct lnet_ni *lnet_nid2ni_locked(lnet_nid_t nid, int cpt); > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 1b47cbd6fd68..20fa3fea04b9 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -693,7 +693,7 @@ lnet_get_net_locked(__u32 net_id) > return NULL; > } > > -static unsigned int > +unsigned int > lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) > { > __u64 key = nid; > > > From jsimmons at infradead.org Sat Sep 29 22:48:54 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:48:54 +0100 (BST) Subject: [lustre-devel] [PATCH 06/34] lnet: introduce lnet_find_peer_ni_locked() In-Reply-To: <153783763508.32103.13303107512736711408.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763508.32103.13303107512736711408.stgit@noble> Message-ID: > Use in place of lnet_find_peer_locked() > > This is part of > Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek Reviewed-by: James Simmons > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 + > drivers/staging/lustre/lnet/lnet/peer.c | 31 ++++++++++++++++++++ > drivers/staging/lustre/lnet/lnet/router.c | 2 + > 3 files changed, 33 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index f925e3cd64ca..656177b64336 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -639,6 +639,7 @@ bool lnet_ni_unique_net(struct list_head *nilist, char *iface); > int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); > struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, > lnet_nid_t nid); > +struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt); > void lnet_peer_tables_cleanup(struct lnet_ni *ni); > void lnet_peer_tables_destroy(void); > int lnet_peer_tables_create(void); > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index fcfad77b9f2c..53b0ca0a2021 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -216,6 +216,37 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > } > } > > +static struct lnet_peer_ni * > +lnet_get_peer_ni_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) > +{ > + struct list_head *peers; > + struct lnet_peer_ni *lp; > + > + LASSERT(!the_lnet.ln_shutdown); > + > + peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; > + list_for_each_entry(lp, peers, lpni_hashlist) { > + if (lp->lpni_nid == nid) { > + lnet_peer_ni_addref_locked(lp); > + return lp; > + } > + } > + > + return NULL; > +} > + > +struct lnet_peer_ni * > +lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt) > +{ > + struct lnet_peer_ni *lpni; > + struct lnet_peer_table *ptable; > + > + ptable = the_lnet.ln_peer_tables[cpt]; > + lpni = lnet_get_peer_ni_locked(ptable, nid); > + > + return lpni; > +} > + > void > lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp) > { > diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c > index ba2b2b930576..de037a77671d 100644 > --- a/drivers/staging/lustre/lnet/lnet/router.c > +++ b/drivers/staging/lustre/lnet/lnet/router.c > @@ -1734,7 +1734,7 @@ lnet_notify(struct lnet_ni *ni, lnet_nid_t nid, int alive, time64_t when) > return -ESHUTDOWN; > } > > - lp = lnet_find_peer_locked(the_lnet.ln_peer_tables[cpt], nid); > + lp = lnet_find_peer_ni_locked(nid, cpt); > if (!lp) { > /* nid not found */ > lnet_net_unlock(cpt); > > > From jsimmons at infradead.org Sat Sep 29 22:53:33 2018 From: jsimmons at infradead.org (James Simmons) Date: Sat, 29 Sep 2018 23:53:33 +0100 (BST) Subject: [lustre-devel] [PATCH 07/34] lnet: lnet_peer_tables_cleanup: use an exclusive lock. In-Reply-To: <153783763511.32103.5073326313518943569.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763511.32103.5073326313518943569.stgit@noble> Message-ID: > Why?? surely this will deadlock. > > This is part of > Commit: 58091af960fe ("LU-7734 lnet: Multi-Rail peer split") > from upstream lustre, where it is marked: > Signed-off-by: Amir Shehata > WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek The code is right but the commit message needs a update. Olaf, Doug, or Amir can you fill in the gaps. Reviewed-by: James Simmons P.S Its strange that git is not sending message to the people in the Reviewed-by:. Maybe git can't handle the indent? > Signed-off-by: NeilBrown > --- > drivers/staging/lustre/lnet/lnet/peer.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index 53b0ca0a2021..376e3459fa92 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -185,9 +185,9 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > * peers are gateways for. > */ > cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { > - lnet_net_lock(i); > + lnet_net_lock(LNET_LOCK_EX); > lnet_peer_table_del_rtrs_locked(ni, ptable, i); > - lnet_net_unlock(i); > + lnet_net_unlock(LNET_LOCK_EX); > } > > /* > @@ -195,17 +195,17 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > * deathrow. > */ > cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { > - lnet_net_lock(i); > + lnet_net_lock(LNET_LOCK_EX); > lnet_peer_table_cleanup_locked(ni, ptable); > - lnet_net_unlock(i); > + lnet_net_unlock(LNET_LOCK_EX); > } > > /* Cleanup all entries on deathrow. */ > cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { > - lnet_net_lock(i); > + lnet_net_lock(LNET_LOCK_EX); > lnet_peer_table_deathrow_wait_locked(ptable, i); > list_splice_init(&ptable->pt_deathrow, &deathrow); > - lnet_net_unlock(i); > + lnet_net_unlock(LNET_LOCK_EX); > } > > while (!list_empty(&deathrow)) { > > > From jsimmons at infradead.org Sat Sep 29 23:01:38 2018 From: jsimmons at infradead.org (James Simmons) Date: Sun, 30 Sep 2018 00:01:38 +0100 (BST) Subject: [lustre-devel] [PATCH 08/34] LU-7734 lnet: Multi-Rail peer split In-Reply-To: <153783763514.32103.5823547209878409504.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763514.32103.5823547209878409504.stgit@noble> Message-ID: On Tue, 25 Sep 2018, NeilBrown wrote: > From: Amir Shehata > > [[Note, the preceding few patches are part of this > in the upstream lustre code - they were split > for easier merging into linux. > ]] > > Split the peer structure into peer/peer_net/peer_ni, as > described in the Multi-Rail HLD. > > Removed deathrow list in peers, instead peers are immediately > deleted. deathrow complicates memory management for peers to > little gain. > > Moved to LNET_LOCK_EX for any operations which will modify the > peer tables. And CPT locks for any operatios which read the peer > tables. Therefore there is no need to use lnet_cpt_of_nid() to > calculate the CPT of the peer NID, instead we use lnet_nid_cpt_hash() > to distribute peers across multiple CPTs. > > It is no longe true that peers and NIs would exist on > the same CPT. In the new design peers and NIs don't have a 1-1 > relationship. You can send to the same peer from several NIs, which > can exist on separate CPTs > > Signed-off-by: Amir Shehata > Change-Id: Ida41d830d38d0ab2bb551476e4a8866d52a25fe2 > Reviewed-on: http://review.whamcloud.com/18293 > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek > Signed-off-by: NeilBrown The patch is fine but the commit message needs to be properly formatted. While patches to OpenSFS tree are titled with "LU-7743 lnet:" for the linux client we changed that to be more inline with what the kernel does. LU-7734 lnet: Multi-Rail peer split --->>> lustre: lnet: Multi-Rail peer split To the outsider reviewer LU-7734 doesn't mean much. Also please replace Change-Id: to the URL link for the work which in turn explains LU-7734. WC-bug-id: https://jira.whamcloud.com/browse/LU-7734 Same for the other patches this series. Seem reasonable? > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 2 > .../staging/lustre/include/linux/lnet/lib-types.h | 29 ++ > drivers/staging/lustre/lnet/lnet/api-ni.c | 1 > drivers/staging/lustre/lnet/lnet/peer.c | 260 ++++++++++++-------- > drivers/staging/lustre/lnet/lnet/router_proc.c | 3 > 5 files changed, 191 insertions(+), 104 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index 656177b64336..bf076298de71 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -637,8 +637,6 @@ bool lnet_net_unique(__u32 net_id, struct list_head *nilist, > bool lnet_ni_unique_net(struct list_head *nilist, char *iface); > > int lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt); > -struct lnet_peer_ni *lnet_find_peer_locked(struct lnet_peer_table *ptable, > - lnet_nid_t nid); > struct lnet_peer_ni *lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt); > void lnet_peer_tables_cleanup(struct lnet_ni *ni); > void lnet_peer_tables_destroy(void); > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 9a2cf319dba9..9f70c094cc4c 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -384,6 +384,7 @@ struct lnet_rc_data { > }; > > struct lnet_peer_ni { > + struct list_head lpni_on_peer_net_list; > /* chain on peer hash */ > struct list_head lpni_hashlist; > /* messages blocking for tx credits */ > @@ -394,6 +395,7 @@ struct lnet_peer_ni { > struct list_head lpni_rtr_list; > /* # tx credits available */ > int lpni_txcredits; > + struct lnet_peer_net *lpni_peer_net; > /* low water mark */ > int lpni_mintxcredits; > /* # router credits */ > @@ -442,6 +444,31 @@ struct lnet_peer_ni { > struct lnet_rc_data *lpni_rcd; > }; > > +struct lnet_peer { > + /* chain on global peer list */ > + struct list_head lp_on_lnet_peer_list; > + > + /* list of peer nets */ > + struct list_head lp_peer_nets; > + > + /* primary NID of the peer */ > + lnet_nid_t lp_primary_nid; > +}; > + > +struct lnet_peer_net { > + /* chain on peer block */ > + struct list_head lpn_on_peer_list; > + > + /* list of peer_nis on this network */ > + struct list_head lpn_peer_nis; > + > + /* pointer to the peer I'm part of */ > + struct lnet_peer *lpn_peer; > + > + /* Net ID */ > + __u32 lpn_net_id; > +}; > + > /* peer hash size */ > #define LNET_PEER_HASH_BITS 9 > #define LNET_PEER_HASH_SIZE (1 << LNET_PEER_HASH_BITS) > @@ -686,6 +713,8 @@ struct lnet { > struct lnet_msg_container **ln_msg_containers; > struct lnet_counters **ln_counters; > struct lnet_peer_table **ln_peer_tables; > + /* list of configured or discovered peers */ > + struct list_head ln_peers; > /* failure simulation */ > struct list_head ln_test_peers; > struct list_head ln_drop_rules; > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 20fa3fea04b9..821b030f9621 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -542,6 +542,7 @@ lnet_prepare(lnet_pid_t requested_pid) > the_lnet.ln_pid = requested_pid; > > INIT_LIST_HEAD(&the_lnet.ln_test_peers); > + INIT_LIST_HEAD(&the_lnet.ln_peers); > INIT_LIST_HEAD(&the_lnet.ln_nets); > INIT_LIST_HEAD(&the_lnet.ln_routers); > INIT_LIST_HEAD(&the_lnet.ln_drop_rules); > diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c > index 376e3459fa92..97ee1f5cfd2f 100644 > --- a/drivers/staging/lustre/lnet/lnet/peer.c > +++ b/drivers/staging/lustre/lnet/lnet/peer.c > @@ -54,8 +54,6 @@ lnet_peer_tables_create(void) > } > > cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { > - INIT_LIST_HEAD(&ptable->pt_deathrow); > - > hash = kvmalloc_cpt(LNET_PEER_HASH_SIZE * sizeof(*hash), > GFP_KERNEL, i); > if (!hash) { > @@ -88,8 +86,6 @@ lnet_peer_tables_destroy(void) > if (!hash) /* not initialized */ > break; > > - LASSERT(list_empty(&ptable->pt_deathrow)); > - > ptable->pt_hash = NULL; > for (j = 0; j < LNET_PEER_HASH_SIZE; j++) > LASSERT(list_empty(&hash[j])); > @@ -123,7 +119,7 @@ lnet_peer_table_cleanup_locked(struct lnet_ni *ni, > } > > static void > -lnet_peer_table_deathrow_wait_locked(struct lnet_peer_table *ptable, > +lnet_peer_table_finalize_wait_locked(struct lnet_peer_table *ptable, > int cpt_locked) > { > int i; > @@ -173,12 +169,8 @@ void > lnet_peer_tables_cleanup(struct lnet_ni *ni) > { > struct lnet_peer_table *ptable; > - struct list_head deathrow; > - struct lnet_peer_ni *lp; > int i; > > - INIT_LIST_HEAD(&deathrow); > - > LASSERT(the_lnet.ln_shutdown || ni); > /* > * If just deleting the peers for a NI, get rid of any routes these > @@ -191,8 +183,7 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > } > > /* > - * Start the process of moving the applicable peers to > - * deathrow. > + * Start the cleanup process > */ > cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { > lnet_net_lock(LNET_LOCK_EX); > @@ -200,20 +191,12 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) > lnet_net_unlock(LNET_LOCK_EX); > } > > - /* Cleanup all entries on deathrow. */ > + /* Wait until all peers have been destroyed. */ > cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { > lnet_net_lock(LNET_LOCK_EX); > - lnet_peer_table_deathrow_wait_locked(ptable, i); > - list_splice_init(&ptable->pt_deathrow, &deathrow); > + lnet_peer_table_finalize_wait_locked(ptable, i); > lnet_net_unlock(LNET_LOCK_EX); > } > - > - while (!list_empty(&deathrow)) { > - lp = list_entry(deathrow.next, struct lnet_peer_ni, > - lpni_hashlist); > - list_del(&lp->lpni_hashlist); > - kfree(lp); > - } > } > > static struct lnet_peer_ni * > @@ -247,74 +230,143 @@ lnet_find_peer_ni_locked(lnet_nid_t nid, int cpt) > return lpni; > } > > -void > -lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lp) > +static void > +lnet_try_destroy_peer_hierarchy_locked(struct lnet_peer_ni *lpni) > { > - struct lnet_peer_table *ptable; > + struct lnet_peer_net *peer_net; > + struct lnet_peer *peer; > > - LASSERT(atomic_read(&lp->lpni_refcount) == 0); > - LASSERT(!lp->lpni_rtr_refcount); > - LASSERT(list_empty(&lp->lpni_txq)); > - LASSERT(list_empty(&lp->lpni_hashlist)); > - LASSERT(!lp->lpni_txqnob); > + /* TODO: could the below situation happen? accessing an already > + * destroyed peer? > + */ > + if (!lpni->lpni_peer_net || > + !lpni->lpni_peer_net->lpn_peer) > + return; > > - ptable = the_lnet.ln_peer_tables[lp->lpni_cpt]; > - LASSERT(ptable->pt_number > 0); > - ptable->pt_number--; > + peer_net = lpni->lpni_peer_net; > + peer = lpni->lpni_peer_net->lpn_peer; > > - lp->lpni_net = NULL; > + list_del_init(&lpni->lpni_on_peer_net_list); > + lpni->lpni_peer_net = NULL; > > - list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); > - LASSERT(ptable->pt_zombies > 0); > - ptable->pt_zombies--; > + /* if peer_net is empty, then remove it from the peer */ > + if (list_empty(&peer_net->lpn_peer_nis)) { > + list_del_init(&peer_net->lpn_on_peer_list); > + peer_net->lpn_peer = NULL; > + kfree(peer_net); > + > + /* If the peer is empty then remove it from the > + * the_lnet.ln_peers > + */ > + if (list_empty(&peer->lp_peer_nets)) { > + list_del_init(&peer->lp_on_lnet_peer_list); > + kfree(peer); > + } > + } > } > > -struct lnet_peer_ni * > -lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid) > +static int > +lnet_build_peer_hierarchy(struct lnet_peer_ni *lpni) > { > - struct list_head *peers; > - struct lnet_peer_ni *lp; > + struct lnet_peer *peer; > + struct lnet_peer_net *peer_net; > + __u32 lpni_net = LNET_NIDNET(lpni->lpni_nid); > > - LASSERT(!the_lnet.ln_shutdown); > + peer = NULL; > + peer_net = NULL; > > - peers = &ptable->pt_hash[lnet_nid2peerhash(nid)]; > - list_for_each_entry(lp, peers, lpni_hashlist) { > - if (lp->lpni_nid == nid) { > - lnet_peer_ni_addref_locked(lp); > - return lp; > - } > + peer = kzalloc(sizeof(*peer), GFP_KERNEL); > + if (!peer) > + return -ENOMEM; > + > + peer_net = kzalloc(sizeof(*peer_net), GFP_KERNEL); > + if (!peer_net) { > + kfree(peer); > + return -ENOMEM; > } > > - return NULL; > + INIT_LIST_HEAD(&peer->lp_on_lnet_peer_list); > + INIT_LIST_HEAD(&peer->lp_peer_nets); > + INIT_LIST_HEAD(&peer_net->lpn_on_peer_list); > + INIT_LIST_HEAD(&peer_net->lpn_peer_nis); > + > + /* build the hierarchy */ > + peer_net->lpn_net_id = lpni_net; > + peer_net->lpn_peer = peer; > + lpni->lpni_peer_net = peer_net; > + peer->lp_primary_nid = lpni->lpni_nid; > + list_add_tail(&peer_net->lpn_on_peer_list, &peer->lp_peer_nets); > + list_add_tail(&lpni->lpni_on_peer_net_list, &peer_net->lpn_peer_nis); > + list_add_tail(&peer->lp_on_lnet_peer_list, &the_lnet.ln_peers); > + > + return 0; > +} > + > +void > +lnet_destroy_peer_ni_locked(struct lnet_peer_ni *lpni) > +{ > + struct lnet_peer_table *ptable; > + > + LASSERT(atomic_read(&lpni->lpni_refcount) == 0); > + LASSERT(lpni->lpni_rtr_refcount == 0); > + LASSERT(list_empty(&lpni->lpni_txq)); > + LASSERT(list_empty(&lpni->lpni_hashlist)); > + LASSERT(lpni->lpni_txqnob == 0); > + LASSERT(lpni->lpni_peer_net); > + LASSERT(lpni->lpni_peer_net->lpn_peer); > + > + ptable = the_lnet.ln_peer_tables[lpni->lpni_cpt]; > + LASSERT(ptable->pt_number > 0); > + ptable->pt_number--; > + > + lpni->lpni_net = NULL; > + > + lnet_try_destroy_peer_hierarchy_locked(lpni); > + > + kfree(lpni); > + > + LASSERT(ptable->pt_zombies > 0); > + ptable->pt_zombies--; > } > > int > -lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) > +lnet_nid2peerni_locked(struct lnet_peer_ni **lpnip, lnet_nid_t nid, int cpt) > { > struct lnet_peer_table *ptable; > - struct lnet_peer_ni *lp = NULL; > - struct lnet_peer_ni *lp2; > + struct lnet_peer_ni *lpni = NULL; > + struct lnet_peer_ni *lpni2; > int cpt2; > int rc = 0; > > - *lpp = NULL; > + *lpnip = NULL; > if (the_lnet.ln_shutdown) /* it's shutting down */ > return -ESHUTDOWN; > > - /* cpt can be LNET_LOCK_EX if it's called from router functions */ > - cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid, NULL); > + /* > + * calculate cpt2 with the standard hash function > + * This cpt2 becomes the slot where we'll find or create the peer. > + */ > + cpt2 = lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); > > - ptable = the_lnet.ln_peer_tables[cpt2]; > - lp = lnet_find_peer_locked(ptable, nid); > - if (lp) { > - *lpp = lp; > - return 0; > + /* > + * Any changes to the peer tables happen under exclusive write > + * lock. Any reads to the peer tables can be done via a standard > + * CPT read lock. > + */ > + if (cpt != LNET_LOCK_EX) { > + lnet_net_unlock(cpt); > + lnet_net_lock(LNET_LOCK_EX); > } > > - if (!list_empty(&ptable->pt_deathrow)) { > - lp = list_entry(ptable->pt_deathrow.next, > - struct lnet_peer_ni, lpni_hashlist); > - list_del(&lp->lpni_hashlist); > + ptable = the_lnet.ln_peer_tables[cpt2]; > + lpni = lnet_get_peer_ni_locked(ptable, nid); > + if (lpni) { > + *lpnip = lpni; > + if (cpt != LNET_LOCK_EX) { > + lnet_net_unlock(LNET_LOCK_EX); > + lnet_net_lock(cpt); > + } > + return 0; > } > > /* > @@ -322,68 +374,72 @@ lnet_nid2peerni_locked(struct lnet_peer_ni **lpp, lnet_nid_t nid, int cpt) > * and destroyed locks and peer-table before I finish the allocation > */ > ptable->pt_number++; > - lnet_net_unlock(cpt); > + lnet_net_unlock(LNET_LOCK_EX); > > - if (lp) > - memset(lp, 0, sizeof(*lp)); > - else > - lp = kzalloc_cpt(sizeof(*lp), GFP_NOFS, cpt2); > - > - if (!lp) { > + lpni = kzalloc_cpt(sizeof(*lpni), GFP_KERNEL, cpt2); > + if (!lpni) { > rc = -ENOMEM; > lnet_net_lock(cpt); > goto out; > } > > - INIT_LIST_HEAD(&lp->lpni_txq); > - INIT_LIST_HEAD(&lp->lpni_rtrq); > - INIT_LIST_HEAD(&lp->lpni_routes); > - > - lp->lpni_notify = 0; > - lp->lpni_notifylnd = 0; > - lp->lpni_notifying = 0; > - lp->lpni_alive_count = 0; > - lp->lpni_timestamp = 0; > - lp->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ > - lp->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ > - lp->lpni_last_query = 0; /* haven't asked NI yet */ > - lp->lpni_ping_timestamp = 0; > - lp->lpni_ping_feats = LNET_PING_FEAT_INVAL; > - lp->lpni_nid = nid; > - lp->lpni_cpt = cpt2; > - atomic_set(&lp->lpni_refcount, 2); /* 1 for caller; 1 for hash */ > - lp->lpni_rtr_refcount = 0; > + INIT_LIST_HEAD(&lpni->lpni_txq); > + INIT_LIST_HEAD(&lpni->lpni_rtrq); > + INIT_LIST_HEAD(&lpni->lpni_routes); > > - lnet_net_lock(cpt); > + lpni->lpni_alive = !lnet_peers_start_down(); /* 1 bit!! */ > + lpni->lpni_last_alive = ktime_get_seconds(); /* assumes alive */ > + lpni->lpni_ping_feats = LNET_PING_FEAT_INVAL; > + lpni->lpni_nid = nid; > + lpni->lpni_cpt = cpt2; > + atomic_set(&lpni->lpni_refcount, 2); /* 1 for caller; 1 for hash */ > + > + rc = lnet_build_peer_hierarchy(lpni); > + if (rc != 0) > + goto out; > + > + lnet_net_lock(LNET_LOCK_EX); > > if (the_lnet.ln_shutdown) { > rc = -ESHUTDOWN; > goto out; > } > > - lp2 = lnet_find_peer_locked(ptable, nid); > - if (lp2) { > - *lpp = lp2; > + lpni2 = lnet_get_peer_ni_locked(ptable, nid); > + if (lpni2) { > + *lpnip = lpni2; > goto out; > } > > - lp->lpni_net = lnet_get_net_locked(LNET_NIDNET(lp->lpni_nid)); > - lp->lpni_txcredits = > - lp->lpni_mintxcredits = > - lp->lpni_net->net_tunables.lct_peer_tx_credits; > - lp->lpni_rtrcredits = > - lp->lpni_minrtrcredits = lnet_peer_buffer_credits(lp->lpni_net); > + lpni->lpni_net = lnet_get_net_locked(LNET_NIDNET(lpni->lpni_nid)); > + lpni->lpni_txcredits = > + lpni->lpni_mintxcredits = > + lpni->lpni_net->net_tunables.lct_peer_tx_credits; > + lpni->lpni_rtrcredits = > + lpni->lpni_minrtrcredits = > + lnet_peer_buffer_credits(lpni->lpni_net); > > - list_add_tail(&lp->lpni_hashlist, > + list_add_tail(&lpni->lpni_hashlist, > &ptable->pt_hash[lnet_nid2peerhash(nid)]); > ptable->pt_version++; > - *lpp = lp; > + *lpnip = lpni; > + > + if (cpt != LNET_LOCK_EX) { > + lnet_net_unlock(LNET_LOCK_EX); > + lnet_net_lock(cpt); > + } > > return 0; > out: > - if (lp) > - list_add(&lp->lpni_hashlist, &ptable->pt_deathrow); > + if (lpni) { > + lnet_try_destroy_peer_hierarchy_locked(lpni); > + kfree(lpni); > + } > ptable->pt_number--; > + if (cpt != LNET_LOCK_EX) { > + lnet_net_unlock(LNET_LOCK_EX); > + lnet_net_lock(cpt); > + } > return rc; > } > > diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c > index 12a4b1708d3c..977a937f261c 100644 > --- a/drivers/staging/lustre/lnet/lnet/router_proc.c > +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c > @@ -385,6 +385,9 @@ static int proc_lnet_routers(struct ctl_table *table, int write, > return rc; > } > > +/* TODO: there should be no direct access to ptable. We should add a set > + * of APIs that give access to the ptable and its members > + */ > static int proc_lnet_peers(struct ctl_table *table, int write, > void __user *buffer, size_t *lenp, loff_t *ppos) > { > > > From jsimmons at infradead.org Sun Sep 30 01:49:59 2018 From: jsimmons at infradead.org (James Simmons) Date: Sun, 30 Sep 2018 02:49:59 +0100 (BST) Subject: [lustre-devel] [PATCH 12/34] LU-7734 lnet: NUMA support In-Reply-To: <153783763531.32103.14595088461405832909.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> <153783763531.32103.14595088461405832909.stgit@noble> Message-ID: > From: Amir Shehata > > This patch adds NUMA node support. NUMA node information is stored > in the CPT table. A NUMA node mask is maintained for the entire table > as well as for each CPT to track the NUMA nodes related to each of > the CPTs. Following key APIs added: > > cfs_cpt_of_node(): returns the CPT of particular NUMA node > cfs_cpt_distance(): calculates the distance between two CPTs > > When the LND device is started it finds the NUMA node of the physical > device and then from there it finds the CPT, which is subsequently > stored in the NI structure. > > When selecting the NI, the MD CPT is determined and the distance > between the MD CPT and the device CPT is calculated. The NI > with the shortest distance is preferred. > > If the device or system is not NUMA aware then the CPT for the > device will default to CFS_CPT_ANY and the distance calculated > when CFS_CPT_ANY is used is largest in the system. IE, none > NUMA aware devices are least preferred. > > A NUMA range value can be set. If the value is large enough > it amounts to basically turning off NUMA criterion completely. > > Signed-off-by: Amir Shehata > Change-Id: I2d7c63f8e8fc8e8a6a249b0d6bfdd08fd090a837 > Reviewed-on: http://review.whamcloud.com/18916 > Tested-by: Jenkins > Tested-by: Maloo We can remove the Test-by: as well. > Reviewed-by: Olaf Weber > Reviewed-by: Doug Oucharek > Signed-off-by: NeilBrown > --- > .../staging/lustre/include/linux/lnet/lib-lnet.h | 1 > .../staging/lustre/include/linux/lnet/lib-types.h | 3 > .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 6 + > .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 6 + > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 4 + > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 13 ++ > drivers/staging/lustre/lnet/lnet/api-ni.c | 27 +++ > drivers/staging/lustre/lnet/lnet/lib-move.c | 160 +++++++++++++++++--- > 8 files changed, 195 insertions(+), 25 deletions(-) > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > index a7cff6426ad8..c338e31b2cdd 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > @@ -408,6 +408,7 @@ struct lnet_ni *lnet_net2ni_addref(__u32 net); > bool lnet_is_ni_healthy_locked(struct lnet_ni *ni); > struct lnet_net *lnet_get_net_locked(u32 net_id); > > +extern unsigned int lnet_numa_range; > extern int portal_rotor; > > int lnet_lib_init(void); > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h > index 22b141cb6cff..5083b72ca20f 100644 > --- a/drivers/staging/lustre/include/linux/lnet/lib-types.h > +++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h > @@ -346,6 +346,9 @@ struct lnet_ni { > /* lnd tunables set explicitly */ > bool ni_lnd_tunables_set; > > + /* physical device CPT */ > + int dev_cpt; > + > /* sequence number used to round robin over nis within a net */ > u32 ni_seq; > > diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h > index fa58aaf6ad9d..a231f6d89e95 100644 > --- a/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h > +++ b/drivers/staging/lustre/include/uapi/linux/lnet/libcfs_ioctl.h > @@ -142,7 +142,9 @@ struct libcfs_debug_ioctl_data { > #define IOC_LIBCFS_ADD_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 95, IOCTL_CONFIG_SIZE) > #define IOC_LIBCFS_DEL_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 96, IOCTL_CONFIG_SIZE) > #define IOC_LIBCFS_GET_LOCAL_NI _IOWR(IOC_LIBCFS_TYPE, 97, IOCTL_CONFIG_SIZE) > -#define IOC_LIBCFS_DBG _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE) > -#define IOC_LIBCFS_MAX_NR 98 > +#define IOC_LIBCFS_SET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE) > +#define IOC_LIBCFS_GET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 99, IOCTL_CONFIG_SIZE) > +#define IOC_LIBCFS_DBG _IOWR(IOC_LIBCFS_TYPE, 100, IOCTL_CONFIG_SIZE) > +#define IOC_LIBCFS_MAX_NR 100 > > #endif /* __LIBCFS_IOCTL_H__ */ > diff --git a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h > index bfd9fc6bc4df..5eaaf0eae470 100644 > --- a/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h > +++ b/drivers/staging/lustre/include/uapi/linux/lnet/lnet-dlc.h > @@ -162,6 +162,7 @@ struct lnet_ioctl_config_ni { > __u32 lic_status; > __u32 lic_tcp_bonding; > __u32 lic_idx; > + __s32 lic_dev_cpt; > char lic_bulk[0]; > }; > > @@ -213,6 +214,11 @@ struct lnet_ioctl_peer_cfg { > char prcfg_bulk[0]; > }; > > +struct lnet_ioctl_numa_range { > + struct libcfs_ioctl_hdr nr_hdr; > + __u32 nr_range; > +}; > + > struct lnet_ioctl_lnet_stats { > struct libcfs_ioctl_hdr st_hdr; > struct lnet_counters st_cntrs; > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > index 958ac9a99045..2e71abbf8a0c 100644 > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > @@ -2829,6 +2829,7 @@ static int kiblnd_startup(struct lnet_ni *ni) > unsigned long flags; > int rc; > int newdev; > + int node_id; > > LASSERT(ni->ni_net->net_lnd == &the_o2iblnd); > > @@ -2878,6 +2879,9 @@ static int kiblnd_startup(struct lnet_ni *ni) > if (!ibdev) > goto failed; > > + node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device); > + ni->dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); > + > net->ibn_dev = ibdev; > ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip); > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > index 9df66c6d160f..ba1ec35a017a 100644 > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > @@ -38,6 +38,7 @@ > * Author: Eric Barton > */ > > +#include > #include "socklnd.h" > #include > > @@ -2726,6 +2727,8 @@ ksocknal_startup(struct lnet_ni *ni) > struct ksock_net *net; > int rc; > int i; > + struct net_device *net_dev; > + int node_id; > > LASSERT(ni->ni_net->net_lnd == &the_ksocklnd); > > @@ -2773,6 +2776,16 @@ ksocknal_startup(struct lnet_ni *ni) > } > } > > + net_dev = dev_get_by_name(&init_net, > + net->ksnn_interfaces[0].ksni_name); > + if (net_dev) { > + node_id = dev_to_node(&net_dev->dev); > + ni->dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); > + dev_put(net_dev); > + } else { > + ni->dev_cpt = CFS_CPT_ANY; > + } > + > /* call it before add it to ksocknal_data.ksnd_nets */ > rc = ksocknal_net_start_threads(net, ni->ni_cpts, ni->ni_ncpts); > if (rc) > diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c > index 1ef9a39b517d..67a3301258d4 100644 > --- a/drivers/staging/lustre/lnet/lnet/api-ni.c > +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c > @@ -64,6 +64,12 @@ module_param(use_tcp_bonding, int, 0444); > MODULE_PARM_DESC(use_tcp_bonding, > "Set to 1 to use socklnd bonding. 0 to use Multi-Rail"); > > +unsigned int lnet_numa_range; > +EXPORT_SYMBOL(lnet_numa_range); > +module_param(lnet_numa_range, uint, 0444); > +MODULE_PARM_DESC(lnet_numa_range, > + "NUMA range to consider during Multi-Rail selection"); > + > /* > * This sequence number keeps track of how many times DLC was used to > * update the configuration. It is incremented on any DLC update and > @@ -1896,6 +1902,7 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_ni *cfg_ni, > cfg_ni->lic_nid = ni->ni_nid; > cfg_ni->lic_status = ni->ni_status->ns_status; > cfg_ni->lic_tcp_bonding = use_tcp_bonding; > + cfg_ni->lic_dev_cpt = ni->dev_cpt; > > memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn)); > > @@ -2642,6 +2649,26 @@ LNetCtl(unsigned int cmd, void *arg) > mutex_unlock(&the_lnet.ln_api_mutex); > return rc; > > + case IOC_LIBCFS_SET_NUMA_RANGE: { > + struct lnet_ioctl_numa_range *numa; > + > + numa = arg; > + if (numa->nr_hdr.ioc_len != sizeof(*numa)) > + return -EINVAL; > + lnet_numa_range = numa->nr_range; > + return 0; > + } > + > + case IOC_LIBCFS_GET_NUMA_RANGE: { > + struct lnet_ioctl_numa_range *numa; > + > + numa = arg; > + if (numa->nr_hdr.ioc_len != sizeof(*numa)) > + return -EINVAL; > + numa->nr_range = lnet_numa_range; > + return 0; > + } > + > case IOC_LIBCFS_GET_BUF: { > struct lnet_ioctl_pool_cfg *pool_cfg; > size_t total = sizeof(*config) + sizeof(*pool_cfg); > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > index fbf209610ff9..bf2256da6122 100644 > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > @@ -1109,6 +1109,10 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, > int best_credits = 0; > u32 seq, seq2; > int best_lpni_credits = INT_MIN; > + int md_cpt = 0; > + unsigned int shortest_distance = UINT_MAX; > + unsigned int distance = 0; > + bool found_ir = false; > > again: > /* > @@ -1127,12 +1131,20 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, > routing = false; > local_net = NULL; > best_ni = NULL; > + shortest_distance = UINT_MAX; > + found_ir = false; > > if (the_lnet.ln_shutdown) { > lnet_net_unlock(cpt); > return -ESHUTDOWN; > } > > + if (msg->msg_md) > + /* get the cpt of the MD, used during NUMA based selection */ > + md_cpt = lnet_cpt_of_cookie(msg->msg_md->md_lh.lh_cookie); > + else > + md_cpt = CFS_CPT_ANY; > + > /* > * initialize the variables which could be reused if we go to > * again > @@ -1258,34 +1270,113 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, > continue; > > /* > - * Second jab at determining best_ni > - * if we get here then the peer we're trying to send > - * to is on a directly connected network, and we'll > - * need to pick the local_ni on that network to send > - * from > + * Iterate through the NIs in this local Net and select > + * the NI to send from. The selection is determined by > + * these 3 criterion in the following priority: > + * 1. NUMA > + * 2. NI available credits > + * 3. Round Robin > */ > while ((ni = lnet_get_next_ni_locked(local_net, ni))) { > if (!lnet_is_ni_healthy_locked(ni)) > continue; > - /* TODO: compare NUMA distance */ > - if (ni->ni_tx_queues[cpt]->tq_credits <= > - best_credits) { > + > + /* > + * calculate the distance from the cpt on which > + * the message memory is allocated to the CPT of > + * the NI's physical device > + */ > + distance = cfs_cpt_distance(lnet_cpt_table(), > + md_cpt, > + ni->dev_cpt); > + > + /* > + * If we already have a closer NI within the NUMA > + * range provided, then there is no need to > + * consider the current NI. Move on to the next > + * one. > + */ > + if (distance > shortest_distance && > + distance > lnet_numa_range) > + continue; > + > + if (distance < shortest_distance && > + distance > lnet_numa_range) { > /* > - * all we want is to read tq_credits > - * value as an approximation of how > - * busy the NI is. No need to grab a lock > + * The current NI is the closest one that we > + * have found, even though it's not in the > + * NUMA range specified. This occurs if > + * the NUMA range is less than the least > + * of the distances in the system. > + * In effect NUMA range consideration is > + * turned off. > */ > - continue; > - } else if (best_ni) { > - if ((best_ni)->ni_seq - ni->ni_seq <= 0) > + shortest_distance = distance; > + } else if ((distance <= shortest_distance && > + distance < lnet_numa_range) || > + distance == shortest_distance) { > + /* > + * This NI is either within range or it's > + * equidistant. In both of these cases we > + * would want to select the NI based on > + * its available credits first, and then > + * via Round Robin. > + */ > + if (distance <= shortest_distance && > + distance < lnet_numa_range) { > + /* > + * If this is the first NI that's > + * within range, then set the > + * shortest distance to the range > + * specified by the user. In > + * effect we're saying that all > + * NIs that fall within this NUMA > + * range shall be dealt with as > + * having equal NUMA weight. Which > + * will mean that we should select > + * through that set by their > + * available credits first > + * followed by Round Robin. > + * > + * And since this is the first NI > + * in the range, let's just set it > + * as our best_ni for now. The > + * following NIs found in the > + * range will be dealt with as > + * mentioned previously. > + */ > + shortest_distance = lnet_numa_range; > + if (!found_ir) { > + found_ir = true; > + goto set_ni; > + } > + } > + /* > + * This NI is NUMA equidistant let's > + * select using credits followed by Round > + * Robin. > + */ > + if (ni->ni_tx_queues[cpt]->tq_credits < > + best_credits) { > continue; > - (best_ni)->ni_seq = ni->ni_seq + 1; > + } else if (ni->ni_tx_queues[cpt]->tq_credits == > + best_credits) { > + if (best_ni && > + best_ni->ni_seq <= ni->ni_seq) > + continue; > + } > } > - > +set_ni: > best_ni = ni; > best_credits = ni->ni_tx_queues[cpt]->tq_credits; > } > } > + /* > + * Now that we selected the NI to use increment its sequence > + * number so the Round Robin algorithm will detect that it has > + * been used and pick the next NI. > + */ > + best_ni->ni_seq++; > > if (!best_ni) { > lnet_net_unlock(cpt); > @@ -1372,29 +1463,52 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, > best_lpni = NULL; > while ((lpni = lnet_get_next_peer_ni_locked(peer, peer_net, lpni))) { > /* > - * if this peer ni is not healty just skip it, no point in > + * if this peer ni is not healthy just skip it, no point in > * examining it further > */ > if (!lnet_is_peer_ni_healthy_locked(lpni)) > continue; > ni_is_pref = lnet_peer_is_ni_pref_locked(lpni, best_ni); > > + /* if this is a preferred peer use it */ > if (!preferred && ni_is_pref) { > preferred = true; > } else if (preferred && !ni_is_pref) { > + /* > + * this is not the preferred peer so let's ignore > + * it. > + */ > continue; > - } else if (lpni->lpni_txcredits <= best_lpni_credits) { > + } else if (lpni->lpni_txcredits < best_lpni_credits) { > + /* > + * We already have a peer that has more credits > + * available than this one. No need to consider > + * this peer further. > + */ > continue; > - } else if (best_lpni) { > - if (best_lpni->lpni_seq - lpni->lpni_seq <= 0) > - continue; > - best_lpni->lpni_seq = lpni->lpni_seq + 1; > + } else if (lpni->lpni_txcredits == best_lpni_credits) { > + /* > + * The best peer found so far and the current peer > + * have the same number of available credits let's > + * make sure to select between them using Round > + * Robin > + */ > + if (best_lpni) { > + if (best_lpni->lpni_seq <= lpni->lpni_seq) > + continue; > + } > } > > best_lpni = lpni; > best_lpni_credits = lpni->lpni_txcredits; > } > > + /* > + * Increment sequence number of the peer selected so that we can > + * pick the next one in Round Robin. > + */ > + best_lpni->lpni_seq++; > + > /* if we still can't find a peer ni then we can't reach it */ > if (!best_lpni) { > u32 net_id = peer_net ? peer_net->lpn_net_id : > @@ -1403,7 +1517,7 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid, > lnet_net_unlock(cpt); > LCONSOLE_WARN("no peer_ni found on peer net %s\n", > libcfs_net2str(net_id)); > - goto again; > + return -EHOSTUNREACH; > } > > send: > > > From jsimmons at infradead.org Sun Sep 30 02:17:45 2018 From: jsimmons at infradead.org (James Simmons) Date: Sun, 30 Sep 2018 03:17:45 +0100 (BST) Subject: [lustre-devel] [PATCH 00/34] lustre: remainder of multi-rail series. In-Reply-To: <153783752960.32103.8394391715843917125.stgit@noble> References: <153783752960.32103.8394391715843917125.stgit@noble> Message-ID: > Hi, > following is the remainder of the Multi-Rail series, ported > to drivers/staging. > The previous series was only the first patch from upstream. > This series is mostly the individual patches from upstream, > though I did split some up a bit, and merged at least one bugfix back > to where the bug was introduced. > > Comments, review, and explanations of bits I didn't understand, are > most welcome. I confess that I haven't looked at the code very > closely, just a superficially scan for things that look odd (there > weren't many). Thanks for doing this. It makes my life easier. With the patches: lustre: lnet: copy the correct amount of cpts to lnet_cpts lustre: lnd: resolve IP query code in LND drivers and the fixup in patch 11 it runs flawless in my testing. I do recommend land the two above patches first so no git bisect will end up blowing up someones nodes :-) Just have a bunch of commit recommendations. I noticed some MR patches landed to the main lustre branch. Perhaps those should be fixed as well. The only reason I ask is that I worry about kernel developers might not like that style of commit messages. In the past Greg pointed such things out to me. Thanks for hearing me out about that concern. I will poke Doug about looking at some of the commit messages you had concern about. > Thanks, > NeilBrown > > --- > > Amir Shehata (22): > LU-7734 lnet: Multi-Rail peer split > LU-7734 lnet: Multi-Rail local_ni/peer_ni selection > LU-7734 lnet: configure peers from DLC > LU-7734 lnet: configure local NI from DLC > LU-7734 lnet: NUMA support > LU-7734 lnet: Primary NID and traffic distribution > LU-7734 lnet: handle non-MR peers > LU-7734 lnet: handle N NIs to 1 LND peer > LU-7734 lnet: rename LND peer to peer_ni > LU-7734 lnet: peer/peer_ni handling adjustments > LU-7734 lnet: proper cpt locking > LU-7734 lnet: protect peer_ni credits > LU-7734 lnet: simplify and fix lnet_select_pathway() > LU-7734 lnet: configuration fixes > LU-7734 lnet: fix lnet_select_pathway() > LU-7734 lnet: Routing fixes part 1 > LU-7734 lnet: Routing fixes part 2 > LU-7734 lnet: fix routing selection > LU-7734 lnet: Fix crash in router_proc.c > LU-7734 lnet: fix NULL access in lnet_peer_aliveness_enabled > LU-7734 lnet: rename peer key_nid to prim_nid > LU-7734 lnet: cpt locking > > Doug Oucharek (1): > LU-7734 lnet: Add peer_ni and NI stats for DLC > > NeilBrown (8): > lnet: replace all lp_ fields with lpni_ > lnet: change struct lnet_peer to struct lnet_peer_ni > lnet: Change lpni_refcount to atomic_t > lnet: change some function names - add 'ni'. > lnet: make lnet_nid_cpt_hash non-static. > lnet: introduce lnet_find_peer_ni_locked() > lnet: lnet_peer_tables_cleanup: use an exclusive lock. > lnet: use BIT() macro for LNET_MD_* flags > > Olaf Weber (3): > LU-7734 lnet: fix lnet_peer_table_cleanup_locked() > LU-7734 lnet: double free in lnet_add_net_common() > LU-7734 lnet: set primary NID in ptlrpc_connection_get() > > > .../lustre/include/linux/libcfs/libcfs_string.h | 12 > drivers/staging/lustre/include/linux/lnet/api.h | 1 > .../staging/lustre/include/linux/lnet/lib-lnet.h | 151 ++- > .../staging/lustre/include/linux/lnet/lib-types.h | 157 ++- > .../lustre/include/uapi/linux/lnet/libcfs_ioctl.h | 11 > .../lustre/include/uapi/linux/lnet/lnet-dlc.h | 104 ++ > .../lustre/include/uapi/linux/lnet/lnet-types.h | 34 - > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 237 ++-- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 118 +- > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 516 ++++----- > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 678 ++++++------ > .../staging/lustre/lnet/klnds/socklnd/socklnd.h | 66 + > .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 207 ++-- > .../lustre/lnet/klnds/socklnd/socklnd_lib.c | 4 > .../lustre/lnet/klnds/socklnd/socklnd_proto.c | 14 > drivers/staging/lustre/lnet/lnet/api-ni.c | 650 ++++++++++- > drivers/staging/lustre/lnet/lnet/config.c | 107 +- > drivers/staging/lustre/lnet/lnet/lib-md.c | 31 + > drivers/staging/lustre/lnet/lnet/lib-move.c | 957 +++++++++++++--- > drivers/staging/lustre/lnet/lnet/lib-msg.c | 18 > drivers/staging/lustre/lnet/lnet/lib-ptl.c | 3 > drivers/staging/lustre/lnet/lnet/module.c | 70 + > drivers/staging/lustre/lnet/lnet/peer.c | 1169 +++++++++++++++++--- > drivers/staging/lustre/lnet/lnet/router.c | 341 +++--- > drivers/staging/lustre/lnet/lnet/router_proc.c | 66 + > drivers/staging/lustre/lustre/include/lustre_net.h | 2 > drivers/staging/lustre/lustre/ptlrpc/connection.c | 1 > drivers/staging/lustre/lustre/ptlrpc/events.c | 5 > drivers/staging/lustre/lustre/ptlrpc/niobuf.c | 40 - > drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 2 > drivers/staging/lustre/lustre/ptlrpc/service.c | 4 > 31 files changed, 4056 insertions(+), 1720 deletions(-) > > -- > Signature > > From jsimmons at infradead.org Sun Sep 30 02:19:36 2018 From: jsimmons at infradead.org (James Simmons) Date: Sun, 30 Sep 2018 03:19:36 +0100 (BST) Subject: [lustre-devel] [PATCH 01/25] lustre: lnet: remove ni from lnet_finalize In-Reply-To: <875zyrizgr.fsf@notabene.neil.brown.name> References: <1537930097-11624-1-git-send-email-jsimmons@infradead.org> <1537930097-11624-2-git-send-email-jsimmons@infradead.org> <875zyrizgr.fsf@notabene.neil.brown.name> Message-ID: > On Tue, Sep 25 2018, James Simmons wrote: > > > From: Sergey Cheremencev > > > > Remove ni from lnet_finalize and kiblnd_txlist_done > > input arguments. Also small code cleanup by introducing > > ibprm_cookie to avoid checkpatch issues. > > What checkpatch issues are avoided ?? more than 80 character. The LND drivers tend to be bad at that. > Thanks, > NeilBrown > > > > > Signed-off-by: Sergey Cheremencev > > WC-bug-id: https://jira.whamcloud.com/browse/LU-9094 > > Seagate-bug-id: MRP-4056 > > Reviewed-on: https://review.whamcloud.com/25375 > > Reviewed-by: Doug Oucharek > > Reviewed-by: Amir Shehata > > Reviewed-by: Oleg Drokin > > Signed-off-by: James Simmons > > --- > > .../staging/lustre/include/linux/lnet/lib-lnet.h | 2 +- > > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c | 2 +- > > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h | 3 +- > > .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | 65 ++++++++++------------ > > .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 3 +- > > .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | 4 +- > > drivers/staging/lustre/lnet/lnet/lib-move.c | 20 +++---- > > drivers/staging/lustre/lnet/lnet/lib-msg.c | 2 +- > > drivers/staging/lustre/lnet/lnet/lo.c | 4 +- > > drivers/staging/lustre/lnet/lnet/net_fault.c | 2 +- > > 10 files changed, 50 insertions(+), 57 deletions(-) > > > > diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > > index aedc88c..53cbf6d 100644 > > --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > > +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h > > @@ -537,7 +537,7 @@ struct lnet_msg *lnet_create_reply_msg(struct lnet_ni *ni, > > void lnet_set_reply_msg_len(struct lnet_ni *ni, struct lnet_msg *msg, > > unsigned int len); > > > > -void lnet_finalize(struct lnet_ni *ni, struct lnet_msg *msg, int rc); > > +void lnet_finalize(struct lnet_msg *msg, int rc); > > > > void lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, > > unsigned int nob); > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > index 75a7e96..b3a4344 100644 > > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c > > @@ -521,7 +521,7 @@ static int kiblnd_del_peer(struct lnet_ni *ni, lnet_nid_t nid) > > > > write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); > > > > - kiblnd_txlist_done(ni, &zombies, -EIO); > > + kiblnd_txlist_done(&zombies, -EIO); > > > > return rc; > > } > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h > > index b1851b5..a3d89ec 100644 > > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h > > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h > > @@ -1034,8 +1034,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer_ni *peer_ni, > > void kiblnd_close_conn_locked(struct kib_conn *conn, int error); > > > > void kiblnd_launch_tx(struct lnet_ni *ni, struct kib_tx *tx, lnet_nid_t nid); > > -void kiblnd_txlist_done(struct lnet_ni *ni, struct list_head *txlist, > > - int status); > > +void kiblnd_txlist_done(struct list_head *txlist, int status); > > > > void kiblnd_qp_event(struct ib_event *event, void *arg); > > void kiblnd_cq_event(struct ib_event *event, void *arg); > > diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > > index cb752dc..debed17 100644 > > --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > > +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c > > @@ -54,14 +54,12 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > > static void kiblnd_check_sends_locked(struct kib_conn *conn); > > > > static void > > -kiblnd_tx_done(struct lnet_ni *ni, struct kib_tx *tx) > > +kiblnd_tx_done(struct kib_tx *tx) > > { > > struct lnet_msg *lntmsg[2]; > > - struct kib_net *net = ni->ni_data; > > int rc; > > int i; > > > > - LASSERT(net); > > LASSERT(!in_interrupt()); > > LASSERT(!tx->tx_queued); /* mustn't be queued for sending */ > > LASSERT(!tx->tx_sending); /* mustn't be awaiting sent callback */ > > @@ -76,8 +74,6 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > > rc = tx->tx_status; > > > > if (tx->tx_conn) { > > - LASSERT(ni == tx->tx_conn->ibc_peer->ibp_ni); > > - > > kiblnd_conn_decref(tx->tx_conn); > > tx->tx_conn = NULL; > > } > > @@ -92,12 +88,12 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > > if (!lntmsg[i]) > > continue; > > > > - lnet_finalize(ni, lntmsg[i], rc); > > + lnet_finalize(lntmsg[i], rc); > > } > > } > > > > void > > -kiblnd_txlist_done(struct lnet_ni *ni, struct list_head *txlist, int status) > > +kiblnd_txlist_done(struct list_head *txlist, int status) > > { > > struct kib_tx *tx; > > > > @@ -108,7 +104,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > > /* complete now */ > > tx->tx_waiting = 0; > > tx->tx_status = status; > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > } > > } > > > > @@ -281,7 +277,7 @@ static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type, > > spin_unlock(&conn->ibc_lock); > > > > if (idle) > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > } > > > > static void > > @@ -794,7 +790,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, > > * posted NOOPs complete > > */ > > spin_unlock(&conn->ibc_lock); > > - kiblnd_tx_done(peer_ni->ibp_ni, tx); > > + kiblnd_tx_done(tx); > > spin_lock(&conn->ibc_lock); > > CDEBUG(D_NET, "%s(%d): redundant or enough NOOP\n", > > libcfs_nid2str(peer_ni->ibp_nid), > > @@ -888,7 +884,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, > > kiblnd_close_conn(conn, rc); > > > > if (done) > > - kiblnd_tx_done(peer_ni->ibp_ni, tx); > > + kiblnd_tx_done(tx); > > > > spin_lock(&conn->ibc_lock); > > > > @@ -1007,7 +1003,7 @@ static int kiblnd_map_tx(struct lnet_ni *ni, struct kib_tx *tx, > > spin_unlock(&conn->ibc_lock); > > > > if (idle) > > - kiblnd_tx_done(conn->ibc_peer->ibp_ni, tx); > > + kiblnd_tx_done(tx); > > } > > > > static void > > @@ -1343,7 +1339,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > > > CWARN("Abort reconnection of %s: %s\n", > > libcfs_nid2str(peer_ni->ibp_nid), reason); > > - kiblnd_txlist_done(peer_ni->ibp_ni, &txs, -ECONNABORTED); > > + kiblnd_txlist_done(&txs, -ECONNABORTED); > > return false; > > } > > > > @@ -1421,7 +1417,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > if (tx) { > > tx->tx_status = -EHOSTUNREACH; > > tx->tx_waiting = 0; > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > } > > return; > > } > > @@ -1557,7 +1553,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > if (rc) { > > CERROR("Can't setup GET sink for %s: %d\n", > > libcfs_nid2str(target.nid), rc); > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > return -EIO; > > } > > > > @@ -1571,7 +1567,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > if (!tx->tx_lntmsg[1]) { > > CERROR("Can't create reply for GET -> %s\n", > > libcfs_nid2str(target.nid)); > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > return -EIO; > > } > > > > @@ -1606,7 +1602,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > if (rc) { > > CERROR("Can't setup PUT src for %s: %d\n", > > libcfs_nid2str(target.nid), rc); > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > return -EIO; > > } > > > > @@ -1697,7 +1693,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > > > if (!nob) { > > /* No RDMA: local completion may happen now! */ > > - lnet_finalize(ni, lntmsg, 0); > > + lnet_finalize(lntmsg, 0); > > } else { > > /* RDMA: lnet_finalize(lntmsg) when it completes */ > > tx->tx_lntmsg[0] = lntmsg; > > @@ -1707,9 +1703,9 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > return; > > > > failed_1: > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > failed_0: > > - lnet_finalize(ni, lntmsg, -EIO); > > + lnet_finalize(lntmsg, -EIO); > > } > > > > int > > @@ -1722,6 +1718,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > struct kib_tx *tx; > > int nob; > > int post_credit = IBLND_POSTRX_PEER_CREDIT; > > + u64 ibprm_cookie; > > int rc = 0; > > > > LASSERT(iov_iter_count(to) <= rlen); > > @@ -1750,17 +1747,18 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > } > > > > rc = 0; > > - lnet_finalize(ni, lntmsg, 0); > > + lnet_finalize(lntmsg, 0); > > break; > > > > case IBLND_MSG_PUT_REQ: { > > + u64 ibprm_cookie = rxmsg->ibm_u.putreq.ibprm_cookie; > > struct kib_msg *txmsg; > > struct kib_rdma_desc *rd; > > > > if (!iov_iter_count(to)) { > > - lnet_finalize(ni, lntmsg, 0); > > - kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, 0, > > - rxmsg->ibm_u.putreq.ibprm_cookie); > > + lnet_finalize(lntmsg, 0); > > + kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, > > + 0, ibprm_cookie); > > break; > > } > > > > @@ -1788,15 +1786,15 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > if (rc) { > > CERROR("Can't setup PUT sink for %s: %d\n", > > libcfs_nid2str(conn->ibc_peer->ibp_nid), rc); > > - kiblnd_tx_done(ni, tx); > > + kiblnd_tx_done(tx); > > /* tell peer_ni it's over */ > > - kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, rc, > > - rxmsg->ibm_u.putreq.ibprm_cookie); > > + kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, > > + rc, ibprm_cookie); > > break; > > } > > > > nob = offsetof(struct kib_putack_msg, ibpam_rd.rd_frags[rd->rd_nfrags]); > > - txmsg->ibm_u.putack.ibpam_src_cookie = rxmsg->ibm_u.putreq.ibprm_cookie; > > + txmsg->ibm_u.putack.ibpam_src_cookie = ibprm_cookie; > > txmsg->ibm_u.putack.ibpam_dst_cookie = tx->tx_cookie; > > > > kiblnd_init_tx_msg(ni, tx, IBLND_MSG_PUT_ACK, nob); > > @@ -1817,8 +1815,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > } else { > > /* GET didn't match anything */ > > kiblnd_send_completion(rx->rx_conn, IBLND_MSG_GET_DONE, > > - -ENODATA, > > - rxmsg->ibm_u.get.ibgm_cookie); > > + -ENODATA, ibprm_cookie); > > } > > break; > > } > > @@ -2016,7 +2013,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > > > spin_unlock(&conn->ibc_lock); > > > > - kiblnd_txlist_done(conn->ibc_peer->ibp_ni, &zombies, -ECONNABORTED); > > + kiblnd_txlist_done(&zombies, -ECONNABORTED); > > } > > > > static void > > @@ -2098,7 +2095,7 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > CNETERR("Deleting messages for %s: connection failed\n", > > libcfs_nid2str(peer_ni->ibp_nid)); > > > > - kiblnd_txlist_done(peer_ni->ibp_ni, &zombies, -EHOSTUNREACH); > > + kiblnd_txlist_done(&zombies, -EHOSTUNREACH); > > } > > > > static void > > @@ -2170,13 +2167,11 @@ static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, > > > > if (!kiblnd_peer_active(peer_ni) || /* peer_ni has been deleted */ > > conn->ibc_comms_error) { /* error has happened already */ > > - struct lnet_ni *ni = peer_ni->ibp_ni; > > - > > /* start to shut down connection */ > > kiblnd_close_conn_locked(conn, -ECONNABORTED); > > write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); > > > > - kiblnd_txlist_done(ni, &txs, -ECONNABORTED); > > + kiblnd_txlist_done(&txs, -ECONNABORTED); > > > > return; > > } > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > index 534ba84..9b9cc87 100644 > > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c > > @@ -1653,8 +1653,7 @@ struct ksock_peer * > > &conn->ksnc_ipaddr, conn->ksnc_port, > > iov_iter_count(&conn->ksnc_rx_to), conn->ksnc_rx_nob_left, > > ktime_get_seconds() - last_rcv); > > - lnet_finalize(conn->ksnc_peer->ksnp_ni, > > - conn->ksnc_cookie, -EIO); > > + lnet_finalize(conn->ksnc_cookie, -EIO); > > break; > > case SOCKNAL_RX_LNET_HEADER: > > if (conn->ksnc_rx_started) > > diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > > index 1bf0170..2e99a17 100644 > > --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > > +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c > > @@ -343,7 +343,7 @@ struct ksock_tx * > > > > ksocknal_free_tx(tx); > > if (lnetmsg) /* KSOCK_MSG_NOOP go without lnetmsg */ > > - lnet_finalize(ni, lnetmsg, rc); > > + lnet_finalize(lnetmsg, rc); > > } > > > > void > > @@ -1226,7 +1226,7 @@ struct ksock_route * > > le64_to_cpu(lhdr->src_nid) != id->nid); > > } > > > > - lnet_finalize(conn->ksnc_peer->ksnp_ni, conn->ksnc_cookie, rc); > > + lnet_finalize(conn->ksnc_cookie, rc); > > > > if (rc) { > > ksocknal_new_packet(conn, 0); > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c > > index d39331f..a213387 100644 > > --- a/drivers/staging/lustre/lnet/lnet/lib-move.c > > +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c > > @@ -408,7 +408,7 @@ > > } > > rc = ni->ni_net->net_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen); > > if (rc < 0) > > - lnet_finalize(ni, msg, rc); > > + lnet_finalize(msg, rc); > > } > > > > static void > > @@ -462,7 +462,7 @@ > > > > rc = ni->ni_net->net_lnd->lnd_send(ni, priv, msg); > > if (rc < 0) > > - lnet_finalize(ni, msg, rc); > > + lnet_finalize(msg, rc); > > } > > > > static int > > @@ -637,7 +637,7 @@ > > CNETERR("Dropping message for %s: peer not alive\n", > > libcfs_id2str(msg->msg_target)); > > if (do_send) > > - lnet_finalize(ni, msg, -EHOSTUNREACH); > > + lnet_finalize(msg, -EHOSTUNREACH); > > > > lnet_net_lock(cpt); > > return -EHOSTUNREACH; > > @@ -650,7 +650,7 @@ > > CNETERR("Aborting message for %s: LNetM[DE]Unlink() already called on the MD/ME.\n", > > libcfs_id2str(msg->msg_target)); > > if (do_send) > > - lnet_finalize(ni, msg, -ECANCELED); > > + lnet_finalize(msg, -ECANCELED); > > > > lnet_net_lock(cpt); > > return -ECANCELED; > > @@ -915,7 +915,7 @@ > > lnet_ni_recv(msg->msg_rxni, msg->msg_private, NULL, > > 0, 0, 0, msg->msg_hdr.payload_length); > > list_del_init(&msg->msg_list); > > - lnet_finalize(NULL, msg, -ECANCELED); > > + lnet_finalize(msg, -ECANCELED); > > } > > > > lnet_net_lock(cpt); > > @@ -1914,7 +1914,7 @@ > > libcfs_nid2str(ni->ni_nid), > > libcfs_id2str(info.mi_id), rc); > > > > - lnet_finalize(ni, msg, rc); > > + lnet_finalize(msg, rc); > > } > > > > return 0; > > @@ -2402,7 +2402,7 @@ > > > > free_drop: > > LASSERT(!msg->msg_md); > > - lnet_finalize(ni, msg, rc); > > + lnet_finalize(msg, rc); > > > > drop: > > lnet_drop_message(ni, cpt, private, payload_length); > > @@ -2447,7 +2447,7 @@ > > * but we still should give error code so lnet_msg_decommit() > > * can skip counters operations and other checks. > > */ > > - lnet_finalize(msg->msg_rxni, msg, -ENOENT); > > + lnet_finalize(msg, -ENOENT); > > } > > } > > > > @@ -2605,7 +2605,7 @@ > > if (rc) { > > CNETERR("Error sending PUT to %s: %d\n", > > libcfs_id2str(target), rc); > > - lnet_finalize(NULL, msg, rc); > > + lnet_finalize(msg, rc); > > } > > > > /* completion will be signalled by an event */ > > @@ -2804,7 +2804,7 @@ struct lnet_msg * > > if (rc < 0) { > > CNETERR("Error sending GET to %s: %d\n", > > libcfs_id2str(target), rc); > > - lnet_finalize(NULL, msg, rc); > > + lnet_finalize(msg, rc); > > } > > > > /* completion will be signalled by an event */ > > diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c > > index aa28b6a..00be9ab 100644 > > --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c > > +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c > > @@ -452,7 +452,7 @@ > > } > > > > void > > -lnet_finalize(struct lnet_ni *ni, struct lnet_msg *msg, int status) > > +lnet_finalize(struct lnet_msg *msg, int status) > > { > > struct lnet_msg_container *container; > > int my_slot; > > diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c > > index 8167980..c8a1eb62 100644 > > --- a/drivers/staging/lustre/lnet/lnet/lo.c > > +++ b/drivers/staging/lustre/lnet/lnet/lo.c > > @@ -62,10 +62,10 @@ > > sendmsg->msg_offset, > > iov_iter_count(to)); > > > > - lnet_finalize(ni, lntmsg, 0); > > + lnet_finalize(lntmsg, 0); > > } > > > > - lnet_finalize(ni, sendmsg, 0); > > + lnet_finalize(sendmsg, 0); > > return 0; > > } > > > > diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c > > index 17891f6..3841bac 100644 > > --- a/drivers/staging/lustre/lnet/lnet/net_fault.c > > +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c > > @@ -633,7 +633,7 @@ struct delay_daemon_data { > > } > > > > lnet_drop_message(ni, cpt, msg->msg_private, msg->msg_len); > > - lnet_finalize(ni, msg, rc); > > + lnet_finalize(msg, rc); > > } > > } > > > > -- > > 1.8.3.1 >