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
4646 SMC_NETLINK_GET_LINK_SMCR,
4747 SMC_NETLINK_GET_LGR_SMCD,
4848 SMC_NETLINK_GET_DEV_SMCD,
49+ SMC_NETLINK_GET_DEV_SMCR,
4950 };
5051
5152 /* SMC_GENL_FAMILY top level attributes */
@@ -56,6 +57,7 @@ enum { · 4 unmodified lines
5657 SMC_GEN_LINK_SMCR, /* nest */
5758 SMC_GEN_LGR_SMCD, /* nest */
5859 SMC_GEN_DEV_SMCD, /* nest */
60+ SMC_GEN_DEV_SMCR, /* nest */
5961 __SMC_GEN_MAX,
6062 SMC_GEN_MAX = __SMC_GEN_MAX - 1
6163 };
@@ -127,16 +129,20 @@ enum { · 65 unmodified lines
127129 SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
128130 };
129131
130−/* SMC_NLA_DEV_PORT attributes */
132+/* SMC_NLA_DEV_PORT nested attributes */
131133 enum {
132134 SMC_NLA_DEV_PORT_UNSPEC,
133135 SMC_NLA_DEV_PORT_PNET_USR, /* u8 */
134136 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 */
135141 __SMC_NLA_DEV_PORT_MAX,
136142 SMC_NLA_DEV_PORT_MAX = __SMC_NLA_DEV_PORT_MAX - 1
137143 };
138144
139−/* SMC_GEN_DEV_SMCD attributes */
145+/* SMC_GEN_DEV_SMCD and SMC_GEN_DEV_SMCR attributes */
140146 enum {
141147 SMC_NLA_DEV_UNSPEC,
142148 SMC_NLA_DEV_USE_CNT, /* u32 */
@@ -147,7 +153,10 @@ enum { · 4 unmodified lines
147153 SMC_NLA_DEV_PCI_DEVICE, /* u16 */
148154 SMC_NLA_DEV_PCI_ID, /* string */
149155 SMC_NLA_DEV_PORT, /* nest */
156+ SMC_NLA_DEV_PORT2, /* nest */
157+ SMC_NLA_DEV_IB_NAME, /* string */
150158 __SMC_NLA_DEV_MAX,
151159 SMC_NLA_DEV_MAX = __SMC_NLA_DEV_MAX - 1
152160 };
161+
153162 #endif /* _UAPI_LINUX_SMC_H */
net/smc/smc_core.c+1−1
@@ -38,7 +38,7 @@ · 37 unmodified lines
3838 #define SMC_LGR_FREE_DELAY_SERV (600 * HZ)
3939 #define SMC_LGR_FREE_DELAY_CLNT (SMC_LGR_FREE_DELAY_SERV + 10 * HZ)
4040
41−static struct smc_lgr_list smc_lgr_list = { /* established link groups */
41+struct smc_lgr_list smc_lgr_list = { /* established link groups */
4242 .lock = __SPIN_LOCK_UNLOCKED(smc_lgr_list.lock),
4343 .list = LIST_HEAD_INIT(smc_lgr_list.list),
4444 .num = 0,
net/smc/smc_ib.c+156−0
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 #include "smc_core.h"
2626 #include "smc_wr.h"
2727 #include "smc.h"
28+#include "smc_netlink.h"
2829
2930 #define SMC_MAX_CQE 32766 /* max. # of completion queue elements */
3031
@@ -326,6 +327,161 @@ int smc_ib_create_protection_domain(struct smc_link *lnk) · 295 unmodified lines
326327 return rc;
327328 }
328329
330+static 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+ }
352+out:
353+ spin_unlock_bh(&smc_lgr->lock);
354+ return rc;
355+}
356+
357+static 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;
391+errattr:
392+ nla_nest_cancel(skb, port_attrs);
393+errout:
394+ return -EMSGSIZE;
395+}
396+
397+static 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+
448+errattr:
449+ nla_nest_cancel(skb, attrs);
450+errout:
451+ genlmsg_cancel(skb, nlh);
452+errmsg:
453+ return -EMSGSIZE;
454+}
455+
456+static 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;
471+next:
472+ num++;
473+ }
474+errout:
475+ mutex_unlock(&dev_list->mutex);
476+ cb_ctx->pos[0] = num;
477+}
478+
479+int 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+
329485 static void smc_ib_qp_event_handler(struct ib_event *ibevent, void *priv)
330486 {
331487 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
3030 };
3131
3232 extern struct smc_ib_devices smc_ib_devices; /* list of smc ib devices */
33+extern struct smc_lgr_list smc_lgr_list; /* list of linkgroups */
3334
3435 struct smc_ib_device { /* ib-device infos for smc */
3536 struct list_head list;
@@ -91,4 +92,5 @@ void smc_ib_sync_sg_for_device(struct smc_link *lnk, · 55 unmodified lines
9192 int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport,
9293 unsigned short vlan_id, u8 gid[], u8 *sgid_index);
9394 bool smc_ib_is_valid_local_systemid(void);
95+int smcr_nl_get_device(struct sk_buff *skb, struct netlink_callback *cb);
9496 #endif
net/smc/smc_netlink.c+6−0
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818
1919 #include "smc_core.h"
2020 #include "smc_ism.h"
21+#include "smc_ib.h"
2122 #include "smc_netlink.h"
2223
2324 #define SMC_CMD_MAX_ATTR 1
@@ -49,6 +50,11 @@ static const struct genl_ops smc_gen_nl_ops[] = { · 25 unmodified lines
4950 /* can be retrieved by unprivileged users */
5051 .dumpit = smcd_nl_get_device,
5152 },
53+ {
54+ .cmd = SMC_NETLINK_GET_DEV_SMCR,
55+ /* can be retrieved by unprivileged users */
56+ .dumpit = smcr_nl_get_device,
57+ },
5258 };
5359
5460 static const struct nla_policy smc_gen_nl_policy[2] = {