aboutsummaryrefslogtreecommitdiffstats
path: root/net/smc
diff options
context:
space:
mode:
authorUrsula Braun <ubraun@linux.ibm.com>2018-06-28 13:05:04 -0400
committerDavid S. Miller <davem@davemloft.net>2018-06-30 07:42:25 -0400
commitbe6a3f38ff2a2bfd2e591fdc566940a0d4d9428c (patch)
tree6611f8a48f23ad8468022b5d35d4802f713974a0 /net/smc
parentb0402f0113675ad78bc10c839f93a25348dd1f73 (diff)
net/smc: determine port attributes independent from pnet table
For SMC it is important to know the current port state of RoCE devices. Monitoring port states has been triggered, when a RoCE device was added to the pnet table. To support future alternatives to the pnet table the monitoring of ports is made independent of the existence of a pnet table. It starts once the smc_ib_device is established. Due to this change smc_ib_remember_port_attr() is now a local function and shuffling its location and the location of its used functions makes any forward references obsolete. And the duplicate SMC_MAX_PORTS definition is removed. Signed-off-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/smc')
-rw-r--r--net/smc/smc.h2
-rw-r--r--net/smc/smc_ib.c130
-rw-r--r--net/smc/smc_ib.h1
-rw-r--r--net/smc/smc_pnet.c7
4 files changed, 72 insertions, 68 deletions
diff --git a/net/smc/smc.h b/net/smc/smc.h
index 51ae1f10d81a..7c86f716a92e 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -21,8 +21,6 @@
21#define SMCPROTO_SMC 0 /* SMC protocol, IPv4 */ 21#define SMCPROTO_SMC 0 /* SMC protocol, IPv4 */
22#define SMCPROTO_SMC6 1 /* SMC protocol, IPv6 */ 22#define SMCPROTO_SMC6 1 /* SMC protocol, IPv6 */
23 23
24#define SMC_MAX_PORTS 2 /* Max # of ports */
25
26extern struct proto smc_proto; 24extern struct proto smc_proto;
27extern struct proto smc_proto6; 25extern struct proto smc_proto6;
28 26
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index 0eed7ab9f28b..f8b159ced032 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -143,6 +143,62 @@ out:
143 return rc; 143 return rc;
144} 144}
145 145
146static int smc_ib_fill_gid_and_mac(struct smc_ib_device *smcibdev, u8 ibport)
147{
148 struct ib_gid_attr gattr;
149 int rc;
150
151 rc = ib_query_gid(smcibdev->ibdev, ibport, 0,
152 &smcibdev->gid[ibport - 1], &gattr);
153 if (rc || !gattr.ndev)
154 return -ENODEV;
155
156 memcpy(smcibdev->mac[ibport - 1], gattr.ndev->dev_addr, ETH_ALEN);
157 dev_put(gattr.ndev);
158 return 0;
159}
160
161/* Create an identifier unique for this instance of SMC-R.
162 * The MAC-address of the first active registered IB device
163 * plus a random 2-byte number is used to create this identifier.
164 * This name is delivered to the peer during connection initialization.
165 */
166static inline void smc_ib_define_local_systemid(struct smc_ib_device *smcibdev,
167 u8 ibport)
168{
169 memcpy(&local_systemid[2], &smcibdev->mac[ibport - 1],
170 sizeof(smcibdev->mac[ibport - 1]));
171 get_random_bytes(&local_systemid[0], 2);
172}
173
174bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport)
175{
176 return smcibdev->pattr[ibport - 1].state == IB_PORT_ACTIVE;
177}
178
179static int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport)
180{
181 int rc;
182
183 memset(&smcibdev->pattr[ibport - 1], 0,
184 sizeof(smcibdev->pattr[ibport - 1]));
185 rc = ib_query_port(smcibdev->ibdev, ibport,
186 &smcibdev->pattr[ibport - 1]);
187 if (rc)
188 goto out;
189 /* the SMC protocol requires specification of the RoCE MAC address */
190 rc = smc_ib_fill_gid_and_mac(smcibdev, ibport);
191 if (rc)
192 goto out;
193 if (!strncmp(local_systemid, SMC_LOCAL_SYSTEMID_RESET,
194 sizeof(local_systemid)) &&
195 smc_ib_port_active(smcibdev, ibport))
196 /* create unique system identifier */
197 smc_ib_define_local_systemid(smcibdev, ibport);
198out:
199 return rc;
200}
201
146/* process context wrapper for might_sleep smc_ib_remember_port_attr */ 202/* process context wrapper for might_sleep smc_ib_remember_port_attr */
147static void smc_ib_port_event_work(struct work_struct *work) 203static void smc_ib_port_event_work(struct work_struct *work)
148{ 204{
@@ -370,62 +426,6 @@ void smc_ib_buf_unmap_sg(struct smc_ib_device *smcibdev,
370 buf_slot->sgt[SMC_SINGLE_LINK].sgl->dma_address = 0; 426 buf_slot->sgt[SMC_SINGLE_LINK].sgl->dma_address = 0;
371} 427}
372 428
373static int smc_ib_fill_gid_and_mac(struct smc_ib_device *smcibdev, u8 ibport)
374{
375 struct ib_gid_attr gattr;
376 int rc;
377
378 rc = ib_query_gid(smcibdev->ibdev, ibport, 0,
379 &smcibdev->gid[ibport - 1], &gattr);
380 if (rc || !gattr.ndev)
381 return -ENODEV;
382
383 memcpy(smcibdev->mac[ibport - 1], gattr.ndev->dev_addr, ETH_ALEN);
384 dev_put(gattr.ndev);
385 return 0;
386}
387
388/* Create an identifier unique for this instance of SMC-R.
389 * The MAC-address of the first active registered IB device
390 * plus a random 2-byte number is used to create this identifier.
391 * This name is delivered to the peer during connection initialization.
392 */
393static inline void smc_ib_define_local_systemid(struct smc_ib_device *smcibdev,
394 u8 ibport)
395{
396 memcpy(&local_systemid[2], &smcibdev->mac[ibport - 1],
397 sizeof(smcibdev->mac[ibport - 1]));
398 get_random_bytes(&local_systemid[0], 2);
399}
400
401bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport)
402{
403 return smcibdev->pattr[ibport - 1].state == IB_PORT_ACTIVE;
404}
405
406int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport)
407{
408 int rc;
409
410 memset(&smcibdev->pattr[ibport - 1], 0,
411 sizeof(smcibdev->pattr[ibport - 1]));
412 rc = ib_query_port(smcibdev->ibdev, ibport,
413 &smcibdev->pattr[ibport - 1]);
414 if (rc)
415 goto out;
416 /* the SMC protocol requires specification of the RoCE MAC address */
417 rc = smc_ib_fill_gid_and_mac(smcibdev, ibport);
418 if (rc)
419 goto out;
420 if (!strncmp(local_systemid, SMC_LOCAL_SYSTEMID_RESET,
421 sizeof(local_systemid)) &&
422 smc_ib_port_active(smcibdev, ibport))
423 /* create unique system identifier */
424 smc_ib_define_local_systemid(smcibdev, ibport);
425out:
426 return rc;
427}
428
429long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev) 429long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev)
430{ 430{
431 struct ib_cq_init_attr cqattr = { 431 struct ib_cq_init_attr cqattr = {
@@ -454,9 +454,6 @@ long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev)
454 smcibdev->roce_cq_recv = NULL; 454 smcibdev->roce_cq_recv = NULL;
455 goto err; 455 goto err;
456 } 456 }
457 INIT_IB_EVENT_HANDLER(&smcibdev->event_handler, smcibdev->ibdev,
458 smc_ib_global_event_handler);
459 ib_register_event_handler(&smcibdev->event_handler);
460 smc_wr_add_dev(smcibdev); 457 smc_wr_add_dev(smcibdev);
461 smcibdev->initialized = 1; 458 smcibdev->initialized = 1;
462 return rc; 459 return rc;
@@ -472,7 +469,6 @@ static void smc_ib_cleanup_per_ibdev(struct smc_ib_device *smcibdev)
472 return; 469 return;
473 smcibdev->initialized = 0; 470 smcibdev->initialized = 0;
474 smc_wr_remove_dev(smcibdev); 471 smc_wr_remove_dev(smcibdev);
475 ib_unregister_event_handler(&smcibdev->event_handler);
476 ib_destroy_cq(smcibdev->roce_cq_recv); 472 ib_destroy_cq(smcibdev->roce_cq_recv);
477 ib_destroy_cq(smcibdev->roce_cq_send); 473 ib_destroy_cq(smcibdev->roce_cq_send);
478} 474}
@@ -483,6 +479,8 @@ static struct ib_client smc_ib_client;
483static void smc_ib_add_dev(struct ib_device *ibdev) 479static void smc_ib_add_dev(struct ib_device *ibdev)
484{ 480{
485 struct smc_ib_device *smcibdev; 481 struct smc_ib_device *smcibdev;
482 u8 port_cnt;
483 int i;
486 484
487 if (ibdev->node_type != RDMA_NODE_IB_CA) 485 if (ibdev->node_type != RDMA_NODE_IB_CA)
488 return; 486 return;
@@ -498,6 +496,17 @@ static void smc_ib_add_dev(struct ib_device *ibdev)
498 list_add_tail(&smcibdev->list, &smc_ib_devices.list); 496 list_add_tail(&smcibdev->list, &smc_ib_devices.list);
499 spin_unlock(&smc_ib_devices.lock); 497 spin_unlock(&smc_ib_devices.lock);
500 ib_set_client_data(ibdev, &smc_ib_client, smcibdev); 498 ib_set_client_data(ibdev, &smc_ib_client, smcibdev);
499 INIT_IB_EVENT_HANDLER(&smcibdev->event_handler, smcibdev->ibdev,
500 smc_ib_global_event_handler);
501 ib_register_event_handler(&smcibdev->event_handler);
502
503 /* trigger reading of the port attributes */
504 port_cnt = smcibdev->ibdev->phys_port_cnt;
505 for (i = 0;
506 i < min_t(size_t, port_cnt, SMC_MAX_PORTS);
507 i++)
508 set_bit(i, &smcibdev->port_event_mask);
509 schedule_work(&smcibdev->port_event_work);
501} 510}
502 511
503/* callback function for ib_register_client() */ 512/* callback function for ib_register_client() */
@@ -512,6 +521,7 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data)
512 spin_unlock(&smc_ib_devices.lock); 521 spin_unlock(&smc_ib_devices.lock);
513 smc_pnet_remove_by_ibdev(smcibdev); 522 smc_pnet_remove_by_ibdev(smcibdev);
514 smc_ib_cleanup_per_ibdev(smcibdev); 523 smc_ib_cleanup_per_ibdev(smcibdev);
524 ib_unregister_event_handler(&smcibdev->event_handler);
515 kfree(smcibdev); 525 kfree(smcibdev);
516} 526}
517 527
diff --git a/net/smc/smc_ib.h b/net/smc/smc_ib.h
index e90630dadf8e..2c480b352928 100644
--- a/net/smc/smc_ib.h
+++ b/net/smc/smc_ib.h
@@ -51,7 +51,6 @@ struct smc_link;
51int smc_ib_register_client(void) __init; 51int smc_ib_register_client(void) __init;
52void smc_ib_unregister_client(void); 52void smc_ib_unregister_client(void);
53bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport); 53bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport);
54int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport);
55int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev, 54int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev,
56 struct smc_buf_desc *buf_slot, 55 struct smc_buf_desc *buf_slot,
57 enum dma_data_direction data_direction); 56 enum dma_data_direction data_direction);
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index d7b88b2d1b22..a82a5cad0282 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -358,9 +358,6 @@ static int smc_pnet_add(struct sk_buff *skb, struct genl_info *info)
358 kfree(pnetelem); 358 kfree(pnetelem);
359 return rc; 359 return rc;
360 } 360 }
361 rc = smc_ib_remember_port_attr(pnetelem->smcibdev, pnetelem->ib_port);
362 if (rc)
363 smc_pnet_remove_by_pnetid(pnetelem->pnet_name);
364 return rc; 361 return rc;
365} 362}
366 363
@@ -485,10 +482,10 @@ static int smc_pnet_netdev_event(struct notifier_block *this,
485 case NETDEV_REBOOT: 482 case NETDEV_REBOOT:
486 case NETDEV_UNREGISTER: 483 case NETDEV_UNREGISTER:
487 smc_pnet_remove_by_ndev(event_dev); 484 smc_pnet_remove_by_ndev(event_dev);
485 return NOTIFY_OK;
488 default: 486 default:
489 break; 487 return NOTIFY_DONE;
490 } 488 }
491 return NOTIFY_DONE;
492} 489}
493 490
494static struct notifier_block smc_netdev_notifier = { 491static struct notifier_block smc_netdev_notifier = {