diff options
author | Nir Muchtar <nirm@voltaire.com> | 2011-01-03 10:33:53 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2011-05-25 16:46:23 -0400 |
commit | 753f618ae03a699cc30044d64eea84165016dc6e (patch) | |
tree | 145bbd73eef824f047affe79ee0570a6bb0940b1 | |
parent | b26f9b9949013fec31b23c426fc463164ae08891 (diff) |
RDMA/cma: Add support for netlink statistics export
Add callbacks and data types for statistics export of all current
devices/ids. The schema for RDMA CM is a series of netlink messages.
Each one contains an rdma_cm_stat struct. Additionally, two netlink
attributes are created for the addresses for each message (if
applicable).
Their types used are:
RDMA_NL_RDMA_CM_ATTR_SRC_ADDR (The source address for this ID)
RDMA_NL_RDMA_CM_ATTR_DST_ADDR (The destination address for this ID)
sockaddr_* structs are encapsulated within these attributes.
In other words, every transaction contains a series of messages like:
-------message 1-------
struct rdma_cm_id_stats {
__u32 qp_num;
__u32 bound_dev_if;
__u32 port_space;
__s32 pid;
__u8 cm_state;
__u8 node_type;
__u8 port_num;
__u8 reserved;
}
RDMA_NL_RDMA_CM_ATTR_SRC_ADDR attribute - contains the source address
RDMA_NL_RDMA_CM_ATTR_DST_ADDR attribute - contains the destination address
-------end 1-------
-------message 2-------
struct rdma_cm_id_stats
RDMA_NL_RDMA_CM_ATTR_SRC_ADDR attribute
RDMA_NL_RDMA_CM_ATTR_DST_ADDR attribute
-------end 2-------
Signed-off-by: Nir Muchtar <nirm@voltaire.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r-- | drivers/infiniband/core/cma.c | 99 | ||||
-rw-r--r-- | include/rdma/rdma_netlink.h | 28 |
2 files changed, 127 insertions, 0 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 44be1c9ed05b..5dd9acb92c3a 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | #include <rdma/rdma_cm.h> | 48 | #include <rdma/rdma_cm.h> |
49 | #include <rdma/rdma_cm_ib.h> | 49 | #include <rdma/rdma_cm_ib.h> |
50 | #include <rdma/rdma_netlink.h> | ||
50 | #include <rdma/ib_cache.h> | 51 | #include <rdma/ib_cache.h> |
51 | #include <rdma/ib_cm.h> | 52 | #include <rdma/ib_cm.h> |
52 | #include <rdma/ib_sa.h> | 53 | #include <rdma/ib_sa.h> |
@@ -3315,6 +3316,99 @@ static void cma_remove_one(struct ib_device *device) | |||
3315 | kfree(cma_dev); | 3316 | kfree(cma_dev); |
3316 | } | 3317 | } |
3317 | 3318 | ||
3319 | static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb) | ||
3320 | { | ||
3321 | struct nlmsghdr *nlh; | ||
3322 | struct rdma_cm_id_stats *id_stats; | ||
3323 | struct rdma_id_private *id_priv; | ||
3324 | struct rdma_cm_id *id = NULL; | ||
3325 | struct cma_device *cma_dev; | ||
3326 | int i_dev = 0, i_id = 0; | ||
3327 | |||
3328 | /* | ||
3329 | * We export all of the IDs as a sequence of messages. Each | ||
3330 | * ID gets its own netlink message. | ||
3331 | */ | ||
3332 | mutex_lock(&lock); | ||
3333 | |||
3334 | list_for_each_entry(cma_dev, &dev_list, list) { | ||
3335 | if (i_dev < cb->args[0]) { | ||
3336 | i_dev++; | ||
3337 | continue; | ||
3338 | } | ||
3339 | |||
3340 | i_id = 0; | ||
3341 | list_for_each_entry(id_priv, &cma_dev->id_list, list) { | ||
3342 | if (i_id < cb->args[1]) { | ||
3343 | i_id++; | ||
3344 | continue; | ||
3345 | } | ||
3346 | |||
3347 | id_stats = ibnl_put_msg(skb, &nlh, cb->nlh->nlmsg_seq, | ||
3348 | sizeof *id_stats, RDMA_NL_RDMA_CM, | ||
3349 | RDMA_NL_RDMA_CM_ID_STATS); | ||
3350 | if (!id_stats) | ||
3351 | goto out; | ||
3352 | |||
3353 | memset(id_stats, 0, sizeof *id_stats); | ||
3354 | id = &id_priv->id; | ||
3355 | id_stats->node_type = id->route.addr.dev_addr.dev_type; | ||
3356 | id_stats->port_num = id->port_num; | ||
3357 | id_stats->bound_dev_if = | ||
3358 | id->route.addr.dev_addr.bound_dev_if; | ||
3359 | |||
3360 | if (id->route.addr.src_addr.ss_family == AF_INET) { | ||
3361 | if (ibnl_put_attr(skb, nlh, | ||
3362 | sizeof(struct sockaddr_in), | ||
3363 | &id->route.addr.src_addr, | ||
3364 | RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) { | ||
3365 | goto out; | ||
3366 | } | ||
3367 | if (ibnl_put_attr(skb, nlh, | ||
3368 | sizeof(struct sockaddr_in), | ||
3369 | &id->route.addr.dst_addr, | ||
3370 | RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) { | ||
3371 | goto out; | ||
3372 | } | ||
3373 | } else if (id->route.addr.src_addr.ss_family == AF_INET6) { | ||
3374 | if (ibnl_put_attr(skb, nlh, | ||
3375 | sizeof(struct sockaddr_in6), | ||
3376 | &id->route.addr.src_addr, | ||
3377 | RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) { | ||
3378 | goto out; | ||
3379 | } | ||
3380 | if (ibnl_put_attr(skb, nlh, | ||
3381 | sizeof(struct sockaddr_in6), | ||
3382 | &id->route.addr.dst_addr, | ||
3383 | RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) { | ||
3384 | goto out; | ||
3385 | } | ||
3386 | } | ||
3387 | |||
3388 | id_stats->port_space = id->ps; | ||
3389 | id_stats->cm_state = id_priv->state; | ||
3390 | id_stats->qp_num = id_priv->qp_num; | ||
3391 | id_stats->qp_type = id->qp_type; | ||
3392 | |||
3393 | i_id++; | ||
3394 | } | ||
3395 | |||
3396 | cb->args[1] = 0; | ||
3397 | i_dev++; | ||
3398 | } | ||
3399 | |||
3400 | out: | ||
3401 | mutex_unlock(&lock); | ||
3402 | cb->args[0] = i_dev; | ||
3403 | cb->args[1] = i_id; | ||
3404 | |||
3405 | return skb->len; | ||
3406 | } | ||
3407 | |||
3408 | static const struct ibnl_client_cbs cma_cb_table[] = { | ||
3409 | [RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats }, | ||
3410 | }; | ||
3411 | |||
3318 | static int __init cma_init(void) | 3412 | static int __init cma_init(void) |
3319 | { | 3413 | { |
3320 | int ret; | 3414 | int ret; |
@@ -3330,6 +3424,10 @@ static int __init cma_init(void) | |||
3330 | ret = ib_register_client(&cma_client); | 3424 | ret = ib_register_client(&cma_client); |
3331 | if (ret) | 3425 | if (ret) |
3332 | goto err; | 3426 | goto err; |
3427 | |||
3428 | if (ibnl_add_client(RDMA_NL_RDMA_CM, RDMA_NL_RDMA_CM_NUM_OPS, cma_cb_table)) | ||
3429 | printk(KERN_WARNING "RDMA CMA: failed to add netlink callback\n"); | ||
3430 | |||
3333 | return 0; | 3431 | return 0; |
3334 | 3432 | ||
3335 | err: | 3433 | err: |
@@ -3342,6 +3440,7 @@ err: | |||
3342 | 3440 | ||
3343 | static void __exit cma_cleanup(void) | 3441 | static void __exit cma_cleanup(void) |
3344 | { | 3442 | { |
3443 | ibnl_remove_client(RDMA_NL_RDMA_CM); | ||
3345 | ib_unregister_client(&cma_client); | 3444 | ib_unregister_client(&cma_client); |
3346 | unregister_netdevice_notifier(&cma_nb); | 3445 | unregister_netdevice_notifier(&cma_nb); |
3347 | rdma_addr_unregister_client(&addr_client); | 3446 | rdma_addr_unregister_client(&addr_client); |
diff --git a/include/rdma/rdma_netlink.h b/include/rdma/rdma_netlink.h index c983a193cecf..3c5363ab867b 100644 --- a/include/rdma/rdma_netlink.h +++ b/include/rdma/rdma_netlink.h | |||
@@ -1,10 +1,38 @@ | |||
1 | #ifndef _RDMA_NETLINK_H | 1 | #ifndef _RDMA_NETLINK_H |
2 | #define _RDMA_NETLINK_H | 2 | #define _RDMA_NETLINK_H |
3 | 3 | ||
4 | #include <linux/types.h> | ||
5 | |||
6 | enum { | ||
7 | RDMA_NL_RDMA_CM = 1 | ||
8 | }; | ||
9 | |||
4 | #define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10) | 10 | #define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10) |
5 | #define RDMA_NL_GET_OP(type) (type & ((1 << 10) - 1)) | 11 | #define RDMA_NL_GET_OP(type) (type & ((1 << 10) - 1)) |
6 | #define RDMA_NL_GET_TYPE(client, op) ((client << 10) + op) | 12 | #define RDMA_NL_GET_TYPE(client, op) ((client << 10) + op) |
7 | 13 | ||
14 | enum { | ||
15 | RDMA_NL_RDMA_CM_ID_STATS = 0, | ||
16 | RDMA_NL_RDMA_CM_NUM_OPS | ||
17 | }; | ||
18 | |||
19 | enum { | ||
20 | RDMA_NL_RDMA_CM_ATTR_SRC_ADDR = 1, | ||
21 | RDMA_NL_RDMA_CM_ATTR_DST_ADDR, | ||
22 | RDMA_NL_RDMA_CM_NUM_ATTR, | ||
23 | }; | ||
24 | |||
25 | struct rdma_cm_id_stats { | ||
26 | __u32 qp_num; | ||
27 | __u32 bound_dev_if; | ||
28 | __u32 port_space; | ||
29 | __s32 pid; | ||
30 | __u8 cm_state; | ||
31 | __u8 node_type; | ||
32 | __u8 port_num; | ||
33 | __u8 qp_type; | ||
34 | }; | ||
35 | |||
8 | #ifdef __KERNEL__ | 36 | #ifdef __KERNEL__ |
9 | 37 | ||
10 | #include <linux/netlink.h> | 38 | #include <linux/netlink.h> |