diff options
author | Ursula Braun <ubraun@linux.ibm.com> | 2018-06-28 13:05:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-06-30 07:42:25 -0400 |
commit | be6a3f38ff2a2bfd2e591fdc566940a0d4d9428c (patch) | |
tree | 6611f8a48f23ad8468022b5d35d4802f713974a0 /net/smc | |
parent | b0402f0113675ad78bc10c839f93a25348dd1f73 (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.h | 2 | ||||
-rw-r--r-- | net/smc/smc_ib.c | 130 | ||||
-rw-r--r-- | net/smc/smc_ib.h | 1 | ||||
-rw-r--r-- | net/smc/smc_pnet.c | 7 |
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 | |||
26 | extern struct proto smc_proto; | 24 | extern struct proto smc_proto; |
27 | extern struct proto smc_proto6; | 25 | extern 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 | ||
146 | static 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 | */ | ||
166 | static 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 | |||
174 | bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport) | ||
175 | { | ||
176 | return smcibdev->pattr[ibport - 1].state == IB_PORT_ACTIVE; | ||
177 | } | ||
178 | |||
179 | static 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); | ||
198 | out: | ||
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 */ |
147 | static void smc_ib_port_event_work(struct work_struct *work) | 203 | static 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 | ||
373 | static 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 | */ | ||
393 | static 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 | |||
401 | bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport) | ||
402 | { | ||
403 | return smcibdev->pattr[ibport - 1].state == IB_PORT_ACTIVE; | ||
404 | } | ||
405 | |||
406 | int 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); | ||
425 | out: | ||
426 | return rc; | ||
427 | } | ||
428 | |||
429 | long smc_ib_setup_per_ibdev(struct smc_ib_device *smcibdev) | 429 | long 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; | |||
483 | static void smc_ib_add_dev(struct ib_device *ibdev) | 479 | static 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; | |||
51 | int smc_ib_register_client(void) __init; | 51 | int smc_ib_register_client(void) __init; |
52 | void smc_ib_unregister_client(void); | 52 | void smc_ib_unregister_client(void); |
53 | bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport); | 53 | bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport); |
54 | int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport); | ||
55 | int smc_ib_buf_map_sg(struct smc_ib_device *smcibdev, | 54 | int 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 | ||
494 | static struct notifier_block smc_netdev_notifier = { | 491 | static struct notifier_block smc_netdev_notifier = { |