Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1 | /* |
| 2 | * GPL HEADER START |
| 3 | * |
| 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 only, |
| 8 | * as published by the Free Software Foundation. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, but |
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | * General Public License version 2 for more details (a copy is included |
| 14 | * in the LICENSE file that accompanied this code). |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * version 2 along with this program; If not, see |
Oleg Drokin | 6a5b99a | 2016-06-14 23:33:40 -0400 | [diff] [blame] | 18 | * http://www.gnu.org/licenses/gpl-2.0.html |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 19 | * |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 20 | * GPL HEADER END |
| 21 | */ |
| 22 | /* |
| 23 | * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
| 24 | * Use is subject to license terms. |
| 25 | * |
Andreas Dilger | 1dc563a | 2015-11-08 18:09:37 -0500 | [diff] [blame] | 26 | * Copyright (c) 2011, 2015, Intel Corporation. |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 27 | */ |
| 28 | /* |
| 29 | * This file is part of Lustre, http://www.lustre.org/ |
| 30 | * Lustre is a trademark of Sun Microsystems, Inc. |
| 31 | */ |
| 32 | |
| 33 | #define DEBUG_SUBSYSTEM S_LNET |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 34 | #include <linux/log2.h> |
Tina Ruchandani | 9056be3 | 2014-10-30 14:35:01 -0700 | [diff] [blame] | 35 | #include <linux/ktime.h> |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 36 | |
James Simmons | db18b8e | 2015-06-11 15:18:12 -0400 | [diff] [blame] | 37 | #include "../../include/linux/lnet/lib-lnet.h" |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 38 | #include "../../include/linux/lnet/lib-dlc.h" |
James Simmons | db18b8e | 2015-06-11 15:18:12 -0400 | [diff] [blame] | 39 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 40 | #define D_LNI D_CONSOLE |
| 41 | |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 42 | lnet_t the_lnet; /* THE state of the network */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 43 | EXPORT_SYMBOL(the_lnet); |
| 44 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 45 | static char *ip2nets = ""; |
Peng Tao | 8cc7b4b | 2013-11-21 22:28:30 +0800 | [diff] [blame] | 46 | module_param(ip2nets, charp, 0444); |
| 47 | MODULE_PARM_DESC(ip2nets, "LNET network <- IP table"); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 48 | |
| 49 | static char *networks = ""; |
Peng Tao | 8cc7b4b | 2013-11-21 22:28:30 +0800 | [diff] [blame] | 50 | module_param(networks, charp, 0444); |
| 51 | MODULE_PARM_DESC(networks, "local networks"); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 52 | |
| 53 | static char *routes = ""; |
Peng Tao | 8cc7b4b | 2013-11-21 22:28:30 +0800 | [diff] [blame] | 54 | module_param(routes, charp, 0444); |
| 55 | MODULE_PARM_DESC(routes, "routes to non-local networks"); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 56 | |
| 57 | static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT; |
Peng Tao | 8cc7b4b | 2013-11-21 22:28:30 +0800 | [diff] [blame] | 58 | module_param(rnet_htable_size, int, 0444); |
| 59 | MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table"); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 60 | |
Oleg Drokin | fccfde7 | 2016-01-03 12:05:32 -0500 | [diff] [blame] | 61 | static int lnet_ping(lnet_process_id_t id, int timeout_ms, |
Oleg Drokin | 4eb53df | 2016-01-03 12:05:41 -0500 | [diff] [blame] | 62 | lnet_process_id_t __user *ids, int n_ids); |
Oleg Drokin | fccfde7 | 2016-01-03 12:05:32 -0500 | [diff] [blame] | 63 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 64 | static char * |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 65 | lnet_get_routes(void) |
| 66 | { |
| 67 | return routes; |
| 68 | } |
| 69 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 70 | static char * |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 71 | lnet_get_networks(void) |
| 72 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 73 | char *nets; |
| 74 | int rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 75 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 76 | if (*networks && *ip2nets) { |
Gulsah Kose | 8ad5360 | 2014-09-20 21:39:46 +0300 | [diff] [blame] | 77 | LCONSOLE_ERROR_MSG(0x101, "Please specify EITHER 'networks' or 'ip2nets' but not both at once\n"); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 78 | return NULL; |
| 79 | } |
| 80 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 81 | if (*ip2nets) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 82 | rc = lnet_parse_ip2nets(&nets, ip2nets); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 83 | return !rc ? nets : NULL; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 84 | } |
| 85 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 86 | if (*networks) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 87 | return networks; |
| 88 | |
| 89 | return "tcp"; |
| 90 | } |
| 91 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 92 | static void |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 93 | lnet_init_locks(void) |
| 94 | { |
| 95 | spin_lock_init(&the_lnet.ln_eq_wait_lock); |
| 96 | init_waitqueue_head(&the_lnet.ln_eq_waitq); |
Amir Shehata | 7f8b70e | 2016-02-22 17:29:16 -0500 | [diff] [blame] | 97 | init_waitqueue_head(&the_lnet.ln_rc_waitq); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 98 | mutex_init(&the_lnet.ln_lnd_mutex); |
| 99 | mutex_init(&the_lnet.ln_api_mutex); |
| 100 | } |
| 101 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 102 | static int |
| 103 | lnet_create_remote_nets_table(void) |
| 104 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 105 | int i; |
| 106 | struct list_head *hash; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 107 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 108 | LASSERT(!the_lnet.ln_remote_nets_hash); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 109 | LASSERT(the_lnet.ln_remote_nets_hbits > 0); |
| 110 | LIBCFS_ALLOC(hash, LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash)); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 111 | if (!hash) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 112 | CERROR("Failed to create remote nets hash table\n"); |
| 113 | return -ENOMEM; |
| 114 | } |
| 115 | |
| 116 | for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++) |
| 117 | INIT_LIST_HEAD(&hash[i]); |
| 118 | the_lnet.ln_remote_nets_hash = hash; |
| 119 | return 0; |
| 120 | } |
| 121 | |
| 122 | static void |
| 123 | lnet_destroy_remote_nets_table(void) |
| 124 | { |
Dmitry Eremin | 1ae2bdb | 2014-04-27 22:25:56 -0400 | [diff] [blame] | 125 | int i; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 126 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 127 | if (!the_lnet.ln_remote_nets_hash) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 128 | return; |
| 129 | |
| 130 | for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++) |
| 131 | LASSERT(list_empty(&the_lnet.ln_remote_nets_hash[i])); |
| 132 | |
| 133 | LIBCFS_FREE(the_lnet.ln_remote_nets_hash, |
Dmitry Eremin | 1ae2bdb | 2014-04-27 22:25:56 -0400 | [diff] [blame] | 134 | LNET_REMOTE_NETS_HASH_SIZE * |
| 135 | sizeof(the_lnet.ln_remote_nets_hash[0])); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 136 | the_lnet.ln_remote_nets_hash = NULL; |
| 137 | } |
| 138 | |
| 139 | static void |
| 140 | lnet_destroy_locks(void) |
| 141 | { |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 142 | if (the_lnet.ln_res_lock) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 143 | cfs_percpt_lock_free(the_lnet.ln_res_lock); |
| 144 | the_lnet.ln_res_lock = NULL; |
| 145 | } |
| 146 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 147 | if (the_lnet.ln_net_lock) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 148 | cfs_percpt_lock_free(the_lnet.ln_net_lock); |
| 149 | the_lnet.ln_net_lock = NULL; |
| 150 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 151 | } |
| 152 | |
| 153 | static int |
| 154 | lnet_create_locks(void) |
| 155 | { |
| 156 | lnet_init_locks(); |
| 157 | |
| 158 | the_lnet.ln_res_lock = cfs_percpt_lock_alloc(lnet_cpt_table()); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 159 | if (!the_lnet.ln_res_lock) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 160 | goto failed; |
| 161 | |
| 162 | the_lnet.ln_net_lock = cfs_percpt_lock_alloc(lnet_cpt_table()); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 163 | if (!the_lnet.ln_net_lock) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 164 | goto failed; |
| 165 | |
| 166 | return 0; |
| 167 | |
| 168 | failed: |
| 169 | lnet_destroy_locks(); |
| 170 | return -ENOMEM; |
| 171 | } |
| 172 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 173 | static void lnet_assert_wire_constants(void) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 174 | { |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 175 | /* |
| 176 | * Wire protocol assertions generated by 'wirecheck' |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 177 | * running on Linux robert.bartonsoftware.com 2.6.8-1.521 |
| 178 | * #1 Mon Aug 16 09:01:18 EDT 2004 i686 athlon i386 GNU/Linux |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 179 | * with gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7) |
| 180 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 181 | |
| 182 | /* Constants... */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 183 | CLASSERT(LNET_PROTO_TCP_MAGIC == 0xeebc0ded); |
| 184 | CLASSERT(LNET_PROTO_TCP_VERSION_MAJOR == 1); |
| 185 | CLASSERT(LNET_PROTO_TCP_VERSION_MINOR == 0); |
| 186 | CLASSERT(LNET_MSG_ACK == 0); |
| 187 | CLASSERT(LNET_MSG_PUT == 1); |
| 188 | CLASSERT(LNET_MSG_GET == 2); |
| 189 | CLASSERT(LNET_MSG_REPLY == 3); |
| 190 | CLASSERT(LNET_MSG_HELLO == 4); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 191 | |
| 192 | /* Checks for struct ptl_handle_wire_t */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 193 | CLASSERT((int)sizeof(lnet_handle_wire_t) == 16); |
| 194 | CLASSERT((int)offsetof(lnet_handle_wire_t, wh_interface_cookie) == 0); |
| 195 | CLASSERT((int)sizeof(((lnet_handle_wire_t *)0)->wh_interface_cookie) == 8); |
| 196 | CLASSERT((int)offsetof(lnet_handle_wire_t, wh_object_cookie) == 8); |
| 197 | CLASSERT((int)sizeof(((lnet_handle_wire_t *)0)->wh_object_cookie) == 8); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 198 | |
| 199 | /* Checks for struct lnet_magicversion_t */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 200 | CLASSERT((int)sizeof(lnet_magicversion_t) == 8); |
| 201 | CLASSERT((int)offsetof(lnet_magicversion_t, magic) == 0); |
| 202 | CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->magic) == 4); |
| 203 | CLASSERT((int)offsetof(lnet_magicversion_t, version_major) == 4); |
| 204 | CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->version_major) == 2); |
| 205 | CLASSERT((int)offsetof(lnet_magicversion_t, version_minor) == 6); |
| 206 | CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->version_minor) == 2); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 207 | |
| 208 | /* Checks for struct lnet_hdr_t */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 209 | CLASSERT((int)sizeof(lnet_hdr_t) == 72); |
| 210 | CLASSERT((int)offsetof(lnet_hdr_t, dest_nid) == 0); |
| 211 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->dest_nid) == 8); |
| 212 | CLASSERT((int)offsetof(lnet_hdr_t, src_nid) == 8); |
| 213 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->src_nid) == 8); |
| 214 | CLASSERT((int)offsetof(lnet_hdr_t, dest_pid) == 16); |
| 215 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->dest_pid) == 4); |
| 216 | CLASSERT((int)offsetof(lnet_hdr_t, src_pid) == 20); |
| 217 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->src_pid) == 4); |
| 218 | CLASSERT((int)offsetof(lnet_hdr_t, type) == 24); |
| 219 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->type) == 4); |
| 220 | CLASSERT((int)offsetof(lnet_hdr_t, payload_length) == 28); |
| 221 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->payload_length) == 4); |
| 222 | CLASSERT((int)offsetof(lnet_hdr_t, msg) == 32); |
| 223 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg) == 40); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 224 | |
| 225 | /* Ack */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 226 | CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.dst_wmd) == 32); |
| 227 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.dst_wmd) == 16); |
| 228 | CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.match_bits) == 48); |
| 229 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.match_bits) == 8); |
| 230 | CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.mlength) == 56); |
| 231 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.mlength) == 4); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 232 | |
| 233 | /* Put */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 234 | CLASSERT((int)offsetof(lnet_hdr_t, msg.put.ack_wmd) == 32); |
| 235 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.ack_wmd) == 16); |
| 236 | CLASSERT((int)offsetof(lnet_hdr_t, msg.put.match_bits) == 48); |
| 237 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.match_bits) == 8); |
| 238 | CLASSERT((int)offsetof(lnet_hdr_t, msg.put.hdr_data) == 56); |
| 239 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.hdr_data) == 8); |
| 240 | CLASSERT((int)offsetof(lnet_hdr_t, msg.put.ptl_index) == 64); |
| 241 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.ptl_index) == 4); |
| 242 | CLASSERT((int)offsetof(lnet_hdr_t, msg.put.offset) == 68); |
| 243 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.offset) == 4); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 244 | |
| 245 | /* Get */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 246 | CLASSERT((int)offsetof(lnet_hdr_t, msg.get.return_wmd) == 32); |
| 247 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.return_wmd) == 16); |
| 248 | CLASSERT((int)offsetof(lnet_hdr_t, msg.get.match_bits) == 48); |
| 249 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.match_bits) == 8); |
| 250 | CLASSERT((int)offsetof(lnet_hdr_t, msg.get.ptl_index) == 56); |
| 251 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.ptl_index) == 4); |
| 252 | CLASSERT((int)offsetof(lnet_hdr_t, msg.get.src_offset) == 60); |
| 253 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.src_offset) == 4); |
| 254 | CLASSERT((int)offsetof(lnet_hdr_t, msg.get.sink_length) == 64); |
| 255 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.sink_length) == 4); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 256 | |
| 257 | /* Reply */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 258 | CLASSERT((int)offsetof(lnet_hdr_t, msg.reply.dst_wmd) == 32); |
| 259 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.reply.dst_wmd) == 16); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 260 | |
| 261 | /* Hello */ |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 262 | CLASSERT((int)offsetof(lnet_hdr_t, msg.hello.incarnation) == 32); |
| 263 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.hello.incarnation) == 8); |
| 264 | CLASSERT((int)offsetof(lnet_hdr_t, msg.hello.type) == 40); |
| 265 | CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.hello.type) == 4); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 266 | } |
| 267 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 268 | static lnd_t * |
Dmitry Eremin | 80feb1e | 2015-10-21 21:52:47 -0400 | [diff] [blame] | 269 | lnet_find_lnd_by_type(__u32 type) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 270 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 271 | lnd_t *lnd; |
| 272 | struct list_head *tmp; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 273 | |
| 274 | /* holding lnd mutex */ |
Thomas Wood | 565f3d2 | 2014-11-17 11:54:40 -0800 | [diff] [blame] | 275 | list_for_each(tmp, &the_lnet.ln_lnds) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 276 | lnd = list_entry(tmp, lnd_t, lnd_list); |
| 277 | |
Dmitry Eremin | 80feb1e | 2015-10-21 21:52:47 -0400 | [diff] [blame] | 278 | if (lnd->lnd_type == type) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 279 | return lnd; |
| 280 | } |
| 281 | |
| 282 | return NULL; |
| 283 | } |
| 284 | |
| 285 | void |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 286 | lnet_register_lnd(lnd_t *lnd) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 287 | { |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 288 | mutex_lock(&the_lnet.ln_lnd_mutex); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 289 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 290 | LASSERT(libcfs_isknown_lnd(lnd->lnd_type)); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 291 | LASSERT(!lnet_find_lnd_by_type(lnd->lnd_type)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 292 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 293 | list_add_tail(&lnd->lnd_list, &the_lnet.ln_lnds); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 294 | lnd->lnd_refcount = 0; |
| 295 | |
| 296 | CDEBUG(D_NET, "%s LND registered\n", libcfs_lnd2str(lnd->lnd_type)); |
| 297 | |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 298 | mutex_unlock(&the_lnet.ln_lnd_mutex); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 299 | } |
| 300 | EXPORT_SYMBOL(lnet_register_lnd); |
| 301 | |
| 302 | void |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 303 | lnet_unregister_lnd(lnd_t *lnd) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 304 | { |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 305 | mutex_lock(&the_lnet.ln_lnd_mutex); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 306 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 307 | LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == lnd); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 308 | LASSERT(!lnd->lnd_refcount); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 309 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 310 | list_del(&lnd->lnd_list); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 311 | CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type)); |
| 312 | |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 313 | mutex_unlock(&the_lnet.ln_lnd_mutex); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 314 | } |
| 315 | EXPORT_SYMBOL(lnet_unregister_lnd); |
| 316 | |
| 317 | void |
| 318 | lnet_counters_get(lnet_counters_t *counters) |
| 319 | { |
| 320 | lnet_counters_t *ctr; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 321 | int i; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 322 | |
| 323 | memset(counters, 0, sizeof(*counters)); |
| 324 | |
| 325 | lnet_net_lock(LNET_LOCK_EX); |
| 326 | |
| 327 | cfs_percpt_for_each(ctr, i, the_lnet.ln_counters) { |
| 328 | counters->msgs_max += ctr->msgs_max; |
| 329 | counters->msgs_alloc += ctr->msgs_alloc; |
| 330 | counters->errors += ctr->errors; |
| 331 | counters->send_count += ctr->send_count; |
| 332 | counters->recv_count += ctr->recv_count; |
| 333 | counters->route_count += ctr->route_count; |
Matt Ezell | b3d0dfe | 2014-04-27 13:06:30 -0400 | [diff] [blame] | 334 | counters->drop_count += ctr->drop_count; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 335 | counters->send_length += ctr->send_length; |
| 336 | counters->recv_length += ctr->recv_length; |
| 337 | counters->route_length += ctr->route_length; |
| 338 | counters->drop_length += ctr->drop_length; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 339 | } |
| 340 | lnet_net_unlock(LNET_LOCK_EX); |
| 341 | } |
| 342 | EXPORT_SYMBOL(lnet_counters_get); |
| 343 | |
| 344 | void |
| 345 | lnet_counters_reset(void) |
| 346 | { |
| 347 | lnet_counters_t *counters; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 348 | int i; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 349 | |
| 350 | lnet_net_lock(LNET_LOCK_EX); |
| 351 | |
| 352 | cfs_percpt_for_each(counters, i, the_lnet.ln_counters) |
| 353 | memset(counters, 0, sizeof(lnet_counters_t)); |
| 354 | |
| 355 | lnet_net_unlock(LNET_LOCK_EX); |
| 356 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 357 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 358 | static char * |
| 359 | lnet_res_type2str(int type) |
| 360 | { |
| 361 | switch (type) { |
| 362 | default: |
| 363 | LBUG(); |
| 364 | case LNET_COOKIE_TYPE_MD: |
| 365 | return "MD"; |
| 366 | case LNET_COOKIE_TYPE_ME: |
| 367 | return "ME"; |
| 368 | case LNET_COOKIE_TYPE_EQ: |
| 369 | return "EQ"; |
| 370 | } |
| 371 | } |
| 372 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 373 | static void |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 374 | lnet_res_container_cleanup(struct lnet_res_container *rec) |
| 375 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 376 | int count = 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 377 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 378 | if (!rec->rec_type) /* not set yet, it's uninitialized */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 379 | return; |
| 380 | |
| 381 | while (!list_empty(&rec->rec_active)) { |
| 382 | struct list_head *e = rec->rec_active.next; |
| 383 | |
| 384 | list_del_init(e); |
| 385 | if (rec->rec_type == LNET_COOKIE_TYPE_EQ) { |
| 386 | lnet_eq_free(list_entry(e, lnet_eq_t, eq_list)); |
| 387 | |
| 388 | } else if (rec->rec_type == LNET_COOKIE_TYPE_MD) { |
| 389 | lnet_md_free(list_entry(e, lnet_libmd_t, md_list)); |
| 390 | |
| 391 | } else { /* NB: Active MEs should be attached on portals */ |
| 392 | LBUG(); |
| 393 | } |
| 394 | count++; |
| 395 | } |
| 396 | |
| 397 | if (count > 0) { |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 398 | /* |
| 399 | * Found alive MD/ME/EQ, user really should unlink/free |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 400 | * all of them before finalize LNet, but if someone didn't, |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 401 | * we have to recycle garbage for him |
| 402 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 403 | CERROR("%d active elements on exit of %s container\n", |
| 404 | count, lnet_res_type2str(rec->rec_type)); |
| 405 | } |
| 406 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 407 | if (rec->rec_lh_hash) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 408 | LIBCFS_FREE(rec->rec_lh_hash, |
| 409 | LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0])); |
| 410 | rec->rec_lh_hash = NULL; |
| 411 | } |
| 412 | |
| 413 | rec->rec_type = 0; /* mark it as finalized */ |
| 414 | } |
| 415 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 416 | static int |
James Simmons | 3944536 | 2015-06-03 16:43:21 -0400 | [diff] [blame] | 417 | lnet_res_container_setup(struct lnet_res_container *rec, int cpt, int type) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 418 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 419 | int rc = 0; |
| 420 | int i; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 421 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 422 | LASSERT(!rec->rec_type); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 423 | |
| 424 | rec->rec_type = type; |
| 425 | INIT_LIST_HEAD(&rec->rec_active); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 426 | rec->rec_lh_cookie = (cpt << LNET_COOKIE_TYPE_BITS) | type; |
| 427 | |
| 428 | /* Arbitrary choice of hash table size */ |
| 429 | LIBCFS_CPT_ALLOC(rec->rec_lh_hash, lnet_cpt_table(), cpt, |
| 430 | LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0])); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 431 | if (!rec->rec_lh_hash) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 432 | rc = -ENOMEM; |
| 433 | goto out; |
| 434 | } |
| 435 | |
| 436 | for (i = 0; i < LNET_LH_HASH_SIZE; i++) |
| 437 | INIT_LIST_HEAD(&rec->rec_lh_hash[i]); |
| 438 | |
| 439 | return 0; |
| 440 | |
| 441 | out: |
| 442 | CERROR("Failed to setup %s resource container\n", |
| 443 | lnet_res_type2str(type)); |
| 444 | lnet_res_container_cleanup(rec); |
| 445 | return rc; |
| 446 | } |
| 447 | |
| 448 | static void |
| 449 | lnet_res_containers_destroy(struct lnet_res_container **recs) |
| 450 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 451 | struct lnet_res_container *rec; |
| 452 | int i; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 453 | |
| 454 | cfs_percpt_for_each(rec, i, recs) |
| 455 | lnet_res_container_cleanup(rec); |
| 456 | |
| 457 | cfs_percpt_free(recs); |
| 458 | } |
| 459 | |
| 460 | static struct lnet_res_container ** |
James Simmons | 3944536 | 2015-06-03 16:43:21 -0400 | [diff] [blame] | 461 | lnet_res_containers_create(int type) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 462 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 463 | struct lnet_res_container **recs; |
| 464 | struct lnet_res_container *rec; |
| 465 | int rc; |
| 466 | int i; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 467 | |
| 468 | recs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*rec)); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 469 | if (!recs) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 470 | CERROR("Failed to allocate %s resource containers\n", |
| 471 | lnet_res_type2str(type)); |
| 472 | return NULL; |
| 473 | } |
| 474 | |
| 475 | cfs_percpt_for_each(rec, i, recs) { |
James Simmons | 3944536 | 2015-06-03 16:43:21 -0400 | [diff] [blame] | 476 | rc = lnet_res_container_setup(rec, i, type); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 477 | if (rc) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 478 | lnet_res_containers_destroy(recs); |
| 479 | return NULL; |
| 480 | } |
| 481 | } |
| 482 | |
| 483 | return recs; |
| 484 | } |
| 485 | |
| 486 | lnet_libhandle_t * |
| 487 | lnet_res_lh_lookup(struct lnet_res_container *rec, __u64 cookie) |
| 488 | { |
| 489 | /* ALWAYS called with lnet_res_lock held */ |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 490 | struct list_head *head; |
| 491 | lnet_libhandle_t *lh; |
| 492 | unsigned int hash; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 493 | |
| 494 | if ((cookie & LNET_COOKIE_MASK) != rec->rec_type) |
| 495 | return NULL; |
| 496 | |
| 497 | hash = cookie >> (LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS); |
| 498 | head = &rec->rec_lh_hash[hash & LNET_LH_HASH_MASK]; |
| 499 | |
| 500 | list_for_each_entry(lh, head, lh_hash_chain) { |
| 501 | if (lh->lh_cookie == cookie) |
| 502 | return lh; |
| 503 | } |
| 504 | |
| 505 | return NULL; |
| 506 | } |
| 507 | |
| 508 | void |
| 509 | lnet_res_lh_initialize(struct lnet_res_container *rec, lnet_libhandle_t *lh) |
| 510 | { |
| 511 | /* ALWAYS called with lnet_res_lock held */ |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 512 | unsigned int ibits = LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS; |
| 513 | unsigned int hash; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 514 | |
| 515 | lh->lh_cookie = rec->rec_lh_cookie; |
| 516 | rec->rec_lh_cookie += 1 << ibits; |
| 517 | |
| 518 | hash = (lh->lh_cookie >> ibits) & LNET_LH_HASH_MASK; |
| 519 | |
| 520 | list_add(&lh->lh_hash_chain, &rec->rec_lh_hash[hash]); |
| 521 | } |
| 522 | |
Frank Zago | 09f2f17 | 2016-02-22 17:29:06 -0500 | [diff] [blame] | 523 | static int lnet_unprepare(void); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 524 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 525 | static int |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 526 | lnet_prepare(lnet_pid_t requested_pid) |
| 527 | { |
| 528 | /* Prepare to bring up the network */ |
| 529 | struct lnet_res_container **recs; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 530 | int rc = 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 531 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 532 | if (requested_pid == LNET_PID_ANY) { |
| 533 | /* Don't instantiate LNET just for me */ |
| 534 | return -ENETDOWN; |
| 535 | } |
| 536 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 537 | LASSERT(!the_lnet.ln_refcount); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 538 | |
| 539 | the_lnet.ln_routing = 0; |
| 540 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 541 | LASSERT(!(requested_pid & LNET_PID_USERFLAG)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 542 | the_lnet.ln_pid = requested_pid; |
| 543 | |
| 544 | INIT_LIST_HEAD(&the_lnet.ln_test_peers); |
| 545 | INIT_LIST_HEAD(&the_lnet.ln_nis); |
| 546 | INIT_LIST_HEAD(&the_lnet.ln_nis_cpt); |
| 547 | INIT_LIST_HEAD(&the_lnet.ln_nis_zombie); |
| 548 | INIT_LIST_HEAD(&the_lnet.ln_routers); |
Liang Zhen | 0fbbced | 2016-03-07 18:10:16 -0500 | [diff] [blame] | 549 | INIT_LIST_HEAD(&the_lnet.ln_drop_rules); |
Liang Zhen | b7acfc9 | 2016-03-07 18:10:17 -0500 | [diff] [blame] | 550 | INIT_LIST_HEAD(&the_lnet.ln_delay_rules); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 551 | |
| 552 | rc = lnet_create_remote_nets_table(); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 553 | if (rc) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 554 | goto failed; |
Shivani Bhardwaj | 7bcd831 | 2015-10-29 12:08:06 +0530 | [diff] [blame] | 555 | /* |
| 556 | * NB the interface cookie in wire handles guards against delayed |
| 557 | * replies and ACKs appearing valid after reboot. |
| 558 | */ |
| 559 | the_lnet.ln_interface_cookie = ktime_get_ns(); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 560 | |
| 561 | the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(), |
| 562 | sizeof(lnet_counters_t)); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 563 | if (!the_lnet.ln_counters) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 564 | CERROR("Failed to allocate counters for LNet\n"); |
| 565 | rc = -ENOMEM; |
| 566 | goto failed; |
| 567 | } |
| 568 | |
| 569 | rc = lnet_peer_tables_create(); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 570 | if (rc) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 571 | goto failed; |
| 572 | |
| 573 | rc = lnet_msg_containers_create(); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 574 | if (rc) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 575 | goto failed; |
| 576 | |
| 577 | rc = lnet_res_container_setup(&the_lnet.ln_eq_container, 0, |
James Simmons | 3944536 | 2015-06-03 16:43:21 -0400 | [diff] [blame] | 578 | LNET_COOKIE_TYPE_EQ); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 579 | if (rc) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 580 | goto failed; |
| 581 | |
James Simmons | 3944536 | 2015-06-03 16:43:21 -0400 | [diff] [blame] | 582 | recs = lnet_res_containers_create(LNET_COOKIE_TYPE_ME); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 583 | if (!recs) { |
Julia Lawall | a18ac31 | 2015-04-05 14:06:35 +0200 | [diff] [blame] | 584 | rc = -ENOMEM; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 585 | goto failed; |
Julia Lawall | a18ac31 | 2015-04-05 14:06:35 +0200 | [diff] [blame] | 586 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 587 | |
| 588 | the_lnet.ln_me_containers = recs; |
| 589 | |
James Simmons | 3944536 | 2015-06-03 16:43:21 -0400 | [diff] [blame] | 590 | recs = lnet_res_containers_create(LNET_COOKIE_TYPE_MD); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 591 | if (!recs) { |
Julia Lawall | a18ac31 | 2015-04-05 14:06:35 +0200 | [diff] [blame] | 592 | rc = -ENOMEM; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 593 | goto failed; |
Julia Lawall | a18ac31 | 2015-04-05 14:06:35 +0200 | [diff] [blame] | 594 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 595 | |
| 596 | the_lnet.ln_md_containers = recs; |
| 597 | |
| 598 | rc = lnet_portals_create(); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 599 | if (rc) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 600 | CERROR("Failed to create portals for LNet: %d\n", rc); |
| 601 | goto failed; |
| 602 | } |
| 603 | |
| 604 | return 0; |
| 605 | |
| 606 | failed: |
| 607 | lnet_unprepare(); |
| 608 | return rc; |
| 609 | } |
| 610 | |
Frank Zago | 09f2f17 | 2016-02-22 17:29:06 -0500 | [diff] [blame] | 611 | static int |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 612 | lnet_unprepare(void) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 613 | { |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 614 | /* |
| 615 | * NB no LNET_LOCK since this is the last reference. All LND instances |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 616 | * have shut down already, so it is safe to unlink and free all |
| 617 | * descriptors, even those that appear committed to a network op (eg MD |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 618 | * with non-zero pending count) |
| 619 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 620 | lnet_fail_nid(LNET_NID_ANY, 0); |
| 621 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 622 | LASSERT(!the_lnet.ln_refcount); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 623 | LASSERT(list_empty(&the_lnet.ln_test_peers)); |
| 624 | LASSERT(list_empty(&the_lnet.ln_nis)); |
| 625 | LASSERT(list_empty(&the_lnet.ln_nis_cpt)); |
| 626 | LASSERT(list_empty(&the_lnet.ln_nis_zombie)); |
| 627 | |
| 628 | lnet_portals_destroy(); |
| 629 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 630 | if (the_lnet.ln_md_containers) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 631 | lnet_res_containers_destroy(the_lnet.ln_md_containers); |
| 632 | the_lnet.ln_md_containers = NULL; |
| 633 | } |
| 634 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 635 | if (the_lnet.ln_me_containers) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 636 | lnet_res_containers_destroy(the_lnet.ln_me_containers); |
| 637 | the_lnet.ln_me_containers = NULL; |
| 638 | } |
| 639 | |
| 640 | lnet_res_container_cleanup(&the_lnet.ln_eq_container); |
| 641 | |
| 642 | lnet_msg_containers_destroy(); |
| 643 | lnet_peer_tables_destroy(); |
Amir Shehata | 86ef625 | 2016-02-15 10:25:53 -0500 | [diff] [blame] | 644 | lnet_rtrpools_free(0); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 645 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 646 | if (the_lnet.ln_counters) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 647 | cfs_percpt_free(the_lnet.ln_counters); |
| 648 | the_lnet.ln_counters = NULL; |
| 649 | } |
| 650 | lnet_destroy_remote_nets_table(); |
| 651 | |
| 652 | return 0; |
| 653 | } |
| 654 | |
| 655 | lnet_ni_t * |
| 656 | lnet_net2ni_locked(__u32 net, int cpt) |
| 657 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 658 | struct list_head *tmp; |
| 659 | lnet_ni_t *ni; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 660 | |
| 661 | LASSERT(cpt != LNET_LOCK_EX); |
| 662 | |
| 663 | list_for_each(tmp, &the_lnet.ln_nis) { |
| 664 | ni = list_entry(tmp, lnet_ni_t, ni_list); |
| 665 | |
| 666 | if (LNET_NIDNET(ni->ni_nid) == net) { |
| 667 | lnet_ni_addref_locked(ni, cpt); |
| 668 | return ni; |
| 669 | } |
| 670 | } |
| 671 | |
| 672 | return NULL; |
| 673 | } |
| 674 | |
| 675 | lnet_ni_t * |
| 676 | lnet_net2ni(__u32 net) |
| 677 | { |
| 678 | lnet_ni_t *ni; |
| 679 | |
| 680 | lnet_net_lock(0); |
| 681 | ni = lnet_net2ni_locked(net, 0); |
| 682 | lnet_net_unlock(0); |
| 683 | |
| 684 | return ni; |
| 685 | } |
| 686 | EXPORT_SYMBOL(lnet_net2ni); |
| 687 | |
| 688 | static unsigned int |
| 689 | lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number) |
| 690 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 691 | __u64 key = nid; |
| 692 | unsigned int val; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 693 | |
| 694 | LASSERT(number >= 1 && number <= LNET_CPT_NUMBER); |
| 695 | |
| 696 | if (number == 1) |
| 697 | return 0; |
| 698 | |
Peng Tao | 72c0824 | 2014-02-12 19:21:39 +0800 | [diff] [blame] | 699 | val = hash_long(key, LNET_CPT_BITS); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 700 | /* NB: LNET_CP_NUMBER doesn't have to be PO2 */ |
| 701 | if (val < number) |
| 702 | return val; |
| 703 | |
| 704 | return (unsigned int)(key + val + (val >> 1)) % number; |
| 705 | } |
| 706 | |
| 707 | int |
| 708 | lnet_cpt_of_nid_locked(lnet_nid_t nid) |
| 709 | { |
| 710 | struct lnet_ni *ni; |
| 711 | |
| 712 | /* must called with hold of lnet_net_lock */ |
| 713 | if (LNET_CPT_NUMBER == 1) |
| 714 | return 0; /* the only one */ |
| 715 | |
| 716 | /* take lnet_net_lock(any) would be OK */ |
| 717 | if (!list_empty(&the_lnet.ln_nis_cpt)) { |
| 718 | list_for_each_entry(ni, &the_lnet.ln_nis_cpt, ni_cptlist) { |
| 719 | if (LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid)) |
| 720 | continue; |
| 721 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 722 | LASSERT(ni->ni_cpts); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 723 | return ni->ni_cpts[lnet_nid_cpt_hash |
| 724 | (nid, ni->ni_ncpts)]; |
| 725 | } |
| 726 | } |
| 727 | |
| 728 | return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); |
| 729 | } |
| 730 | |
| 731 | int |
| 732 | lnet_cpt_of_nid(lnet_nid_t nid) |
| 733 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 734 | int cpt; |
| 735 | int cpt2; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 736 | |
| 737 | if (LNET_CPT_NUMBER == 1) |
| 738 | return 0; /* the only one */ |
| 739 | |
| 740 | if (list_empty(&the_lnet.ln_nis_cpt)) |
| 741 | return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER); |
| 742 | |
| 743 | cpt = lnet_net_lock_current(); |
| 744 | cpt2 = lnet_cpt_of_nid_locked(nid); |
| 745 | lnet_net_unlock(cpt); |
| 746 | |
| 747 | return cpt2; |
| 748 | } |
| 749 | EXPORT_SYMBOL(lnet_cpt_of_nid); |
| 750 | |
| 751 | int |
| 752 | lnet_islocalnet(__u32 net) |
| 753 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 754 | struct lnet_ni *ni; |
| 755 | int cpt; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 756 | |
| 757 | cpt = lnet_net_lock_current(); |
| 758 | |
| 759 | ni = lnet_net2ni_locked(net, cpt); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 760 | if (ni) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 761 | lnet_ni_decref_locked(ni, cpt); |
| 762 | |
| 763 | lnet_net_unlock(cpt); |
| 764 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 765 | return !!ni; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 766 | } |
| 767 | |
| 768 | lnet_ni_t * |
| 769 | lnet_nid2ni_locked(lnet_nid_t nid, int cpt) |
| 770 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 771 | struct lnet_ni *ni; |
| 772 | struct list_head *tmp; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 773 | |
| 774 | LASSERT(cpt != LNET_LOCK_EX); |
| 775 | |
| 776 | list_for_each(tmp, &the_lnet.ln_nis) { |
| 777 | ni = list_entry(tmp, lnet_ni_t, ni_list); |
| 778 | |
| 779 | if (ni->ni_nid == nid) { |
| 780 | lnet_ni_addref_locked(ni, cpt); |
| 781 | return ni; |
| 782 | } |
| 783 | } |
| 784 | |
| 785 | return NULL; |
| 786 | } |
| 787 | |
| 788 | int |
| 789 | lnet_islocalnid(lnet_nid_t nid) |
| 790 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 791 | struct lnet_ni *ni; |
| 792 | int cpt; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 793 | |
| 794 | cpt = lnet_net_lock_current(); |
| 795 | ni = lnet_nid2ni_locked(nid, cpt); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 796 | if (ni) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 797 | lnet_ni_decref_locked(ni, cpt); |
| 798 | lnet_net_unlock(cpt); |
| 799 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 800 | return !!ni; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 801 | } |
| 802 | |
| 803 | int |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 804 | lnet_count_acceptor_nis(void) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 805 | { |
| 806 | /* Return the # of NIs that need the acceptor. */ |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 807 | int count = 0; |
| 808 | struct list_head *tmp; |
| 809 | struct lnet_ni *ni; |
| 810 | int cpt; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 811 | |
| 812 | cpt = lnet_net_lock_current(); |
| 813 | list_for_each(tmp, &the_lnet.ln_nis) { |
| 814 | ni = list_entry(tmp, lnet_ni_t, ni_list); |
| 815 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 816 | if (ni->ni_lnd->lnd_accept) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 817 | count++; |
| 818 | } |
| 819 | |
| 820 | lnet_net_unlock(cpt); |
| 821 | |
| 822 | return count; |
| 823 | } |
| 824 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 825 | static lnet_ping_info_t * |
| 826 | lnet_ping_info_create(int num_ni) |
| 827 | { |
| 828 | lnet_ping_info_t *ping_info; |
| 829 | unsigned int infosz; |
| 830 | |
| 831 | infosz = offsetof(lnet_ping_info_t, pi_ni[num_ni]); |
| 832 | LIBCFS_ALLOC(ping_info, infosz); |
| 833 | if (!ping_info) { |
| 834 | CERROR("Can't allocate ping info[%d]\n", num_ni); |
| 835 | return NULL; |
| 836 | } |
| 837 | |
| 838 | ping_info->pi_nnis = num_ni; |
| 839 | ping_info->pi_pid = the_lnet.ln_pid; |
| 840 | ping_info->pi_magic = LNET_PROTO_PING_MAGIC; |
| 841 | ping_info->pi_features = LNET_PING_FEAT_NI_STATUS; |
| 842 | |
| 843 | return ping_info; |
| 844 | } |
| 845 | |
| 846 | static inline int |
| 847 | lnet_get_ni_count(void) |
| 848 | { |
| 849 | struct lnet_ni *ni; |
| 850 | int count = 0; |
| 851 | |
| 852 | lnet_net_lock(0); |
| 853 | |
| 854 | list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) |
| 855 | count++; |
| 856 | |
| 857 | lnet_net_unlock(0); |
| 858 | |
| 859 | return count; |
| 860 | } |
| 861 | |
| 862 | static inline void |
| 863 | lnet_ping_info_free(lnet_ping_info_t *pinfo) |
| 864 | { |
| 865 | LIBCFS_FREE(pinfo, |
| 866 | offsetof(lnet_ping_info_t, |
| 867 | pi_ni[pinfo->pi_nnis])); |
| 868 | } |
| 869 | |
| 870 | static void |
| 871 | lnet_ping_info_destroy(void) |
| 872 | { |
| 873 | struct lnet_ni *ni; |
| 874 | |
| 875 | lnet_net_lock(LNET_LOCK_EX); |
| 876 | |
| 877 | list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { |
| 878 | lnet_ni_lock(ni); |
| 879 | ni->ni_status = NULL; |
| 880 | lnet_ni_unlock(ni); |
| 881 | } |
| 882 | |
| 883 | lnet_ping_info_free(the_lnet.ln_ping_info); |
| 884 | the_lnet.ln_ping_info = NULL; |
| 885 | |
| 886 | lnet_net_unlock(LNET_LOCK_EX); |
| 887 | } |
| 888 | |
| 889 | static void |
| 890 | lnet_ping_event_handler(lnet_event_t *event) |
| 891 | { |
| 892 | lnet_ping_info_t *pinfo = event->md.user_ptr; |
| 893 | |
| 894 | if (event->unlinked) |
| 895 | pinfo->pi_features = LNET_PING_FEAT_INVAL; |
| 896 | } |
| 897 | |
| 898 | static int |
| 899 | lnet_ping_info_setup(lnet_ping_info_t **ppinfo, lnet_handle_md_t *md_handle, |
| 900 | int ni_count, bool set_eq) |
| 901 | { |
| 902 | lnet_process_id_t id = {LNET_NID_ANY, LNET_PID_ANY}; |
| 903 | lnet_handle_me_t me_handle; |
Frank Zago | 24af3e16 | 2016-02-22 17:29:11 -0500 | [diff] [blame] | 904 | lnet_md_t md = { NULL }; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 905 | int rc, rc2; |
| 906 | |
| 907 | if (set_eq) { |
| 908 | rc = LNetEQAlloc(0, lnet_ping_event_handler, |
| 909 | &the_lnet.ln_ping_target_eq); |
| 910 | if (rc) { |
| 911 | CERROR("Can't allocate ping EQ: %d\n", rc); |
| 912 | return rc; |
| 913 | } |
| 914 | } |
| 915 | |
| 916 | *ppinfo = lnet_ping_info_create(ni_count); |
| 917 | if (!*ppinfo) { |
| 918 | rc = -ENOMEM; |
| 919 | goto failed_0; |
| 920 | } |
| 921 | |
| 922 | rc = LNetMEAttach(LNET_RESERVED_PORTAL, id, |
| 923 | LNET_PROTO_PING_MATCHBITS, 0, |
| 924 | LNET_UNLINK, LNET_INS_AFTER, |
| 925 | &me_handle); |
| 926 | if (rc) { |
| 927 | CERROR("Can't create ping ME: %d\n", rc); |
| 928 | goto failed_1; |
| 929 | } |
| 930 | |
| 931 | /* initialize md content */ |
| 932 | md.start = *ppinfo; |
| 933 | md.length = offsetof(lnet_ping_info_t, |
| 934 | pi_ni[(*ppinfo)->pi_nnis]); |
| 935 | md.threshold = LNET_MD_THRESH_INF; |
| 936 | md.max_size = 0; |
| 937 | md.options = LNET_MD_OP_GET | LNET_MD_TRUNCATE | |
| 938 | LNET_MD_MANAGE_REMOTE; |
| 939 | md.user_ptr = NULL; |
| 940 | md.eq_handle = the_lnet.ln_ping_target_eq; |
| 941 | md.user_ptr = *ppinfo; |
| 942 | |
| 943 | rc = LNetMDAttach(me_handle, md, LNET_RETAIN, md_handle); |
| 944 | if (rc) { |
| 945 | CERROR("Can't attach ping MD: %d\n", rc); |
| 946 | goto failed_2; |
| 947 | } |
| 948 | |
| 949 | return 0; |
| 950 | |
| 951 | failed_2: |
| 952 | rc2 = LNetMEUnlink(me_handle); |
| 953 | LASSERT(!rc2); |
| 954 | failed_1: |
| 955 | lnet_ping_info_free(*ppinfo); |
| 956 | *ppinfo = NULL; |
| 957 | failed_0: |
| 958 | if (set_eq) |
| 959 | LNetEQFree(the_lnet.ln_ping_target_eq); |
| 960 | return rc; |
| 961 | } |
| 962 | |
| 963 | static void |
| 964 | lnet_ping_md_unlink(lnet_ping_info_t *pinfo, lnet_handle_md_t *md_handle) |
| 965 | { |
| 966 | sigset_t blocked = cfs_block_allsigs(); |
| 967 | |
| 968 | LNetMDUnlink(*md_handle); |
| 969 | LNetInvalidateHandle(md_handle); |
| 970 | |
| 971 | /* NB md could be busy; this just starts the unlink */ |
| 972 | while (pinfo->pi_features != LNET_PING_FEAT_INVAL) { |
| 973 | CDEBUG(D_NET, "Still waiting for ping MD to unlink\n"); |
| 974 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 975 | schedule_timeout(cfs_time_seconds(1)); |
| 976 | } |
| 977 | |
| 978 | cfs_restore_sigs(blocked); |
| 979 | } |
| 980 | |
| 981 | static void |
| 982 | lnet_ping_info_install_locked(lnet_ping_info_t *ping_info) |
| 983 | { |
| 984 | lnet_ni_status_t *ns; |
| 985 | lnet_ni_t *ni; |
| 986 | int i = 0; |
| 987 | |
| 988 | list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { |
| 989 | LASSERT(i < ping_info->pi_nnis); |
| 990 | |
| 991 | ns = &ping_info->pi_ni[i]; |
| 992 | |
| 993 | ns->ns_nid = ni->ni_nid; |
| 994 | |
| 995 | lnet_ni_lock(ni); |
| 996 | ns->ns_status = (ni->ni_status) ? |
| 997 | ni->ni_status->ns_status : LNET_NI_STATUS_UP; |
| 998 | ni->ni_status = ns; |
| 999 | lnet_ni_unlock(ni); |
| 1000 | |
| 1001 | i++; |
| 1002 | } |
| 1003 | } |
| 1004 | |
| 1005 | static void |
| 1006 | lnet_ping_target_update(lnet_ping_info_t *pinfo, lnet_handle_md_t md_handle) |
| 1007 | { |
| 1008 | lnet_ping_info_t *old_pinfo = NULL; |
| 1009 | lnet_handle_md_t old_md; |
| 1010 | |
| 1011 | /* switch the NIs to point to the new ping info created */ |
| 1012 | lnet_net_lock(LNET_LOCK_EX); |
| 1013 | |
| 1014 | if (!the_lnet.ln_routing) |
| 1015 | pinfo->pi_features |= LNET_PING_FEAT_RTE_DISABLED; |
| 1016 | lnet_ping_info_install_locked(pinfo); |
| 1017 | |
| 1018 | if (the_lnet.ln_ping_info) { |
| 1019 | old_pinfo = the_lnet.ln_ping_info; |
| 1020 | old_md = the_lnet.ln_ping_target_md; |
| 1021 | } |
| 1022 | the_lnet.ln_ping_target_md = md_handle; |
| 1023 | the_lnet.ln_ping_info = pinfo; |
| 1024 | |
| 1025 | lnet_net_unlock(LNET_LOCK_EX); |
| 1026 | |
| 1027 | if (old_pinfo) { |
| 1028 | /* unlink the old ping info */ |
| 1029 | lnet_ping_md_unlink(old_pinfo, &old_md); |
| 1030 | lnet_ping_info_free(old_pinfo); |
| 1031 | } |
| 1032 | } |
| 1033 | |
| 1034 | static void |
| 1035 | lnet_ping_target_fini(void) |
| 1036 | { |
| 1037 | int rc; |
| 1038 | |
| 1039 | lnet_ping_md_unlink(the_lnet.ln_ping_info, |
| 1040 | &the_lnet.ln_ping_target_md); |
| 1041 | |
| 1042 | rc = LNetEQFree(the_lnet.ln_ping_target_eq); |
| 1043 | LASSERT(!rc); |
| 1044 | |
| 1045 | lnet_ping_info_destroy(); |
| 1046 | } |
| 1047 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1048 | static int |
| 1049 | lnet_ni_tq_credits(lnet_ni_t *ni) |
| 1050 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1051 | int credits; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1052 | |
| 1053 | LASSERT(ni->ni_ncpts >= 1); |
| 1054 | |
| 1055 | if (ni->ni_ncpts == 1) |
| 1056 | return ni->ni_maxtxcredits; |
| 1057 | |
| 1058 | credits = ni->ni_maxtxcredits / ni->ni_ncpts; |
| 1059 | credits = max(credits, 8 * ni->ni_peertxcredits); |
| 1060 | credits = min(credits, ni->ni_maxtxcredits); |
| 1061 | |
| 1062 | return credits; |
| 1063 | } |
| 1064 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 1065 | static void |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1066 | lnet_ni_unlink_locked(lnet_ni_t *ni) |
| 1067 | { |
| 1068 | if (!list_empty(&ni->ni_cptlist)) { |
| 1069 | list_del_init(&ni->ni_cptlist); |
| 1070 | lnet_ni_decref_locked(ni, 0); |
| 1071 | } |
| 1072 | |
| 1073 | /* move it to zombie list and nobody can find it anymore */ |
| 1074 | LASSERT(!list_empty(&ni->ni_list)); |
| 1075 | list_move(&ni->ni_list, &the_lnet.ln_nis_zombie); |
| 1076 | lnet_ni_decref_locked(ni, 0); /* drop ln_nis' ref */ |
| 1077 | } |
| 1078 | |
| 1079 | static void |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1080 | lnet_clear_zombies_nis_locked(void) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1081 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1082 | int i; |
| 1083 | int islo; |
| 1084 | lnet_ni_t *ni; |
Bhaktipriya Shridhar | c997866 | 2016-03-12 01:35:29 +0530 | [diff] [blame] | 1085 | lnet_ni_t *temp; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1086 | |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 1087 | /* |
| 1088 | * Now wait for the NI's I just nuked to show up on ln_zombie_nis |
| 1089 | * and shut them down in guaranteed thread context |
| 1090 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1091 | i = 2; |
Bhaktipriya Shridhar | c997866 | 2016-03-12 01:35:29 +0530 | [diff] [blame] | 1092 | list_for_each_entry_safe(ni, temp, &the_lnet.ln_nis_zombie, ni_list) { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1093 | int *ref; |
| 1094 | int j; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1095 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1096 | list_del_init(&ni->ni_list); |
| 1097 | cfs_percpt_for_each(ref, j, ni->ni_refs) { |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 1098 | if (!*ref) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1099 | continue; |
| 1100 | /* still busy, add it back to zombie list */ |
| 1101 | list_add(&ni->ni_list, &the_lnet.ln_nis_zombie); |
| 1102 | break; |
| 1103 | } |
| 1104 | |
Liang Zhen | 526cdb4 | 2014-04-27 13:06:56 -0400 | [diff] [blame] | 1105 | if (!list_empty(&ni->ni_list)) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1106 | lnet_net_unlock(LNET_LOCK_EX); |
| 1107 | ++i; |
| 1108 | if ((i & (-i)) == i) { |
Liang Zhen | 526cdb4 | 2014-04-27 13:06:56 -0400 | [diff] [blame] | 1109 | CDEBUG(D_WARNING, "Waiting for zombie LNI %s\n", |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1110 | libcfs_nid2str(ni->ni_nid)); |
| 1111 | } |
Peng Tao | d3caf4d | 2014-03-18 21:05:56 +0800 | [diff] [blame] | 1112 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 1113 | schedule_timeout(cfs_time_seconds(1)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1114 | lnet_net_lock(LNET_LOCK_EX); |
| 1115 | continue; |
| 1116 | } |
| 1117 | |
| 1118 | ni->ni_lnd->lnd_refcount--; |
| 1119 | lnet_net_unlock(LNET_LOCK_EX); |
| 1120 | |
| 1121 | islo = ni->ni_lnd->lnd_type == LOLND; |
| 1122 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 1123 | LASSERT(!in_interrupt()); |
James Simmons | 0eee677 | 2016-02-12 12:06:02 -0500 | [diff] [blame] | 1124 | ni->ni_lnd->lnd_shutdown(ni); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1125 | |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 1126 | /* |
| 1127 | * can't deref lnd anymore now; it might have unregistered |
| 1128 | * itself... |
| 1129 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1130 | if (!islo) |
| 1131 | CDEBUG(D_LNI, "Removed LNI %s\n", |
| 1132 | libcfs_nid2str(ni->ni_nid)); |
| 1133 | |
| 1134 | lnet_ni_free(ni); |
Liang Zhen | 526cdb4 | 2014-04-27 13:06:56 -0400 | [diff] [blame] | 1135 | i = 2; |
| 1136 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1137 | lnet_net_lock(LNET_LOCK_EX); |
| 1138 | } |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1139 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1140 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1141 | static void |
| 1142 | lnet_shutdown_lndnis(void) |
| 1143 | { |
| 1144 | lnet_ni_t *ni; |
Bhaktipriya Shridhar | c997866 | 2016-03-12 01:35:29 +0530 | [diff] [blame] | 1145 | lnet_ni_t *temp; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1146 | int i; |
| 1147 | |
| 1148 | /* NB called holding the global mutex */ |
| 1149 | |
| 1150 | /* All quiet on the API front */ |
| 1151 | LASSERT(!the_lnet.ln_shutdown); |
| 1152 | LASSERT(!the_lnet.ln_refcount); |
| 1153 | LASSERT(list_empty(&the_lnet.ln_nis_zombie)); |
| 1154 | |
| 1155 | lnet_net_lock(LNET_LOCK_EX); |
| 1156 | the_lnet.ln_shutdown = 1; /* flag shutdown */ |
| 1157 | |
| 1158 | /* Unlink NIs from the global table */ |
Bhaktipriya Shridhar | c997866 | 2016-03-12 01:35:29 +0530 | [diff] [blame] | 1159 | list_for_each_entry_safe(ni, temp, &the_lnet.ln_nis, ni_list) { |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1160 | lnet_ni_unlink_locked(ni); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1161 | } |
| 1162 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1163 | /* Drop the cached loopback NI. */ |
| 1164 | if (the_lnet.ln_loni) { |
| 1165 | lnet_ni_decref_locked(the_lnet.ln_loni, 0); |
| 1166 | the_lnet.ln_loni = NULL; |
| 1167 | } |
| 1168 | |
| 1169 | lnet_net_unlock(LNET_LOCK_EX); |
| 1170 | |
| 1171 | /* |
| 1172 | * Clear lazy portals and drop delayed messages which hold refs |
| 1173 | * on their lnet_msg_t::msg_rxpeer |
| 1174 | */ |
| 1175 | for (i = 0; i < the_lnet.ln_nportals; i++) |
| 1176 | LNetClearLazyPortal(i); |
| 1177 | |
| 1178 | /* |
| 1179 | * Clear the peer table and wait for all peers to go (they hold refs on |
| 1180 | * their NIs) |
| 1181 | */ |
| 1182 | lnet_peer_tables_cleanup(NULL); |
| 1183 | |
| 1184 | lnet_net_lock(LNET_LOCK_EX); |
| 1185 | |
| 1186 | lnet_clear_zombies_nis_locked(); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1187 | the_lnet.ln_shutdown = 0; |
| 1188 | lnet_net_unlock(LNET_LOCK_EX); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1189 | } |
| 1190 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1191 | /* shutdown down the NI and release refcount */ |
| 1192 | static void |
| 1193 | lnet_shutdown_lndni(struct lnet_ni *ni) |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1194 | { |
Amir Shehata | 1a9be84 | 2016-02-22 17:29:19 -0500 | [diff] [blame] | 1195 | int i; |
| 1196 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1197 | lnet_net_lock(LNET_LOCK_EX); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1198 | lnet_ni_unlink_locked(ni); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1199 | lnet_net_unlock(LNET_LOCK_EX); |
| 1200 | |
Amir Shehata | 1a9be84 | 2016-02-22 17:29:19 -0500 | [diff] [blame] | 1201 | /* clear messages for this NI on the lazy portal */ |
| 1202 | for (i = 0; i < the_lnet.ln_nportals; i++) |
| 1203 | lnet_clear_lazy_portal(ni, i, "Shutting down NI"); |
| 1204 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1205 | /* Do peer table cleanup for this ni */ |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1206 | lnet_peer_tables_cleanup(ni); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1207 | |
| 1208 | lnet_net_lock(LNET_LOCK_EX); |
| 1209 | lnet_clear_zombies_nis_locked(); |
| 1210 | lnet_net_unlock(LNET_LOCK_EX); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1211 | } |
| 1212 | |
Anil Belur | 51bd881 | 2014-06-28 21:26:16 +0530 | [diff] [blame] | 1213 | static int |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1214 | lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1215 | { |
Amir Shehata | 1b30ccd | 2016-05-06 21:30:31 -0400 | [diff] [blame] | 1216 | struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL; |
Amir Shehata | 5af8a05 | 2016-02-22 17:29:14 -0500 | [diff] [blame] | 1217 | int rc = -EINVAL; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1218 | int lnd_type; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1219 | lnd_t *lnd; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1220 | struct lnet_tx_queue *tq; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1221 | int i; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1222 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1223 | lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1224 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1225 | LASSERT(libcfs_isknown_lnd(lnd_type)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1226 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1227 | if (lnd_type == CIBLND || lnd_type == OPENIBLND || |
| 1228 | lnd_type == IIBLND || lnd_type == VIBLND) { |
| 1229 | CERROR("LND %s obsoleted\n", libcfs_lnd2str(lnd_type)); |
| 1230 | goto failed0; |
| 1231 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1232 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1233 | /* Make sure this new NI is unique. */ |
| 1234 | lnet_net_lock(LNET_LOCK_EX); |
Amir Shehata | 5af8a05 | 2016-02-22 17:29:14 -0500 | [diff] [blame] | 1235 | rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis); |
| 1236 | lnet_net_unlock(LNET_LOCK_EX); |
| 1237 | if (!rc) { |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1238 | if (lnd_type == LOLND) { |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1239 | lnet_ni_free(ni); |
| 1240 | return 0; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1241 | } |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1242 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1243 | CERROR("Net %s is not unique\n", |
| 1244 | libcfs_net2str(LNET_NIDNET(ni->ni_nid))); |
Amir Shehata | 5af8a05 | 2016-02-22 17:29:14 -0500 | [diff] [blame] | 1245 | rc = -EEXIST; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1246 | goto failed0; |
| 1247 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1248 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1249 | mutex_lock(&the_lnet.ln_lnd_mutex); |
| 1250 | lnd = lnet_find_lnd_by_type(lnd_type); |
| 1251 | |
| 1252 | if (!lnd) { |
| 1253 | mutex_unlock(&the_lnet.ln_lnd_mutex); |
| 1254 | rc = request_module("%s", libcfs_lnd2modname(lnd_type)); |
| 1255 | mutex_lock(&the_lnet.ln_lnd_mutex); |
| 1256 | |
| 1257 | lnd = lnet_find_lnd_by_type(lnd_type); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 1258 | if (!lnd) { |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 1259 | mutex_unlock(&the_lnet.ln_lnd_mutex); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1260 | CERROR("Can't load LND %s, module %s, rc=%d\n", |
| 1261 | libcfs_lnd2str(lnd_type), |
| 1262 | libcfs_lnd2modname(lnd_type), rc); |
Amir Shehata | 5af8a05 | 2016-02-22 17:29:14 -0500 | [diff] [blame] | 1263 | rc = -EINVAL; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1264 | goto failed0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1265 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1266 | } |
| 1267 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1268 | lnet_net_lock(LNET_LOCK_EX); |
| 1269 | lnd->lnd_refcount++; |
| 1270 | lnet_net_unlock(LNET_LOCK_EX); |
| 1271 | |
| 1272 | ni->ni_lnd = lnd; |
| 1273 | |
Amir Shehata | 1b30ccd | 2016-05-06 21:30:31 -0400 | [diff] [blame] | 1274 | if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf)) |
| 1275 | lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; |
| 1276 | |
| 1277 | if (lnd_tunables) { |
| 1278 | LIBCFS_ALLOC(ni->ni_lnd_tunables, |
| 1279 | sizeof(*ni->ni_lnd_tunables)); |
| 1280 | if (!ni->ni_lnd_tunables) { |
| 1281 | mutex_unlock(&the_lnet.ln_lnd_mutex); |
| 1282 | rc = -ENOMEM; |
| 1283 | goto failed0; |
| 1284 | } |
| 1285 | memcpy(ni->ni_lnd_tunables, lnd_tunables, |
| 1286 | sizeof(*ni->ni_lnd_tunables)); |
| 1287 | } |
| 1288 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1289 | rc = lnd->lnd_startup(ni); |
| 1290 | |
| 1291 | mutex_unlock(&the_lnet.ln_lnd_mutex); |
| 1292 | |
| 1293 | if (rc) { |
| 1294 | LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n", |
| 1295 | rc, libcfs_lnd2str(lnd->lnd_type)); |
| 1296 | lnet_net_lock(LNET_LOCK_EX); |
| 1297 | lnd->lnd_refcount--; |
| 1298 | lnet_net_unlock(LNET_LOCK_EX); |
| 1299 | goto failed0; |
| 1300 | } |
| 1301 | |
| 1302 | /* |
| 1303 | * If given some LND tunable parameters, parse those now to |
| 1304 | * override the values in the NI structure. |
| 1305 | */ |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1306 | if (conf && conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) { |
| 1307 | ni->ni_peerrtrcredits = |
| 1308 | conf->cfg_config_u.cfg_net.net_peer_rtr_credits; |
| 1309 | } |
| 1310 | if (conf && conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) { |
| 1311 | ni->ni_peertimeout = |
| 1312 | conf->cfg_config_u.cfg_net.net_peer_timeout; |
| 1313 | } |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1314 | /* |
| 1315 | * TODO |
| 1316 | * Note: For now, don't allow the user to change |
| 1317 | * peertxcredits as this number is used in the |
| 1318 | * IB LND to control queue depth. |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1319 | * |
| 1320 | * if (conf && conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1) |
| 1321 | * ni->ni_peertxcredits = |
| 1322 | * conf->cfg_config_u.cfg_net.net_peer_tx_credits; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1323 | */ |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1324 | if (conf && conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) { |
| 1325 | ni->ni_maxtxcredits = |
| 1326 | conf->cfg_config_u.cfg_net.net_max_tx_credits; |
| 1327 | } |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1328 | |
| 1329 | LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query); |
| 1330 | |
| 1331 | lnet_net_lock(LNET_LOCK_EX); |
| 1332 | /* refcount for ln_nis */ |
| 1333 | lnet_ni_addref_locked(ni, 0); |
| 1334 | list_add_tail(&ni->ni_list, &the_lnet.ln_nis); |
| 1335 | if (ni->ni_cpts) { |
| 1336 | lnet_ni_addref_locked(ni, 0); |
| 1337 | list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt); |
| 1338 | } |
| 1339 | |
| 1340 | lnet_net_unlock(LNET_LOCK_EX); |
| 1341 | |
| 1342 | if (lnd->lnd_type == LOLND) { |
| 1343 | lnet_ni_addref(ni); |
| 1344 | LASSERT(!the_lnet.ln_loni); |
| 1345 | the_lnet.ln_loni = ni; |
| 1346 | return 0; |
| 1347 | } |
| 1348 | |
| 1349 | if (!ni->ni_peertxcredits || !ni->ni_maxtxcredits) { |
| 1350 | LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n", |
| 1351 | libcfs_lnd2str(lnd->lnd_type), |
| 1352 | !ni->ni_peertxcredits ? |
| 1353 | "" : "per-peer "); |
| 1354 | /* |
| 1355 | * shutdown the NI since if we get here then it must've already |
| 1356 | * been started |
| 1357 | */ |
Anchal Jain | 1181643 | 2016-02-28 19:25:23 +0530 | [diff] [blame] | 1358 | lnet_shutdown_lndni(ni); |
| 1359 | return -EINVAL; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1360 | } |
| 1361 | |
| 1362 | cfs_percpt_for_each(tq, i, ni->ni_tx_queues) { |
| 1363 | tq->tq_credits_min = |
| 1364 | tq->tq_credits_max = |
| 1365 | tq->tq_credits = lnet_ni_tq_credits(ni); |
| 1366 | } |
| 1367 | |
| 1368 | CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n", |
| 1369 | libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits, |
| 1370 | lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER, |
| 1371 | ni->ni_peerrtrcredits, ni->ni_peertimeout); |
| 1372 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1373 | return 0; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1374 | failed0: |
| 1375 | lnet_ni_free(ni); |
Amir Shehata | 5af8a05 | 2016-02-22 17:29:14 -0500 | [diff] [blame] | 1376 | return rc; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1377 | } |
| 1378 | |
| 1379 | static int |
| 1380 | lnet_startup_lndnis(struct list_head *nilist) |
| 1381 | { |
| 1382 | struct lnet_ni *ni; |
| 1383 | int rc; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1384 | int ni_count = 0; |
| 1385 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1386 | while (!list_empty(nilist)) { |
| 1387 | ni = list_entry(nilist->next, lnet_ni_t, ni_list); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1388 | list_del(&ni->ni_list); |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1389 | rc = lnet_startup_lndni(ni, NULL); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1390 | |
| 1391 | if (rc < 0) |
| 1392 | goto failed; |
| 1393 | |
| 1394 | ni_count++; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1395 | } |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1396 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1397 | return ni_count; |
| 1398 | failed: |
| 1399 | lnet_shutdown_lndnis(); |
| 1400 | |
| 1401 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1402 | } |
| 1403 | |
| 1404 | /** |
| 1405 | * Initialize LNet library. |
| 1406 | * |
John L. Hammond | 94bfb3c | 2016-02-22 17:29:17 -0500 | [diff] [blame] | 1407 | * Automatically called at module loading time. Caller has to call |
Andreas Dilger | e0f9411 | 2016-02-26 11:36:05 -0500 | [diff] [blame] | 1408 | * lnet_lib_exit() after a call to lnet_lib_init(), if and only if the |
John L. Hammond | 94bfb3c | 2016-02-22 17:29:17 -0500 | [diff] [blame] | 1409 | * latter returned 0. It must be called exactly once. |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1410 | * |
Andreas Dilger | 29b2ded | 2016-02-26 11:36:06 -0500 | [diff] [blame] | 1411 | * \retval 0 on success |
| 1412 | * \retval -ve on failures. |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1413 | */ |
Andreas Dilger | e0f9411 | 2016-02-26 11:36:05 -0500 | [diff] [blame] | 1414 | int lnet_lib_init(void) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1415 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1416 | int rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1417 | |
| 1418 | lnet_assert_wire_constants(); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1419 | |
| 1420 | memset(&the_lnet, 0, sizeof(the_lnet)); |
| 1421 | |
| 1422 | /* refer to global cfs_cpt_table for now */ |
| 1423 | the_lnet.ln_cpt_table = cfs_cpt_table; |
| 1424 | the_lnet.ln_cpt_number = cfs_cpt_number(cfs_cpt_table); |
| 1425 | |
| 1426 | LASSERT(the_lnet.ln_cpt_number > 0); |
| 1427 | if (the_lnet.ln_cpt_number > LNET_CPT_MAX) { |
| 1428 | /* we are under risk of consuming all lh_cookie */ |
Gulsah Kose | 8ad5360 | 2014-09-20 21:39:46 +0300 | [diff] [blame] | 1429 | CERROR("Can't have %d CPTs for LNet (max allowed is %d), please change setting of CPT-table and retry\n", |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1430 | the_lnet.ln_cpt_number, LNET_CPT_MAX); |
James Simmons | 58cb2ad | 2016-03-02 17:01:47 -0500 | [diff] [blame] | 1431 | return -E2BIG; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1432 | } |
| 1433 | |
| 1434 | while ((1 << the_lnet.ln_cpt_bits) < the_lnet.ln_cpt_number) |
| 1435 | the_lnet.ln_cpt_bits++; |
| 1436 | |
| 1437 | rc = lnet_create_locks(); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 1438 | if (rc) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1439 | CERROR("Can't create LNet global locks: %d\n", rc); |
James Simmons | 58cb2ad | 2016-03-02 17:01:47 -0500 | [diff] [blame] | 1440 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1441 | } |
| 1442 | |
| 1443 | the_lnet.ln_refcount = 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1444 | LNetInvalidateHandle(&the_lnet.ln_rc_eqh); |
| 1445 | INIT_LIST_HEAD(&the_lnet.ln_lnds); |
| 1446 | INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie); |
| 1447 | INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow); |
| 1448 | |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 1449 | /* |
| 1450 | * The hash table size is the number of bits it takes to express the set |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1451 | * ln_num_routes, minus 1 (better to under estimate than over so we |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 1452 | * don't waste memory). |
| 1453 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1454 | if (rnet_htable_size <= 0) |
| 1455 | rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT; |
| 1456 | else if (rnet_htable_size > LNET_REMOTE_NETS_HASH_MAX) |
| 1457 | rnet_htable_size = LNET_REMOTE_NETS_HASH_MAX; |
| 1458 | the_lnet.ln_remote_nets_hbits = max_t(int, 1, |
| 1459 | order_base_2(rnet_htable_size) - 1); |
| 1460 | |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 1461 | /* |
| 1462 | * All LNDs apart from the LOLND are in separate modules. They |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1463 | * register themselves when their module loads, and unregister |
James Simmons | 4420cfd | 2016-02-12 12:06:00 -0500 | [diff] [blame] | 1464 | * themselves when their module is unloaded. |
| 1465 | */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1466 | lnet_register_lnd(&the_lolnd); |
| 1467 | return 0; |
| 1468 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1469 | |
| 1470 | /** |
| 1471 | * Finalize LNet library. |
| 1472 | * |
Andreas Dilger | e0f9411 | 2016-02-26 11:36:05 -0500 | [diff] [blame] | 1473 | * \pre lnet_lib_init() called with success. |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1474 | * \pre All LNet users called LNetNIFini() for matching LNetNIInit() calls. |
| 1475 | */ |
Andreas Dilger | e0f9411 | 2016-02-26 11:36:05 -0500 | [diff] [blame] | 1476 | void lnet_lib_exit(void) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1477 | { |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 1478 | LASSERT(!the_lnet.ln_refcount); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1479 | |
| 1480 | while (!list_empty(&the_lnet.ln_lnds)) |
| 1481 | lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next, |
James Simmons | c314c31 | 2016-02-12 12:06:01 -0500 | [diff] [blame] | 1482 | lnd_t, lnd_list)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1483 | lnet_destroy_locks(); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1484 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1485 | |
| 1486 | /** |
| 1487 | * Set LNet PID and start LNet interfaces, routing, and forwarding. |
| 1488 | * |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1489 | * Users must call this function at least once before any other functions. |
| 1490 | * For each successful call there must be a corresponding call to |
| 1491 | * LNetNIFini(). For subsequent calls to LNetNIInit(), \a requested_pid is |
| 1492 | * ignored. |
| 1493 | * |
| 1494 | * The PID used by LNet may be different from the one requested. |
| 1495 | * See LNetGetId(). |
| 1496 | * |
| 1497 | * \param requested_pid PID requested by the caller. |
| 1498 | * |
| 1499 | * \return >= 0 on success, and < 0 error code on failures. |
| 1500 | */ |
| 1501 | int |
| 1502 | LNetNIInit(lnet_pid_t requested_pid) |
| 1503 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1504 | int im_a_router = 0; |
Amir Shehata | 5af8a05 | 2016-02-22 17:29:14 -0500 | [diff] [blame] | 1505 | int rc; |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1506 | int ni_count; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1507 | lnet_ping_info_t *pinfo; |
| 1508 | lnet_handle_md_t md_handle; |
| 1509 | struct list_head net_head; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1510 | |
| 1511 | INIT_LIST_HEAD(&net_head); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1512 | |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 1513 | mutex_lock(&the_lnet.ln_api_mutex); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1514 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1515 | CDEBUG(D_OTHER, "refs %d\n", the_lnet.ln_refcount); |
| 1516 | |
| 1517 | if (the_lnet.ln_refcount > 0) { |
| 1518 | rc = the_lnet.ln_refcount++; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1519 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1520 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1521 | } |
| 1522 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1523 | rc = lnet_prepare(requested_pid); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1524 | if (rc) { |
| 1525 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1526 | return rc; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1527 | } |
| 1528 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1529 | /* Add in the loopback network */ |
| 1530 | if (!lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head)) { |
| 1531 | rc = -ENOMEM; |
| 1532 | goto err_empty_list; |
| 1533 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1534 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1535 | /* |
| 1536 | * If LNet is being initialized via DLC it is possible |
| 1537 | * that the user requests not to load module parameters (ones which |
| 1538 | * are supported by DLC) on initialization. Therefore, make sure not |
| 1539 | * to load networks, routes and forwarding from module parameters |
| 1540 | * in this case. On cleanup in case of failure only clean up |
| 1541 | * routes if it has been loaded |
| 1542 | */ |
| 1543 | if (!the_lnet.ln_nis_from_mod_params) { |
| 1544 | rc = lnet_parse_networks(&net_head, lnet_get_networks()); |
| 1545 | if (rc < 0) |
| 1546 | goto err_empty_list; |
| 1547 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1548 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1549 | ni_count = lnet_startup_lndnis(&net_head); |
| 1550 | if (ni_count < 0) { |
| 1551 | rc = ni_count; |
| 1552 | goto err_empty_list; |
| 1553 | } |
| 1554 | |
| 1555 | if (!the_lnet.ln_nis_from_mod_params) { |
| 1556 | rc = lnet_parse_routes(lnet_get_routes(), &im_a_router); |
| 1557 | if (rc) |
| 1558 | goto err_shutdown_lndnis; |
| 1559 | |
| 1560 | rc = lnet_check_routes(); |
| 1561 | if (rc) |
| 1562 | goto err_destory_routes; |
| 1563 | |
| 1564 | rc = lnet_rtrpools_alloc(im_a_router); |
| 1565 | if (rc) |
| 1566 | goto err_destory_routes; |
| 1567 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1568 | |
| 1569 | rc = lnet_acceptor_start(); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 1570 | if (rc) |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1571 | goto err_destory_routes; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1572 | |
| 1573 | the_lnet.ln_refcount = 1; |
| 1574 | /* Now I may use my own API functions... */ |
| 1575 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1576 | rc = lnet_ping_info_setup(&pinfo, &md_handle, ni_count, true); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 1577 | if (rc) |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1578 | goto err_acceptor_stop; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1579 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1580 | lnet_ping_target_update(pinfo, md_handle); |
| 1581 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1582 | rc = lnet_router_checker_start(); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 1583 | if (rc) |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1584 | goto err_stop_ping; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1585 | |
Liang Zhen | 0fbbced | 2016-03-07 18:10:16 -0500 | [diff] [blame] | 1586 | lnet_fault_init(); |
Oleg Drokin | b03f395 | 2015-09-14 18:41:17 -0400 | [diff] [blame] | 1587 | lnet_router_debugfs_init(); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1588 | |
| 1589 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1590 | |
| 1591 | return 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1592 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1593 | err_stop_ping: |
Amir Shehata | 5af8a05 | 2016-02-22 17:29:14 -0500 | [diff] [blame] | 1594 | lnet_ping_target_fini(); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1595 | err_acceptor_stop: |
| 1596 | the_lnet.ln_refcount = 0; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1597 | lnet_acceptor_stop(); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1598 | err_destory_routes: |
| 1599 | if (!the_lnet.ln_nis_from_mod_params) |
| 1600 | lnet_destroy_routes(); |
| 1601 | err_shutdown_lndnis: |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1602 | lnet_shutdown_lndnis(); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1603 | err_empty_list: |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1604 | lnet_unprepare(); |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 1605 | LASSERT(rc < 0); |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 1606 | mutex_unlock(&the_lnet.ln_api_mutex); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1607 | while (!list_empty(&net_head)) { |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1608 | struct lnet_ni *ni; |
| 1609 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1610 | ni = list_entry(net_head.next, struct lnet_ni, ni_list); |
| 1611 | list_del_init(&ni->ni_list); |
| 1612 | lnet_ni_free(ni); |
| 1613 | } |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1614 | return rc; |
| 1615 | } |
| 1616 | EXPORT_SYMBOL(LNetNIInit); |
| 1617 | |
| 1618 | /** |
| 1619 | * Stop LNet interfaces, routing, and forwarding. |
| 1620 | * |
| 1621 | * Users must call this function once for each successful call to LNetNIInit(). |
| 1622 | * Once the LNetNIFini() operation has been started, the results of pending |
| 1623 | * API operations are undefined. |
| 1624 | * |
| 1625 | * \return always 0 for current implementation. |
| 1626 | */ |
| 1627 | int |
Emil Goode | 7d46a21 | 2013-07-28 00:38:55 +0200 | [diff] [blame] | 1628 | LNetNIFini(void) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1629 | { |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 1630 | mutex_lock(&the_lnet.ln_api_mutex); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1631 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 1632 | LASSERT(the_lnet.ln_refcount > 0); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1633 | |
| 1634 | if (the_lnet.ln_refcount != 1) { |
| 1635 | the_lnet.ln_refcount--; |
| 1636 | } else { |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 1637 | LASSERT(!the_lnet.ln_niinit_self); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1638 | |
Liang Zhen | 0fbbced | 2016-03-07 18:10:16 -0500 | [diff] [blame] | 1639 | lnet_fault_fini(); |
Oleg Drokin | b03f395 | 2015-09-14 18:41:17 -0400 | [diff] [blame] | 1640 | lnet_router_debugfs_fini(); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1641 | lnet_router_checker_stop(); |
| 1642 | lnet_ping_target_fini(); |
| 1643 | |
| 1644 | /* Teardown fns that use my own API functions BEFORE here */ |
| 1645 | the_lnet.ln_refcount = 0; |
| 1646 | |
| 1647 | lnet_acceptor_stop(); |
| 1648 | lnet_destroy_routes(); |
| 1649 | lnet_shutdown_lndnis(); |
| 1650 | lnet_unprepare(); |
| 1651 | } |
| 1652 | |
Mike Shuey | bdd84a6 | 2015-05-19 10:14:39 -0400 | [diff] [blame] | 1653 | mutex_unlock(&the_lnet.ln_api_mutex); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1654 | return 0; |
| 1655 | } |
| 1656 | EXPORT_SYMBOL(LNetNIFini); |
| 1657 | |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1658 | /** |
| 1659 | * Grabs the ni data from the ni structure and fills the out |
| 1660 | * parameters |
| 1661 | * |
| 1662 | * \param[in] ni network interface structure |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1663 | * \param[out] config NI configuration |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1664 | */ |
| 1665 | static void |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1666 | lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config) |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1667 | { |
Amir Shehata | 1b30ccd | 2016-05-06 21:30:31 -0400 | [diff] [blame] | 1668 | struct lnet_ioctl_config_lnd_tunables *lnd_cfg = NULL; |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1669 | struct lnet_ioctl_net_config *net_config; |
Amir Shehata | 1b30ccd | 2016-05-06 21:30:31 -0400 | [diff] [blame] | 1670 | size_t min_size, tunable_size = 0; |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1671 | int i; |
| 1672 | |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1673 | if (!ni || !config) |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1674 | return; |
| 1675 | |
Oleg Drokin | 9797fb0 | 2016-06-18 23:53:12 -0400 | [diff] [blame] | 1676 | net_config = (struct lnet_ioctl_net_config *)config->cfg_bulk; |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1677 | if (!net_config) |
| 1678 | return; |
| 1679 | |
| 1680 | BUILD_BUG_ON(ARRAY_SIZE(ni->ni_interfaces) != |
| 1681 | ARRAY_SIZE(net_config->ni_interfaces)); |
| 1682 | |
| 1683 | for (i = 0; i < ARRAY_SIZE(ni->ni_interfaces); i++) { |
| 1684 | if (!ni->ni_interfaces[i]) |
| 1685 | break; |
| 1686 | |
| 1687 | strncpy(net_config->ni_interfaces[i], |
| 1688 | ni->ni_interfaces[i], |
| 1689 | sizeof(net_config->ni_interfaces[i])); |
| 1690 | } |
| 1691 | |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1692 | config->cfg_nid = ni->ni_nid; |
| 1693 | config->cfg_config_u.cfg_net.net_peer_timeout = ni->ni_peertimeout; |
| 1694 | config->cfg_config_u.cfg_net.net_max_tx_credits = ni->ni_maxtxcredits; |
| 1695 | config->cfg_config_u.cfg_net.net_peer_tx_credits = ni->ni_peertxcredits; |
| 1696 | config->cfg_config_u.cfg_net.net_peer_rtr_credits = ni->ni_peerrtrcredits; |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1697 | |
| 1698 | net_config->ni_status = ni->ni_status->ns_status; |
| 1699 | |
| 1700 | if (ni->ni_cpts) { |
| 1701 | int num_cpts = min(ni->ni_ncpts, LNET_MAX_SHOW_NUM_CPT); |
| 1702 | |
| 1703 | for (i = 0; i < num_cpts; i++) |
| 1704 | net_config->ni_cpts[i] = ni->ni_cpts[i]; |
| 1705 | |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1706 | config->cfg_ncpts = num_cpts; |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1707 | } |
Amir Shehata | 1b30ccd | 2016-05-06 21:30:31 -0400 | [diff] [blame] | 1708 | |
| 1709 | /* |
| 1710 | * See if user land tools sent in a newer and larger version |
| 1711 | * of struct lnet_tunables than what the kernel uses. |
| 1712 | */ |
| 1713 | min_size = sizeof(*config) + sizeof(*net_config); |
| 1714 | |
| 1715 | if (config->cfg_hdr.ioc_len > min_size) |
| 1716 | tunable_size = config->cfg_hdr.ioc_len - min_size; |
| 1717 | |
| 1718 | /* Don't copy to much data to user space */ |
| 1719 | min_size = min(tunable_size, sizeof(*ni->ni_lnd_tunables)); |
| 1720 | lnd_cfg = (struct lnet_ioctl_config_lnd_tunables *)net_config->cfg_bulk; |
| 1721 | |
| 1722 | if (ni->ni_lnd_tunables && lnd_cfg && min_size) { |
| 1723 | memcpy(lnd_cfg, ni->ni_lnd_tunables, min_size); |
| 1724 | config->cfg_config_u.cfg_net.net_interface_count = 1; |
| 1725 | |
| 1726 | /* Tell user land that kernel side has less data */ |
| 1727 | if (tunable_size > sizeof(*ni->ni_lnd_tunables)) { |
| 1728 | min_size = tunable_size - sizeof(ni->ni_lnd_tunables); |
| 1729 | config->cfg_hdr.ioc_len -= min_size; |
| 1730 | } |
| 1731 | } |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1732 | } |
| 1733 | |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1734 | static int |
| 1735 | lnet_get_net_config(struct lnet_ioctl_config_data *config) |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1736 | { |
| 1737 | struct lnet_ni *ni; |
| 1738 | struct list_head *tmp; |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1739 | int idx = config->cfg_count; |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1740 | int cpt, i = 0; |
| 1741 | int rc = -ENOENT; |
| 1742 | |
| 1743 | cpt = lnet_net_lock_current(); |
| 1744 | |
| 1745 | list_for_each(tmp, &the_lnet.ln_nis) { |
| 1746 | if (i++ != idx) |
| 1747 | continue; |
| 1748 | |
| 1749 | ni = list_entry(tmp, lnet_ni_t, ni_list); |
| 1750 | lnet_ni_lock(ni); |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1751 | lnet_fill_ni_info(ni, config); |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1752 | lnet_ni_unlock(ni); |
| 1753 | rc = 0; |
| 1754 | break; |
| 1755 | } |
| 1756 | |
| 1757 | lnet_net_unlock(cpt); |
| 1758 | return rc; |
| 1759 | } |
| 1760 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1761 | int |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1762 | lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf) |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1763 | { |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1764 | char *nets = conf->cfg_config_u.cfg_net.net_intf; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1765 | lnet_ping_info_t *pinfo; |
| 1766 | lnet_handle_md_t md_handle; |
| 1767 | struct lnet_ni *ni; |
| 1768 | struct list_head net_head; |
Amir Shehata | 445c6a1 | 2016-02-22 17:29:13 -0500 | [diff] [blame] | 1769 | lnet_remotenet_t *rnet; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1770 | int rc; |
| 1771 | |
| 1772 | INIT_LIST_HEAD(&net_head); |
| 1773 | |
| 1774 | /* Create a ni structure for the network string */ |
| 1775 | rc = lnet_parse_networks(&net_head, nets); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1776 | if (rc <= 0) |
| 1777 | return !rc ? -EINVAL : rc; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1778 | |
| 1779 | mutex_lock(&the_lnet.ln_api_mutex); |
| 1780 | |
| 1781 | if (rc > 1) { |
| 1782 | rc = -EINVAL; /* only add one interface per call */ |
| 1783 | goto failed0; |
| 1784 | } |
| 1785 | |
Amir Shehata | 445c6a1 | 2016-02-22 17:29:13 -0500 | [diff] [blame] | 1786 | ni = list_entry(net_head.next, struct lnet_ni, ni_list); |
| 1787 | |
| 1788 | lnet_net_lock(LNET_LOCK_EX); |
| 1789 | rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid)); |
| 1790 | lnet_net_unlock(LNET_LOCK_EX); |
| 1791 | /* |
| 1792 | * make sure that the net added doesn't invalidate the current |
| 1793 | * configuration LNet is keeping |
| 1794 | */ |
| 1795 | if (rnet) { |
| 1796 | CERROR("Adding net %s will invalidate routing configuration\n", |
| 1797 | nets); |
| 1798 | rc = -EUSERS; |
| 1799 | goto failed0; |
| 1800 | } |
| 1801 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1802 | rc = lnet_ping_info_setup(&pinfo, &md_handle, 1 + lnet_get_ni_count(), |
| 1803 | false); |
| 1804 | if (rc) |
| 1805 | goto failed0; |
| 1806 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1807 | list_del_init(&ni->ni_list); |
| 1808 | |
Amir Shehata | d76d938 | 2016-05-06 21:30:22 -0400 | [diff] [blame] | 1809 | rc = lnet_startup_lndni(ni, conf); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1810 | if (rc) |
| 1811 | goto failed1; |
| 1812 | |
Amir Shehata | 7ee3842 | 2016-02-22 17:29:12 -0500 | [diff] [blame] | 1813 | if (ni->ni_lnd->lnd_accept) { |
| 1814 | rc = lnet_acceptor_start(); |
| 1815 | if (rc < 0) { |
| 1816 | /* shutdown the ni that we just started */ |
| 1817 | CERROR("Failed to start up acceptor thread\n"); |
| 1818 | lnet_shutdown_lndni(ni); |
| 1819 | goto failed1; |
| 1820 | } |
| 1821 | } |
| 1822 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1823 | lnet_ping_target_update(pinfo, md_handle); |
| 1824 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1825 | |
| 1826 | return 0; |
| 1827 | |
| 1828 | failed1: |
| 1829 | lnet_ping_md_unlink(pinfo, &md_handle); |
| 1830 | lnet_ping_info_free(pinfo); |
| 1831 | failed0: |
| 1832 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1833 | while (!list_empty(&net_head)) { |
| 1834 | ni = list_entry(net_head.next, struct lnet_ni, ni_list); |
| 1835 | list_del_init(&ni->ni_list); |
| 1836 | lnet_ni_free(ni); |
| 1837 | } |
| 1838 | return rc; |
| 1839 | } |
| 1840 | |
| 1841 | int |
| 1842 | lnet_dyn_del_ni(__u32 net) |
| 1843 | { |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1844 | lnet_ni_t *ni; |
| 1845 | lnet_ping_info_t *pinfo; |
| 1846 | lnet_handle_md_t md_handle; |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1847 | int rc; |
| 1848 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1849 | /* don't allow userspace to shutdown the LOLND */ |
| 1850 | if (LNET_NETTYP(net) == LOLND) |
| 1851 | return -EINVAL; |
| 1852 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1853 | mutex_lock(&the_lnet.ln_api_mutex); |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1854 | /* create and link a new ping info, before removing the old one */ |
| 1855 | rc = lnet_ping_info_setup(&pinfo, &md_handle, |
| 1856 | lnet_get_ni_count() - 1, false); |
| 1857 | if (rc) |
| 1858 | goto out; |
| 1859 | |
| 1860 | ni = lnet_net2ni(net); |
| 1861 | if (!ni) { |
| 1862 | rc = -EINVAL; |
| 1863 | goto failed; |
| 1864 | } |
| 1865 | |
| 1866 | /* decrement the reference counter taken by lnet_net2ni() */ |
| 1867 | lnet_ni_decref_locked(ni, 0); |
| 1868 | |
| 1869 | lnet_shutdown_lndni(ni); |
Amir Shehata | 7ee3842 | 2016-02-22 17:29:12 -0500 | [diff] [blame] | 1870 | |
| 1871 | if (!lnet_count_acceptor_nis()) |
| 1872 | lnet_acceptor_stop(); |
| 1873 | |
Amir Shehata | 9c26b89 | 2016-02-22 17:29:08 -0500 | [diff] [blame] | 1874 | lnet_ping_target_update(pinfo, md_handle); |
| 1875 | goto out; |
| 1876 | failed: |
| 1877 | lnet_ping_md_unlink(pinfo, &md_handle); |
| 1878 | lnet_ping_info_free(pinfo); |
| 1879 | out: |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1880 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1881 | |
| 1882 | return rc; |
| 1883 | } |
| 1884 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1885 | /** |
Oleg Drokin | 71c36dd | 2016-01-03 12:05:33 -0500 | [diff] [blame] | 1886 | * LNet ioctl handler. |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1887 | * |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1888 | */ |
| 1889 | int |
| 1890 | LNetCtl(unsigned int cmd, void *arg) |
| 1891 | { |
| 1892 | struct libcfs_ioctl_data *data = arg; |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1893 | struct lnet_ioctl_config_data *config; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 1894 | lnet_process_id_t id = {0}; |
| 1895 | lnet_ni_t *ni; |
| 1896 | int rc; |
Arnd Bergmann | 5e50efe | 2015-09-27 16:45:10 -0400 | [diff] [blame] | 1897 | unsigned long secs_passed; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1898 | |
Liang Zhen | da4e589 | 2016-03-22 19:03:58 -0400 | [diff] [blame] | 1899 | BUILD_BUG_ON(LIBCFS_IOC_DATA_MAX < |
| 1900 | sizeof(struct lnet_ioctl_net_config) + |
| 1901 | sizeof(struct lnet_ioctl_config_data)); |
| 1902 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1903 | switch (cmd) { |
| 1904 | case IOC_LIBCFS_GET_NI: |
| 1905 | rc = LNetGetId(data->ioc_count, &id); |
| 1906 | data->ioc_nid = id.nid; |
| 1907 | return rc; |
| 1908 | |
| 1909 | case IOC_LIBCFS_FAIL_NID: |
| 1910 | return lnet_fail_nid(data->ioc_nid, data->ioc_count); |
| 1911 | |
| 1912 | case IOC_LIBCFS_ADD_ROUTE: |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1913 | config = arg; |
| 1914 | |
| 1915 | if (config->cfg_hdr.ioc_len < sizeof(*config)) |
| 1916 | return -EINVAL; |
| 1917 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1918 | mutex_lock(&the_lnet.ln_api_mutex); |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1919 | rc = lnet_add_route(config->cfg_net, |
| 1920 | config->cfg_config_u.cfg_route.rtr_hop, |
| 1921 | config->cfg_nid, |
| 1922 | config->cfg_config_u.cfg_route.rtr_priority); |
Amir Shehata | 1ccde72 | 2016-02-22 17:29:15 -0500 | [diff] [blame] | 1923 | if (!rc) { |
| 1924 | rc = lnet_check_routes(); |
| 1925 | if (rc) |
| 1926 | lnet_del_route(config->cfg_net, |
| 1927 | config->cfg_nid); |
| 1928 | } |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1929 | mutex_unlock(&the_lnet.ln_api_mutex); |
Amir Shehata | 1ccde72 | 2016-02-22 17:29:15 -0500 | [diff] [blame] | 1930 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1931 | |
| 1932 | case IOC_LIBCFS_DEL_ROUTE: |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1933 | config = arg; |
| 1934 | |
| 1935 | if (config->cfg_hdr.ioc_len < sizeof(*config)) |
| 1936 | return -EINVAL; |
| 1937 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1938 | mutex_lock(&the_lnet.ln_api_mutex); |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1939 | rc = lnet_del_route(config->cfg_net, config->cfg_nid); |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 1940 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1941 | return rc; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 1942 | |
| 1943 | case IOC_LIBCFS_GET_ROUTE: |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1944 | config = arg; |
| 1945 | |
| 1946 | if (config->cfg_hdr.ioc_len < sizeof(*config)) |
| 1947 | return -EINVAL; |
| 1948 | |
| 1949 | return lnet_get_route(config->cfg_count, |
| 1950 | &config->cfg_net, |
| 1951 | &config->cfg_config_u.cfg_route.rtr_hop, |
| 1952 | &config->cfg_nid, |
| 1953 | &config->cfg_config_u.cfg_route.rtr_flags, |
| 1954 | &config->cfg_config_u.cfg_route.rtr_priority); |
| 1955 | |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1956 | case IOC_LIBCFS_GET_NET: { |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1957 | size_t total = sizeof(*config) + |
| 1958 | sizeof(struct lnet_ioctl_net_config); |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1959 | config = arg; |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1960 | |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1961 | if (config->cfg_hdr.ioc_len < total) |
| 1962 | return -EINVAL; |
| 1963 | |
Amir Shehata | 27c7f7c | 2016-05-06 21:30:23 -0400 | [diff] [blame] | 1964 | return lnet_get_net_config(config); |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1965 | } |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1966 | |
| 1967 | case IOC_LIBCFS_GET_LNET_STATS: { |
| 1968 | struct lnet_ioctl_lnet_stats *lnet_stats = arg; |
| 1969 | |
| 1970 | if (lnet_stats->st_hdr.ioc_len < sizeof(*lnet_stats)) |
| 1971 | return -EINVAL; |
| 1972 | |
| 1973 | lnet_counters_get(&lnet_stats->st_cntrs); |
| 1974 | return 0; |
| 1975 | } |
| 1976 | |
| 1977 | case IOC_LIBCFS_CONFIG_RTR: |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1978 | config = arg; |
| 1979 | |
| 1980 | if (config->cfg_hdr.ioc_len < sizeof(*config)) |
| 1981 | return -EINVAL; |
| 1982 | |
| 1983 | mutex_lock(&the_lnet.ln_api_mutex); |
| 1984 | if (config->cfg_config_u.cfg_buffers.buf_enable) { |
| 1985 | rc = lnet_rtrpools_enable(); |
| 1986 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 1987 | return rc; |
| 1988 | } |
| 1989 | lnet_rtrpools_disable(); |
| 1990 | mutex_unlock(&the_lnet.ln_api_mutex); |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1991 | return 0; |
| 1992 | |
| 1993 | case IOC_LIBCFS_ADD_BUF: |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1994 | config = arg; |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1995 | |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1996 | if (config->cfg_hdr.ioc_len < sizeof(*config)) |
| 1997 | return -EINVAL; |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 1998 | |
Amir Shehata | edeb5d8 | 2016-02-22 17:29:05 -0500 | [diff] [blame] | 1999 | mutex_lock(&the_lnet.ln_api_mutex); |
| 2000 | rc = lnet_rtrpools_adjust(config->cfg_config_u.cfg_buffers.buf_tiny, |
| 2001 | config->cfg_config_u.cfg_buffers.buf_small, |
| 2002 | config->cfg_config_u.cfg_buffers.buf_large); |
| 2003 | mutex_unlock(&the_lnet.ln_api_mutex); |
| 2004 | return rc; |
| 2005 | |
| 2006 | case IOC_LIBCFS_GET_BUF: { |
| 2007 | struct lnet_ioctl_pool_cfg *pool_cfg; |
| 2008 | size_t total = sizeof(*config) + sizeof(*pool_cfg); |
| 2009 | |
| 2010 | config = arg; |
| 2011 | |
| 2012 | if (config->cfg_hdr.ioc_len < total) |
| 2013 | return -EINVAL; |
| 2014 | |
| 2015 | pool_cfg = (struct lnet_ioctl_pool_cfg *)config->cfg_bulk; |
| 2016 | return lnet_get_rtr_pool_cfg(config->cfg_count, pool_cfg); |
| 2017 | } |
| 2018 | |
| 2019 | case IOC_LIBCFS_GET_PEER_INFO: { |
| 2020 | struct lnet_ioctl_peer *peer_info = arg; |
| 2021 | |
| 2022 | if (peer_info->pr_hdr.ioc_len < sizeof(*peer_info)) |
| 2023 | return -EINVAL; |
| 2024 | |
| 2025 | return lnet_get_peer_info(peer_info->pr_count, |
| 2026 | &peer_info->pr_nid, |
| 2027 | peer_info->pr_lnd_u.pr_peer_credits.cr_aliveness, |
| 2028 | &peer_info->pr_lnd_u.pr_peer_credits.cr_ncpt, |
| 2029 | &peer_info->pr_lnd_u.pr_peer_credits.cr_refcount, |
| 2030 | &peer_info->pr_lnd_u.pr_peer_credits.cr_ni_peer_tx_credits, |
| 2031 | &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_credits, |
| 2032 | &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_rtr_credits, |
| 2033 | &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_min_rtr_credits, |
| 2034 | &peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_qnob); |
| 2035 | } |
Amir Shehata | 2e9a51b | 2016-02-22 17:29:03 -0500 | [diff] [blame] | 2036 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2037 | case IOC_LIBCFS_NOTIFY_ROUTER: |
Arnd Bergmann | 5e50efe | 2015-09-27 16:45:10 -0400 | [diff] [blame] | 2038 | secs_passed = (ktime_get_real_seconds() - data->ioc_u64[0]); |
Jian Yu | 27d81ac | 2016-03-02 17:01:53 -0500 | [diff] [blame] | 2039 | secs_passed *= msecs_to_jiffies(MSEC_PER_SEC); |
| 2040 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2041 | return lnet_notify(NULL, data->ioc_nid, data->ioc_flags, |
Jian Yu | 27d81ac | 2016-03-02 17:01:53 -0500 | [diff] [blame] | 2042 | jiffies - secs_passed); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2043 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2044 | case IOC_LIBCFS_LNET_DIST: |
| 2045 | rc = LNetDist(data->ioc_nid, &data->ioc_nid, &data->ioc_u32[1]); |
| 2046 | if (rc < 0 && rc != -EHOSTUNREACH) |
| 2047 | return rc; |
| 2048 | |
| 2049 | data->ioc_u32[0] = rc; |
| 2050 | return 0; |
| 2051 | |
| 2052 | case IOC_LIBCFS_TESTPROTOCOMPAT: |
| 2053 | lnet_net_lock(LNET_LOCK_EX); |
| 2054 | the_lnet.ln_testprotocompat = data->ioc_flags; |
| 2055 | lnet_net_unlock(LNET_LOCK_EX); |
| 2056 | return 0; |
| 2057 | |
Liang Zhen | 0fbbced | 2016-03-07 18:10:16 -0500 | [diff] [blame] | 2058 | case IOC_LIBCFS_LNET_FAULT: |
| 2059 | return lnet_fault_ctl(data->ioc_flags, data); |
| 2060 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2061 | case IOC_LIBCFS_PING: |
| 2062 | id.nid = data->ioc_nid; |
| 2063 | id.pid = data->ioc_u32[0]; |
| 2064 | rc = lnet_ping(id, data->ioc_u32[1], /* timeout */ |
Oleg Drokin | 4eb53df | 2016-01-03 12:05:41 -0500 | [diff] [blame] | 2065 | data->ioc_pbuf1, |
James Simmons | 51078e2 | 2016-02-12 12:06:04 -0500 | [diff] [blame] | 2066 | data->ioc_plen1 / sizeof(lnet_process_id_t)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2067 | if (rc < 0) |
| 2068 | return rc; |
| 2069 | data->ioc_count = rc; |
| 2070 | return 0; |
| 2071 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2072 | default: |
| 2073 | ni = lnet_net2ni(data->ioc_net); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 2074 | if (!ni) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2075 | return -EINVAL; |
| 2076 | |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 2077 | if (!ni->ni_lnd->lnd_ctl) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2078 | rc = -EINVAL; |
| 2079 | else |
| 2080 | rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg); |
| 2081 | |
| 2082 | lnet_ni_decref(ni); |
| 2083 | return rc; |
| 2084 | } |
| 2085 | /* not reached */ |
| 2086 | } |
| 2087 | EXPORT_SYMBOL(LNetCtl); |
| 2088 | |
Oleg Drokin | 71c36dd | 2016-01-03 12:05:33 -0500 | [diff] [blame] | 2089 | void LNetDebugPeer(lnet_process_id_t id) |
| 2090 | { |
| 2091 | lnet_debug_peer(id.nid); |
| 2092 | } |
| 2093 | EXPORT_SYMBOL(LNetDebugPeer); |
| 2094 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2095 | /** |
| 2096 | * Retrieve the lnet_process_id_t ID of LNet interface at \a index. Note that |
| 2097 | * all interfaces share a same PID, as requested by LNetNIInit(). |
| 2098 | * |
| 2099 | * \param index Index of the interface to look up. |
| 2100 | * \param id On successful return, this location will hold the |
| 2101 | * lnet_process_id_t ID of the interface. |
| 2102 | * |
| 2103 | * \retval 0 If an interface exists at \a index. |
| 2104 | * \retval -ENOENT If no interface has been found. |
| 2105 | */ |
| 2106 | int |
| 2107 | LNetGetId(unsigned int index, lnet_process_id_t *id) |
| 2108 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 2109 | struct lnet_ni *ni; |
| 2110 | struct list_head *tmp; |
| 2111 | int cpt; |
| 2112 | int rc = -ENOENT; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2113 | |
James Simmons | 31b36ec | 2016-03-07 18:10:22 -0500 | [diff] [blame] | 2114 | LASSERT(the_lnet.ln_refcount > 0); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2115 | |
| 2116 | cpt = lnet_net_lock_current(); |
| 2117 | |
| 2118 | list_for_each(tmp, &the_lnet.ln_nis) { |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2119 | if (index--) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2120 | continue; |
| 2121 | |
| 2122 | ni = list_entry(tmp, lnet_ni_t, ni_list); |
| 2123 | |
| 2124 | id->nid = ni->ni_nid; |
| 2125 | id->pid = the_lnet.ln_pid; |
| 2126 | rc = 0; |
| 2127 | break; |
| 2128 | } |
| 2129 | |
| 2130 | lnet_net_unlock(cpt); |
| 2131 | return rc; |
| 2132 | } |
| 2133 | EXPORT_SYMBOL(LNetGetId); |
| 2134 | |
| 2135 | /** |
| 2136 | * Print a string representation of handle \a h into buffer \a str of |
| 2137 | * \a len bytes. |
| 2138 | */ |
| 2139 | void |
| 2140 | LNetSnprintHandle(char *str, int len, lnet_handle_any_t h) |
| 2141 | { |
Greg Kroah-Hartman | 55f5a82 | 2014-07-12 20:26:07 -0700 | [diff] [blame] | 2142 | snprintf(str, len, "%#llx", h.cookie); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2143 | } |
| 2144 | EXPORT_SYMBOL(LNetSnprintHandle); |
| 2145 | |
Oleg Drokin | fccfde7 | 2016-01-03 12:05:32 -0500 | [diff] [blame] | 2146 | static int lnet_ping(lnet_process_id_t id, int timeout_ms, |
Oleg Drokin | 4eb53df | 2016-01-03 12:05:41 -0500 | [diff] [blame] | 2147 | lnet_process_id_t __user *ids, int n_ids) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2148 | { |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 2149 | lnet_handle_eq_t eqh; |
| 2150 | lnet_handle_md_t mdh; |
| 2151 | lnet_event_t event; |
| 2152 | lnet_md_t md = { NULL }; |
| 2153 | int which; |
| 2154 | int unlinked = 0; |
| 2155 | int replied = 0; |
| 2156 | const int a_long_time = 60000; /* mS */ |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 2157 | int infosz; |
Mike Shuey | 7e7ab09 | 2015-05-19 10:14:32 -0400 | [diff] [blame] | 2158 | lnet_ping_info_t *info; |
| 2159 | lnet_process_id_t tmpid; |
| 2160 | int i; |
| 2161 | int nob; |
| 2162 | int rc; |
| 2163 | int rc2; |
| 2164 | sigset_t blocked; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2165 | |
Amir Shehata | 6c9e5a5 | 2016-02-15 10:25:54 -0500 | [diff] [blame] | 2166 | infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]); |
| 2167 | |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2168 | if (n_ids <= 0 || |
| 2169 | id.nid == LNET_NID_ANY || |
| 2170 | timeout_ms > 500000 || /* arbitrary limit! */ |
| 2171 | n_ids > 20) /* arbitrary limit! */ |
| 2172 | return -EINVAL; |
| 2173 | |
| 2174 | if (id.pid == LNET_PID_ANY) |
John L. Hammond | fe7cb65 | 2016-02-22 17:29:07 -0500 | [diff] [blame] | 2175 | id.pid = LNET_PID_LUSTRE; |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2176 | |
| 2177 | LIBCFS_ALLOC(info, infosz); |
James Simmons | 06ace26 | 2016-02-12 12:06:08 -0500 | [diff] [blame] | 2178 | if (!info) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2179 | return -ENOMEM; |
| 2180 | |
| 2181 | /* NB 2 events max (including any unlink event) */ |
| 2182 | rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &eqh); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2183 | if (rc) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2184 | CERROR("Can't allocate EQ: %d\n", rc); |
| 2185 | goto out_0; |
| 2186 | } |
| 2187 | |
| 2188 | /* initialize md content */ |
| 2189 | md.start = info; |
| 2190 | md.length = infosz; |
| 2191 | md.threshold = 2; /*GET/REPLY*/ |
| 2192 | md.max_size = 0; |
| 2193 | md.options = LNET_MD_TRUNCATE; |
| 2194 | md.user_ptr = NULL; |
| 2195 | md.eq_handle = eqh; |
| 2196 | |
| 2197 | rc = LNetMDBind(md, LNET_UNLINK, &mdh); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2198 | if (rc) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2199 | CERROR("Can't bind MD: %d\n", rc); |
| 2200 | goto out_1; |
| 2201 | } |
| 2202 | |
| 2203 | rc = LNetGet(LNET_NID_ANY, mdh, id, |
| 2204 | LNET_RESERVED_PORTAL, |
| 2205 | LNET_PROTO_PING_MATCHBITS, 0); |
| 2206 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2207 | if (rc) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2208 | /* Don't CERROR; this could be deliberate! */ |
| 2209 | |
| 2210 | rc2 = LNetMDUnlink(mdh); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2211 | LASSERT(!rc2); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2212 | |
| 2213 | /* NB must wait for the UNLINK event below... */ |
| 2214 | unlinked = 1; |
| 2215 | timeout_ms = a_long_time; |
| 2216 | } |
| 2217 | |
| 2218 | do { |
| 2219 | /* MUST block for unlink to complete */ |
| 2220 | if (unlinked) |
| 2221 | blocked = cfs_block_allsigs(); |
| 2222 | |
| 2223 | rc2 = LNetEQPoll(&eqh, 1, timeout_ms, &event, &which); |
| 2224 | |
| 2225 | if (unlinked) |
| 2226 | cfs_restore_sigs(blocked); |
| 2227 | |
| 2228 | CDEBUG(D_NET, "poll %d(%d %d)%s\n", rc2, |
| 2229 | (rc2 <= 0) ? -1 : event.type, |
| 2230 | (rc2 <= 0) ? -1 : event.status, |
| 2231 | (rc2 > 0 && event.unlinked) ? " unlinked" : ""); |
| 2232 | |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 2233 | LASSERT(rc2 != -EOVERFLOW); /* can't miss anything */ |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2234 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2235 | if (rc2 <= 0 || event.status) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2236 | /* timeout or error */ |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2237 | if (!replied && !rc) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2238 | rc = (rc2 < 0) ? rc2 : |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2239 | !rc2 ? -ETIMEDOUT : |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2240 | event.status; |
| 2241 | |
| 2242 | if (!unlinked) { |
| 2243 | /* Ensure completion in finite time... */ |
| 2244 | LNetMDUnlink(mdh); |
| 2245 | /* No assertion (racing with network) */ |
| 2246 | unlinked = 1; |
| 2247 | timeout_ms = a_long_time; |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2248 | } else if (!rc2) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2249 | /* timed out waiting for unlink */ |
| 2250 | CWARN("ping %s: late network completion\n", |
| 2251 | libcfs_id2str(id)); |
| 2252 | } |
| 2253 | } else if (event.type == LNET_EVENT_REPLY) { |
| 2254 | replied = 1; |
| 2255 | rc = event.mlength; |
| 2256 | } |
| 2257 | |
| 2258 | } while (rc2 <= 0 || !event.unlinked); |
| 2259 | |
| 2260 | if (!replied) { |
| 2261 | if (rc >= 0) |
| 2262 | CWARN("%s: Unexpected rc >= 0 but no reply!\n", |
| 2263 | libcfs_id2str(id)); |
| 2264 | rc = -EIO; |
| 2265 | goto out_1; |
| 2266 | } |
| 2267 | |
| 2268 | nob = rc; |
Tapasweni Pathak | 3b7566d | 2014-09-29 16:02:46 +0530 | [diff] [blame] | 2269 | LASSERT(nob >= 0 && nob <= infosz); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2270 | |
| 2271 | rc = -EPROTO; /* if I can't parse... */ |
| 2272 | |
| 2273 | if (nob < 8) { |
| 2274 | /* can't check magic/version */ |
| 2275 | CERROR("%s: ping info too short %d\n", |
| 2276 | libcfs_id2str(id), nob); |
| 2277 | goto out_1; |
| 2278 | } |
| 2279 | |
| 2280 | if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) { |
| 2281 | lnet_swap_pinginfo(info); |
| 2282 | } else if (info->pi_magic != LNET_PROTO_PING_MAGIC) { |
| 2283 | CERROR("%s: Unexpected magic %08x\n", |
| 2284 | libcfs_id2str(id), info->pi_magic); |
| 2285 | goto out_1; |
| 2286 | } |
| 2287 | |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2288 | if (!(info->pi_features & LNET_PING_FEAT_NI_STATUS)) { |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2289 | CERROR("%s: ping w/o NI status: 0x%x\n", |
| 2290 | libcfs_id2str(id), info->pi_features); |
| 2291 | goto out_1; |
| 2292 | } |
| 2293 | |
| 2294 | if (nob < offsetof(lnet_ping_info_t, pi_ni[0])) { |
| 2295 | CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id), |
| 2296 | nob, (int)offsetof(lnet_ping_info_t, pi_ni[0])); |
| 2297 | goto out_1; |
| 2298 | } |
| 2299 | |
| 2300 | if (info->pi_nnis < n_ids) |
| 2301 | n_ids = info->pi_nnis; |
| 2302 | |
| 2303 | if (nob < offsetof(lnet_ping_info_t, pi_ni[n_ids])) { |
| 2304 | CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id), |
| 2305 | nob, (int)offsetof(lnet_ping_info_t, pi_ni[n_ids])); |
| 2306 | goto out_1; |
| 2307 | } |
| 2308 | |
| 2309 | rc = -EFAULT; /* If I SEGV... */ |
| 2310 | |
Dan Carpenter | 751a624 | 2014-05-03 23:23:29 +0300 | [diff] [blame] | 2311 | memset(&tmpid, 0, sizeof(tmpid)); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2312 | for (i = 0; i < n_ids; i++) { |
| 2313 | tmpid.pid = info->pi_pid; |
| 2314 | tmpid.nid = info->pi_ni[i].ns_nid; |
| 2315 | if (copy_to_user(&ids[i], &tmpid, sizeof(tmpid))) |
| 2316 | goto out_1; |
| 2317 | } |
| 2318 | rc = info->pi_nnis; |
| 2319 | |
| 2320 | out_1: |
| 2321 | rc2 = LNetEQFree(eqh); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2322 | if (rc2) |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2323 | CERROR("rc2 %d\n", rc2); |
James Simmons | 5fd8833 | 2016-02-12 12:06:09 -0500 | [diff] [blame] | 2324 | LASSERT(!rc2); |
Peng Tao | d7e09d0 | 2013-05-02 16:46:55 +0800 | [diff] [blame] | 2325 | |
| 2326 | out_0: |
| 2327 | LIBCFS_FREE(info, infosz); |
| 2328 | return rc; |
| 2329 | } |