History

net/smc: Add support for obtaining SMCR device list

Deliver SMCR device information via netlink based diagnostic interface.

Guvenc Gulce committed 5 years ago

Commit a3db10e1 parent aaf95525 files · +176 −3Browse files

Unified · Split

5 files
  1. include/uapi/linux/smc.h +11 −2
  2. net/smc/smc_core.c +1 −1
  3. net/smc/smc_ib.c +156 −0
  4. net/smc/smc_ib.h +2 −0
  5. net/smc/smc_netlink.c +6 −0
include/uapi/linux/smc.h+11−2
@@ -46,6 +46,7 @@ enum { · 45 unmodified lines
46 SMC_NETLINK_GET_LINK_SMCR,46 SMC_NETLINK_GET_LINK_SMCR,
47 SMC_NETLINK_GET_LGR_SMCD,47 SMC_NETLINK_GET_LGR_SMCD,
48 SMC_NETLINK_GET_DEV_SMCD,48 SMC_NETLINK_GET_DEV_SMCD,
49 SMC_NETLINK_GET_DEV_SMCR,
49};50};
50 51
51/* SMC_GENL_FAMILY top level attributes */52/* SMC_GENL_FAMILY top level attributes */
@@ -56,6 +57,7 @@ enum { · 4 unmodified lines
56 SMC_GEN_LINK_SMCR, /* nest */57 SMC_GEN_LINK_SMCR, /* nest */
57 SMC_GEN_LGR_SMCD, /* nest */58 SMC_GEN_LGR_SMCD, /* nest */
58 SMC_GEN_DEV_SMCD, /* nest */59 SMC_GEN_DEV_SMCD, /* nest */
60 SMC_GEN_DEV_SMCR, /* nest */
59 __SMC_GEN_MAX,61 __SMC_GEN_MAX,
60 SMC_GEN_MAX = __SMC_GEN_MAX - 162 SMC_GEN_MAX = __SMC_GEN_MAX - 1
61};63};
@@ -127,16 +129,20 @@ enum { · 65 unmodified lines
127 SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1129 SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
128};130};
129 131
130/* SMC_NLA_DEV_PORT attributes */132/* SMC_NLA_DEV_PORT nested attributes */
131enum {133enum {
132 SMC_NLA_DEV_PORT_UNSPEC,134 SMC_NLA_DEV_PORT_UNSPEC,
133 SMC_NLA_DEV_PORT_PNET_USR, /* u8 */135 SMC_NLA_DEV_PORT_PNET_USR, /* u8 */
134 SMC_NLA_DEV_PORT_PNETID, /* string */136 SMC_NLA_DEV_PORT_PNETID, /* string */
137 SMC_NLA_DEV_PORT_NETDEV, /* u32 */
138 SMC_NLA_DEV_PORT_STATE, /* u8 */
139 SMC_NLA_DEV_PORT_VALID, /* u8 */
140 SMC_NLA_DEV_PORT_LNK_CNT, /* u32 */
135 __SMC_NLA_DEV_PORT_MAX,141 __SMC_NLA_DEV_PORT_MAX,
136 SMC_NLA_DEV_PORT_MAX = __SMC_NLA_DEV_PORT_MAX - 1142 SMC_NLA_DEV_PORT_MAX = __SMC_NLA_DEV_PORT_MAX - 1
137};143};
138 144
139/* SMC_GEN_DEV_SMCD attributes */145/* SMC_GEN_DEV_SMCD and SMC_GEN_DEV_SMCR attributes */
140enum {146enum {
141 SMC_NLA_DEV_UNSPEC,147 SMC_NLA_DEV_UNSPEC,
142 SMC_NLA_DEV_USE_CNT, /* u32 */148 SMC_NLA_DEV_USE_CNT, /* u32 */
@@ -147,7 +153,10 @@ enum { · 4 unmodified lines
147 SMC_NLA_DEV_PCI_DEVICE, /* u16 */153 SMC_NLA_DEV_PCI_DEVICE, /* u16 */
148 SMC_NLA_DEV_PCI_ID, /* string */154 SMC_NLA_DEV_PCI_ID, /* string */
149 SMC_NLA_DEV_PORT, /* nest */155 SMC_NLA_DEV_PORT, /* nest */
156 SMC_NLA_DEV_PORT2, /* nest */
157 SMC_NLA_DEV_IB_NAME, /* string */
150 __SMC_NLA_DEV_MAX,158 __SMC_NLA_DEV_MAX,
151 SMC_NLA_DEV_MAX = __SMC_NLA_DEV_MAX - 1159 SMC_NLA_DEV_MAX = __SMC_NLA_DEV_MAX - 1
152};160};
161
153#endif /* _UAPI_LINUX_SMC_H */162#endif /* _UAPI_LINUX_SMC_H */
net/smc/smc_core.c+1−1
@@ -38,7 +38,7 @@ · 37 unmodified lines
38#define SMC_LGR_FREE_DELAY_SERV (600 * HZ)38#define SMC_LGR_FREE_DELAY_SERV (600 * HZ)
39#define SMC_LGR_FREE_DELAY_CLNT (SMC_LGR_FREE_DELAY_SERV + 10 * HZ)39#define SMC_LGR_FREE_DELAY_CLNT (SMC_LGR_FREE_DELAY_SERV + 10 * HZ)
40 40
41static struct smc_lgr_list smc_lgr_list = { /* established link groups */41struct smc_lgr_list smc_lgr_list = { /* established link groups */
42 .lock = __SPIN_LOCK_UNLOCKED(smc_lgr_list.lock),42 .lock = __SPIN_LOCK_UNLOCKED(smc_lgr_list.lock),
43 .list = LIST_HEAD_INIT(smc_lgr_list.list),43 .list = LIST_HEAD_INIT(smc_lgr_list.list),
44 .num = 0,44 .num = 0,
net/smc/smc_ib.c+156−0
@@ -25,6 +25,7 @@ · 24 unmodified lines
25#include "smc_core.h"25#include "smc_core.h"
26#include "smc_wr.h"26#include "smc_wr.h"
27#include "smc.h"27#include "smc.h"
28#include "smc_netlink.h"
28 29
29#define SMC_MAX_CQE 32766 /* max. # of completion queue elements */30#define SMC_MAX_CQE 32766 /* max. # of completion queue elements */
30 31
@@ -326,6 +327,161 @@ int smc_ib_create_protection_domain(struct smc_link *lnk) · 295 unmodified lines
326 return rc;327 return rc;
327}328}
328 329
330static bool smcr_diag_is_dev_critical(struct smc_lgr_list *smc_lgr,
331 struct smc_ib_device *smcibdev)
332{
333 struct smc_link_group *lgr;
334 bool rc = false;
335 int i;
336
337 spin_lock_bh(&smc_lgr->lock);
338 list_for_each_entry(lgr, &smc_lgr->list, list) {
339 if (lgr->is_smcd)
340 continue;
341 for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
342 if (lgr->lnk[i].state == SMC_LNK_UNUSED ||
343 lgr->lnk[i].smcibdev != smcibdev)
344 continue;
345 if (lgr->type == SMC_LGR_SINGLE ||
346 lgr->type == SMC_LGR_ASYMMETRIC_LOCAL) {
347 rc = true;
348 goto out;
349 }
350 }
351 }
352out:
353 spin_unlock_bh(&smc_lgr->lock);
354 return rc;
355}
356
357static int smc_nl_handle_dev_port(struct sk_buff *skb,
358 struct ib_device *ibdev,
359 struct smc_ib_device *smcibdev,
360 int port)
361{
362 char smc_pnet[SMC_MAX_PNETID_LEN + 1];
363 struct nlattr *port_attrs;
364 unsigned char port_state;
365 int lnk_count = 0;
366
367 port_attrs = nla_nest_start(skb, SMC_NLA_DEV_PORT + port);
368 if (!port_attrs)
369 goto errout;
370
371 if (nla_put_u8(skb, SMC_NLA_DEV_PORT_PNET_USR,
372 smcibdev->pnetid_by_user[port]))
373 goto errattr;
374 snprintf(smc_pnet, sizeof(smc_pnet), "%s",
375 (char *)&smcibdev->pnetid[port]);
376 if (nla_put_string(skb, SMC_NLA_DEV_PORT_PNETID, smc_pnet))
377 goto errattr;
378 if (nla_put_u32(skb, SMC_NLA_DEV_PORT_NETDEV,
379 smcibdev->ndev_ifidx[port]))
380 goto errattr;
381 if (nla_put_u8(skb, SMC_NLA_DEV_PORT_VALID, 1))
382 goto errattr;
383 port_state = smc_ib_port_active(smcibdev, port + 1);
384 if (nla_put_u8(skb, SMC_NLA_DEV_PORT_STATE, port_state))
385 goto errattr;
386 lnk_count = atomic_read(&smcibdev->lnk_cnt_by_port[port]);
387 if (nla_put_u32(skb, SMC_NLA_DEV_PORT_LNK_CNT, lnk_count))
388 goto errattr;
389 nla_nest_end(skb, port_attrs);
390 return 0;
391errattr:
392 nla_nest_cancel(skb, port_attrs);
393errout:
394 return -EMSGSIZE;
395}
396
397static int smc_nl_handle_smcr_dev(struct smc_ib_device *smcibdev,
398 struct sk_buff *skb,
399 struct netlink_callback *cb)
400{
401 char smc_ibname[IB_DEVICE_NAME_MAX + 1];
402 struct smc_pci_dev smc_pci_dev;
403 struct pci_dev *pci_dev;
404 unsigned char is_crit;
405 struct nlattr *attrs;
406 void *nlh;
407 int i;
408
409 nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
410 &smc_gen_nl_family, NLM_F_MULTI,
411 SMC_NETLINK_GET_DEV_SMCR);
412 if (!nlh)
413 goto errmsg;
414 attrs = nla_nest_start(skb, SMC_GEN_DEV_SMCR);
415 if (!attrs)
416 goto errout;
417 is_crit = smcr_diag_is_dev_critical(&smc_lgr_list, smcibdev);
418 if (nla_put_u8(skb, SMC_NLA_DEV_IS_CRIT, is_crit))
419 goto errattr;
420 memset(&smc_pci_dev, 0, sizeof(smc_pci_dev));
421 pci_dev = to_pci_dev(smcibdev->ibdev->dev.parent);
422 smc_set_pci_values(pci_dev, &smc_pci_dev);
423 if (nla_put_u32(skb, SMC_NLA_DEV_PCI_FID, smc_pci_dev.pci_fid))
424 goto errattr;
425 if (nla_put_u16(skb, SMC_NLA_DEV_PCI_CHID, smc_pci_dev.pci_pchid))
426 goto errattr;
427 if (nla_put_u16(skb, SMC_NLA_DEV_PCI_VENDOR, smc_pci_dev.pci_vendor))
428 goto errattr;
429 if (nla_put_u16(skb, SMC_NLA_DEV_PCI_DEVICE, smc_pci_dev.pci_device))
430 goto errattr;
431 if (nla_put_string(skb, SMC_NLA_DEV_PCI_ID, smc_pci_dev.pci_id))
432 goto errattr;
433 snprintf(smc_ibname, sizeof(smc_ibname), "%s", smcibdev->ibdev->name);
434 if (nla_put_string(skb, SMC_NLA_DEV_IB_NAME, smc_ibname))
435 goto errattr;
436 for (i = 1; i <= SMC_MAX_PORTS; i++) {
437 if (!rdma_is_port_valid(smcibdev->ibdev, i))
438 continue;
439 if (smc_nl_handle_dev_port(skb, smcibdev->ibdev,
440 smcibdev, i - 1))
441 goto errattr;
442 }
443
444 nla_nest_end(skb, attrs);
445 genlmsg_end(skb, nlh);
446 return 0;
447
448errattr:
449 nla_nest_cancel(skb, attrs);
450errout:
451 genlmsg_cancel(skb, nlh);
452errmsg:
453 return -EMSGSIZE;
454}
455
456static void smc_nl_prep_smcr_dev(struct smc_ib_devices *dev_list,
457 struct sk_buff *skb,
458 struct netlink_callback *cb)
459{
460 struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
461 struct smc_ib_device *smcibdev;
462 int snum = cb_ctx->pos[0];
463 int num = 0;
464
465 mutex_lock(&dev_list->mutex);
466 list_for_each_entry(smcibdev, &dev_list->list, list) {
467 if (num < snum)
468 goto next;
469 if (smc_nl_handle_smcr_dev(smcibdev, skb, cb))
470 goto errout;
471next:
472 num++;
473 }
474errout:
475 mutex_unlock(&dev_list->mutex);
476 cb_ctx->pos[0] = num;
477}
478
479int smcr_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb)
480{
481 smc_nl_prep_smcr_dev(&smc_ib_devices, skb, cb);
482 return skb->len;
483}
484
329static void smc_ib_qp_event_handler(struct ib_event *ibevent, void *priv)485static void smc_ib_qp_event_handler(struct ib_event *ibevent, void *priv)
330{486{
331 struct smc_link *lnk = (struct smc_link *)priv;487 struct smc_link *lnk = (struct smc_link *)priv;
net/smc/smc_ib.h+2−0
@@ -30,6 +30,7 @@ struct smc_ib_devices { /* list of smc ib devices definition */ · 29 unmodified lines
30};30};
31 31
32extern struct smc_ib_devices smc_ib_devices; /* list of smc ib devices */32extern struct smc_ib_devices smc_ib_devices; /* list of smc ib devices */
33extern struct smc_lgr_list smc_lgr_list; /* list of linkgroups */
33 34
34struct smc_ib_device { /* ib-device infos for smc */35struct smc_ib_device { /* ib-device infos for smc */
35 struct list_head list;36 struct list_head list;
@@ -91,4 +92,5 @@ void smc_ib_sync_sg_for_device(struct smc_link *lnk, · 55 unmodified lines
91int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport,92int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport,
92 unsigned short vlan_id, u8 gid[], u8 *sgid_index);93 unsigned short vlan_id, u8 gid[], u8 *sgid_index);
93bool smc_ib_is_valid_local_systemid(void);94bool smc_ib_is_valid_local_systemid(void);
95int smcr_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb);
94#endif96#endif
net/smc/smc_netlink.c+6−0
@@ -18,6 +18,7 @@ · 17 unmodified lines
18 18
19#include "smc_core.h"19#include "smc_core.h"
20#include "smc_ism.h"20#include "smc_ism.h"
21#include "smc_ib.h"
21#include "smc_netlink.h"22#include "smc_netlink.h"
22 23
23#define SMC_CMD_MAX_ATTR 124#define SMC_CMD_MAX_ATTR 1
@@ -49,6 +50,11 @@ static const struct genl_ops smc_gen_nl_ops[] = { · 25 unmodified lines
49 /* can be retrieved by unprivileged users */50 /* can be retrieved by unprivileged users */
50 .dumpit = smcd_nl_get_device,51 .dumpit = smcd_nl_get_device,
51 },52 },
53 {
54 .cmd = SMC_NETLINK_GET_DEV_SMCR,
55 /* can be retrieved by unprivileged users */
56 .dumpit = smcr_nl_get_device,
57 },
52};58};
53 59
54static const struct nla_policy smc_gen_nl_policy[2] = {60static const struct nla_policy smc_gen_nl_policy[2] = {