Merge tag 'for-linus-unmerged' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma...
[platform/kernel/linux-rpi.git] / drivers / infiniband / core / cma.c
index 6ab1059..51a6410 100644 (file)
@@ -62,6 +62,7 @@
 #include <rdma/iw_cm.h>
 
 #include "core_priv.h"
+#include "cma_priv.h"
 
 MODULE_AUTHOR("Sean Hefty");
 MODULE_DESCRIPTION("Generic RDMA CM Agent");
@@ -174,7 +175,7 @@ static struct cma_pernet *cma_pernet(struct net *net)
        return net_generic(net, cma_pernet_id);
 }
 
-static struct idr *cma_pernet_idr(struct net *net, enum rdma_port_space ps)
+static struct idr *cma_pernet_idr(struct net *net, enum rdma_ucm_port_space ps)
 {
        struct cma_pernet *pernet = cma_pernet(net);
 
@@ -203,7 +204,7 @@ struct cma_device {
 };
 
 struct rdma_bind_list {
-       enum rdma_port_space    ps;
+       enum rdma_ucm_port_space ps;
        struct hlist_head       owners;
        unsigned short          port;
 };
@@ -216,7 +217,7 @@ struct class_port_info_context {
        u8                              port_num;
 };
 
-static int cma_ps_alloc(struct net *net, enum rdma_port_space ps,
+static int cma_ps_alloc(struct net *net, enum rdma_ucm_port_space ps,
                        struct rdma_bind_list *bind_list, int snum)
 {
        struct idr *idr = cma_pernet_idr(net, ps);
@@ -225,14 +226,15 @@ static int cma_ps_alloc(struct net *net, enum rdma_port_space ps,
 }
 
 static struct rdma_bind_list *cma_ps_find(struct net *net,
-                                         enum rdma_port_space ps, int snum)
+                                         enum rdma_ucm_port_space ps, int snum)
 {
        struct idr *idr = cma_pernet_idr(net, ps);
 
        return idr_find(idr, snum);
 }
 
-static void cma_ps_remove(struct net *net, enum rdma_port_space ps, int snum)
+static void cma_ps_remove(struct net *net, enum rdma_ucm_port_space ps,
+                         int snum)
 {
        struct idr *idr = cma_pernet_idr(net, ps);
 
@@ -327,46 +329,6 @@ struct ib_device *cma_get_ib_dev(struct cma_device *cma_dev)
  * We do this by disabling removal notification while a callback is in process,
  * and reporting it after the callback completes.
  */
-struct rdma_id_private {
-       struct rdma_cm_id       id;
-
-       struct rdma_bind_list   *bind_list;
-       struct hlist_node       node;
-       struct list_head        list; /* listen_any_list or cma_device.list */
-       struct list_head        listen_list; /* per device listens */
-       struct cma_device       *cma_dev;
-       struct list_head        mc_list;
-
-       int                     internal_id;
-       enum rdma_cm_state      state;
-       spinlock_t              lock;
-       struct mutex            qp_mutex;
-
-       struct completion       comp;
-       atomic_t                refcount;
-       struct mutex            handler_mutex;
-
-       int                     backlog;
-       int                     timeout_ms;
-       struct ib_sa_query      *query;
-       int                     query_id;
-       union {
-               struct ib_cm_id *ib;
-               struct iw_cm_id *iw;
-       } cm_id;
-
-       u32                     seq_num;
-       u32                     qkey;
-       u32                     qp_num;
-       pid_t                   owner;
-       u32                     options;
-       u8                      srq;
-       u8                      tos;
-       bool                    tos_set;
-       u8                      reuseaddr;
-       u8                      afonly;
-       enum ib_gid_type        gid_type;
-};
 
 struct cma_multicast {
        struct rdma_id_private *id_priv;
@@ -505,6 +467,8 @@ static void _cma_attach_to_dev(struct rdma_id_private *id_priv,
        id_priv->id.route.addr.dev_addr.transport =
                rdma_node_get_transport(cma_dev->device->node_type);
        list_add_tail(&id_priv->list, &cma_dev->id_list);
+       id_priv->res.type = RDMA_RESTRACK_CM_ID;
+       rdma_restrack_add(&id_priv->res);
 }
 
 static void cma_attach_to_dev(struct rdma_id_private *id_priv,
@@ -777,10 +741,10 @@ static void cma_deref_id(struct rdma_id_private *id_priv)
                complete(&id_priv->comp);
 }
 
-struct rdma_cm_id *rdma_create_id(struct net *net,
-                                 rdma_cm_event_handler event_handler,
-                                 void *context, enum rdma_port_space ps,
-                                 enum ib_qp_type qp_type)
+struct rdma_cm_id *__rdma_create_id(struct net *net,
+                                   rdma_cm_event_handler event_handler,
+                                   void *context, enum rdma_ucm_port_space ps,
+                                   enum ib_qp_type qp_type, const char *caller)
 {
        struct rdma_id_private *id_priv;
 
@@ -788,7 +752,10 @@ struct rdma_cm_id *rdma_create_id(struct net *net,
        if (!id_priv)
                return ERR_PTR(-ENOMEM);
 
-       id_priv->owner = task_pid_nr(current);
+       if (caller)
+               id_priv->res.kern_name = caller;
+       else
+               rdma_restrack_set_task(&id_priv->res, current);
        id_priv->state = RDMA_CM_IDLE;
        id_priv->id.context = context;
        id_priv->id.event_handler = event_handler;
@@ -808,7 +775,7 @@ struct rdma_cm_id *rdma_create_id(struct net *net,
 
        return &id_priv->id;
 }
-EXPORT_SYMBOL(rdma_create_id);
+EXPORT_SYMBOL(__rdma_create_id);
 
 static int cma_init_ud_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
 {
@@ -1400,7 +1367,7 @@ static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event,
        return net_dev;
 }
 
-static enum rdma_port_space rdma_ps_from_service_id(__be64 service_id)
+static enum rdma_ucm_port_space rdma_ps_from_service_id(__be64 service_id)
 {
        return (be64_to_cpu(service_id) >> 16) & 0xffff;
 }
@@ -1441,21 +1408,12 @@ static bool cma_match_private_data(struct rdma_id_private *id_priv,
        return true;
 }
 
-static bool cma_protocol_roce_dev_port(struct ib_device *device, int port_num)
-{
-       enum rdma_link_layer ll = rdma_port_get_link_layer(device, port_num);
-       enum rdma_transport_type transport =
-               rdma_node_get_transport(device->node_type);
-
-       return ll == IB_LINK_LAYER_ETHERNET && transport == RDMA_TRANSPORT_IB;
-}
-
 static bool cma_protocol_roce(const struct rdma_cm_id *id)
 {
        struct ib_device *device = id->device;
        const int port_num = id->port_num ?: rdma_start_port(device);
 
-       return cma_protocol_roce_dev_port(device, port_num);
+       return rdma_protocol_roce(device, port_num);
 }
 
 static bool cma_match_net_dev(const struct rdma_cm_id *id,
@@ -1468,7 +1426,7 @@ static bool cma_match_net_dev(const struct rdma_cm_id *id,
                /* This request is an AF_IB request or a RoCE request */
                return (!id->port_num || id->port_num == port_num) &&
                       (addr->src_addr.ss_family == AF_IB ||
-                       cma_protocol_roce_dev_port(id->device, port_num));
+                       rdma_protocol_roce(id->device, port_num));
 
        return !addr->dev_addr.bound_dev_if ||
               (net_eq(dev_net(net_dev), addr->dev_addr.net) &&
@@ -1523,7 +1481,7 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
                if (PTR_ERR(*net_dev) == -EAFNOSUPPORT) {
                        /* Assuming the protocol is AF_IB */
                        *net_dev = NULL;
-               } else if (cma_protocol_roce_dev_port(req.device, req.port)) {
+               } else if (rdma_protocol_roce(req.device, req.port)) {
                        /* TODO find the net dev matching the request parameters
                         * through the RoCE GID table */
                        *net_dev = NULL;
@@ -1668,6 +1626,7 @@ void rdma_destroy_id(struct rdma_cm_id *id)
        mutex_unlock(&id_priv->handler_mutex);
 
        if (id_priv->cma_dev) {
+               rdma_restrack_del(&id_priv->res);
                if (rdma_cap_ib_cm(id_priv->id.device, 1)) {
                        if (id_priv->cm_id.ib)
                                ib_destroy_cm_id(id_priv->cm_id.ib);
@@ -1817,6 +1776,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
                                               struct ib_cm_event *ib_event,
                                               struct net_device *net_dev)
 {
+       struct rdma_id_private *listen_id_priv;
        struct rdma_id_private *id_priv;
        struct rdma_cm_id *id;
        struct rdma_route *rt;
@@ -1826,9 +1786,11 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
                ib_event->param.req_rcvd.primary_path->service_id;
        int ret;
 
-       id = rdma_create_id(listen_id->route.addr.dev_addr.net,
+       listen_id_priv = container_of(listen_id, struct rdma_id_private, id);
+       id = __rdma_create_id(listen_id->route.addr.dev_addr.net,
                            listen_id->event_handler, listen_id->context,
-                           listen_id->ps, ib_event->param.req_rcvd.qp_type);
+                           listen_id->ps, ib_event->param.req_rcvd.qp_type,
+                           listen_id_priv->res.kern_name);
        if (IS_ERR(id))
                return NULL;
 
@@ -1877,14 +1839,17 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
                                              struct ib_cm_event *ib_event,
                                              struct net_device *net_dev)
 {
+       struct rdma_id_private *listen_id_priv;
        struct rdma_id_private *id_priv;
        struct rdma_cm_id *id;
        const sa_family_t ss_family = listen_id->route.addr.src_addr.ss_family;
        struct net *net = listen_id->route.addr.dev_addr.net;
        int ret;
 
-       id = rdma_create_id(net, listen_id->event_handler, listen_id->context,
-                           listen_id->ps, IB_QPT_UD);
+       listen_id_priv = container_of(listen_id, struct rdma_id_private, id);
+       id = __rdma_create_id(net, listen_id->event_handler, listen_id->context,
+                             listen_id->ps, IB_QPT_UD,
+                             listen_id_priv->res.kern_name);
        if (IS_ERR(id))
                return NULL;
 
@@ -2150,10 +2115,11 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
                goto out;
 
        /* Create a new RDMA id for the new IW CM ID */
-       new_cm_id = rdma_create_id(listen_id->id.route.addr.dev_addr.net,
-                                  listen_id->id.event_handler,
-                                  listen_id->id.context,
-                                  RDMA_PS_TCP, IB_QPT_RC);
+       new_cm_id = __rdma_create_id(listen_id->id.route.addr.dev_addr.net,
+                                    listen_id->id.event_handler,
+                                    listen_id->id.context,
+                                    RDMA_PS_TCP, IB_QPT_RC,
+                                    listen_id->res.kern_name);
        if (IS_ERR(new_cm_id)) {
                ret = -ENOMEM;
                goto out;
@@ -2278,8 +2244,8 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
        if (cma_family(id_priv) == AF_IB && !rdma_cap_ib_cm(cma_dev->device, 1))
                return;
 
-       id = rdma_create_id(net, cma_listen_handler, id_priv, id_priv->id.ps,
-                           id_priv->id.qp_type);
+       id = __rdma_create_id(net, cma_listen_handler, id_priv, id_priv->id.ps,
+                             id_priv->id.qp_type, id_priv->res.kern_name);
        if (IS_ERR(id))
                return;
 
@@ -2541,6 +2507,7 @@ cma_iboe_set_path_rec_l2_fields(struct rdma_id_private *id_priv)
                gid_type = ib_network_to_gid_type(addr->dev_addr.network);
        route->path_rec->rec_type = sa_conv_gid_to_pathrec_type(gid_type);
 
+       route->path_rec->roce.route_resolved = true;
        sa_path_set_ndev(route->path_rec, addr->dev_addr.net);
        sa_path_set_ifindex(route->path_rec, ndev->ifindex);
        sa_path_set_dmac(route->path_rec, addr->dev_addr.dst_dev_addr);
@@ -3028,7 +2995,7 @@ static void cma_bind_port(struct rdma_bind_list *bind_list,
        hlist_add_head(&id_priv->node, &bind_list->owners);
 }
 
-static int cma_alloc_port(enum rdma_port_space ps,
+static int cma_alloc_port(enum rdma_ucm_port_space ps,
                          struct rdma_id_private *id_priv, unsigned short snum)
 {
        struct rdma_bind_list *bind_list;
@@ -3091,7 +3058,7 @@ static int cma_port_is_unique(struct rdma_bind_list *bind_list,
        return 0;
 }
 
-static int cma_alloc_any_port(enum rdma_port_space ps,
+static int cma_alloc_any_port(enum rdma_ucm_port_space ps,
                              struct rdma_id_private *id_priv)
 {
        static unsigned int last_used_port;
@@ -3169,7 +3136,7 @@ static int cma_check_port(struct rdma_bind_list *bind_list,
        return 0;
 }
 
-static int cma_use_port(enum rdma_port_space ps,
+static int cma_use_port(enum rdma_ucm_port_space ps,
                        struct rdma_id_private *id_priv)
 {
        struct rdma_bind_list *bind_list;
@@ -3203,8 +3170,8 @@ static int cma_bind_listen(struct rdma_id_private *id_priv)
        return ret;
 }
 
-static enum rdma_port_space cma_select_inet_ps(
-               struct rdma_id_private *id_priv)
+static enum rdma_ucm_port_space
+cma_select_inet_ps(struct rdma_id_private *id_priv)
 {
        switch (id_priv->id.ps) {
        case RDMA_PS_TCP:
@@ -3218,9 +3185,10 @@ static enum rdma_port_space cma_select_inet_ps(
        }
 }
 
-static enum rdma_port_space cma_select_ib_ps(struct rdma_id_private *id_priv)
+static enum rdma_ucm_port_space
+cma_select_ib_ps(struct rdma_id_private *id_priv)
 {
-       enum rdma_port_space ps = 0;
+       enum rdma_ucm_port_space ps = 0;
        struct sockaddr_ib *sib;
        u64 sid_ps, mask, sid;
 
@@ -3251,7 +3219,7 @@ static enum rdma_port_space cma_select_ib_ps(struct rdma_id_private *id_priv)
 
 static int cma_get_port(struct rdma_id_private *id_priv)
 {
-       enum rdma_port_space ps;
+       enum rdma_ucm_port_space ps;
        int ret;
 
        if (cma_family(id_priv) != AF_IB)
@@ -3389,8 +3357,10 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
 
        return 0;
 err2:
-       if (id_priv->cma_dev)
+       if (id_priv->cma_dev) {
+               rdma_restrack_del(&id_priv->res);
                cma_release_dev(id_priv);
+       }
 err1:
        cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_IDLE);
        return ret;
@@ -3773,14 +3743,18 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
        return ib_send_cm_sidr_rep(id_priv->cm_id.ib, &rep);
 }
 
-int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
+int __rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param,
+                 const char *caller)
 {
        struct rdma_id_private *id_priv;
        int ret;
 
        id_priv = container_of(id, struct rdma_id_private, id);
 
-       id_priv->owner = task_pid_nr(current);
+       if (caller)
+               id_priv->res.kern_name = caller;
+       else
+               rdma_restrack_set_task(&id_priv->res, current);
 
        if (!cma_comp(id_priv, RDMA_CM_CONNECT))
                return -EINVAL;
@@ -3820,7 +3794,7 @@ reject:
        rdma_reject(id, NULL, 0);
        return ret;
 }
-EXPORT_SYMBOL(rdma_accept);
+EXPORT_SYMBOL(__rdma_accept);
 
 int rdma_notify(struct rdma_cm_id *id, enum ib_event_type event)
 {
@@ -3938,10 +3912,14 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
                        rdma_start_port(id_priv->cma_dev->device)];
 
                event.event = RDMA_CM_EVENT_MULTICAST_JOIN;
-               ib_init_ah_from_mcmember(id_priv->id.device,
-                                        id_priv->id.port_num, &multicast->rec,
-                                        ndev, gid_type,
-                                        &event.param.ud.ah_attr);
+               ret = ib_init_ah_from_mcmember(id_priv->id.device,
+                                              id_priv->id.port_num,
+                                              &multicast->rec,
+                                              ndev, gid_type,
+                                              &event.param.ud.ah_attr);
+               if (ret)
+                       event.event = RDMA_CM_EVENT_MULTICAST_ERROR;
+
                event.param.ud.qp_num = 0xFFFFFF;
                event.param.ud.qkey = be32_to_cpu(multicast->rec.qkey);
                if (ndev)
@@ -4501,7 +4479,7 @@ static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb)
                                          RDMA_NL_RDMA_CM_ATTR_DST_ADDR))
                                goto out;
 
-                       id_stats->pid           = id_priv->owner;
+                       id_stats->pid   = task_pid_vnr(id_priv->res.task);
                        id_stats->port_space    = id->ps;
                        id_stats->cm_state      = id_priv->state;
                        id_stats->qp_num        = id_priv->qp_num;