IB/cma: Helper functions to access port space IDRs
authorHaggai Eran <haggaie@mellanox.com>
Thu, 30 Jul 2015 14:50:20 +0000 (17:50 +0300)
committerDoug Ledford <dledford@redhat.com>
Sun, 30 Aug 2015 19:48:23 +0000 (15:48 -0400)
Add helper functions to access the IDRs by port-space and port number.

Pass around the port-space enum in cma.c instead of using pointers to
port-space IDRs.

Signed-off-by: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: Yotam Kenneth <yotamke@mellanox.com>
Signed-off-by: Shachar Raindel <raindel@mellanox.com>
Signed-off-by: Guy Shapiro <guysh@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/cma.c

index 249944c2c537edec8bcb332e20f83e5324439cb1..a7886acba0724b3987324cdb8c6b79107ba1738e 100644 (file)
@@ -113,6 +113,22 @@ static DEFINE_IDR(udp_ps);
 static DEFINE_IDR(ipoib_ps);
 static DEFINE_IDR(ib_ps);
 
+static struct idr *cma_idr(enum rdma_port_space ps)
+{
+       switch (ps) {
+       case RDMA_PS_TCP:
+               return &tcp_ps;
+       case RDMA_PS_UDP:
+               return &udp_ps;
+       case RDMA_PS_IPOIB:
+               return &ipoib_ps;
+       case RDMA_PS_IB:
+               return &ib_ps;
+       default:
+               return NULL;
+       }
+}
+
 struct cma_device {
        struct list_head        list;
        struct ib_device        *device;
@@ -122,11 +138,33 @@ struct cma_device {
 };
 
 struct rdma_bind_list {
-       struct idr              *ps;
+       enum rdma_port_space    ps;
        struct hlist_head       owners;
        unsigned short          port;
 };
 
+static int cma_ps_alloc(enum rdma_port_space ps,
+                       struct rdma_bind_list *bind_list, int snum)
+{
+       struct idr *idr = cma_idr(ps);
+
+       return idr_alloc(idr, bind_list, snum, snum + 1, GFP_KERNEL);
+}
+
+static struct rdma_bind_list *cma_ps_find(enum rdma_port_space ps, int snum)
+{
+       struct idr *idr = cma_idr(ps);
+
+       return idr_find(idr, snum);
+}
+
+static void cma_ps_remove(enum rdma_port_space ps, int snum)
+{
+       struct idr *idr = cma_idr(ps);
+
+       idr_remove(idr, snum);
+}
+
 enum {
        CMA_OPTION_AFONLY,
 };
@@ -1069,7 +1107,7 @@ static void cma_release_port(struct rdma_id_private *id_priv)
        mutex_lock(&lock);
        hlist_del(&id_priv->node);
        if (hlist_empty(&bind_list->owners)) {
-               idr_remove(bind_list->ps, bind_list->port);
+               cma_ps_remove(bind_list->ps, bind_list->port);
                kfree(bind_list);
        }
        mutex_unlock(&lock);
@@ -2368,8 +2406,8 @@ 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(struct idr *ps, struct rdma_id_private *id_priv,
-                         unsigned short snum)
+static int cma_alloc_port(enum rdma_port_space ps,
+                         struct rdma_id_private *id_priv, unsigned short snum)
 {
        struct rdma_bind_list *bind_list;
        int ret;
@@ -2378,7 +2416,7 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
        if (!bind_list)
                return -ENOMEM;
 
-       ret = idr_alloc(ps, bind_list, snum, snum + 1, GFP_KERNEL);
+       ret = cma_ps_alloc(ps, bind_list, snum);
        if (ret < 0)
                goto err;
 
@@ -2391,7 +2429,8 @@ err:
        return ret == -ENOSPC ? -EADDRNOTAVAIL : ret;
 }
 
-static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
+static int cma_alloc_any_port(enum rdma_port_space ps,
+                             struct rdma_id_private *id_priv)
 {
        static unsigned int last_used_port;
        int low, high, remaining;
@@ -2402,7 +2441,7 @@ static int cma_alloc_any_port(struct idr *ps, struct rdma_id_private *id_priv)
        rover = prandom_u32() % remaining + low;
 retry:
        if (last_used_port != rover &&
-           !idr_find(ps, (unsigned short) rover)) {
+           !cma_ps_find(ps, (unsigned short)rover)) {
                int ret = cma_alloc_port(ps, id_priv, rover);
                /*
                 * Remember previously used port number in order to avoid
@@ -2457,7 +2496,8 @@ static int cma_check_port(struct rdma_bind_list *bind_list,
        return 0;
 }
 
-static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
+static int cma_use_port(enum rdma_port_space ps,
+                       struct rdma_id_private *id_priv)
 {
        struct rdma_bind_list *bind_list;
        unsigned short snum;
@@ -2467,7 +2507,7 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
        if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
                return -EACCES;
 
-       bind_list = idr_find(ps, snum);
+       bind_list = cma_ps_find(ps, snum);
        if (!bind_list) {
                ret = cma_alloc_port(ps, id_priv, snum);
        } else {
@@ -2490,25 +2530,24 @@ static int cma_bind_listen(struct rdma_id_private *id_priv)
        return ret;
 }
 
-static struct idr *cma_select_inet_ps(struct rdma_id_private *id_priv)
+static enum rdma_port_space cma_select_inet_ps(
+               struct rdma_id_private *id_priv)
 {
        switch (id_priv->id.ps) {
        case RDMA_PS_TCP:
-               return &tcp_ps;
        case RDMA_PS_UDP:
-               return &udp_ps;
        case RDMA_PS_IPOIB:
-               return &ipoib_ps;
        case RDMA_PS_IB:
-               return &ib_ps;
+               return id_priv->id.ps;
        default:
-               return NULL;
+
+               return 0;
        }
 }
 
-static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
+static enum rdma_port_space cma_select_ib_ps(struct rdma_id_private *id_priv)
 {
-       struct idr *ps = NULL;
+       enum rdma_port_space ps = 0;
        struct sockaddr_ib *sib;
        u64 sid_ps, mask, sid;
 
@@ -2518,15 +2557,15 @@ static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
 
        if ((id_priv->id.ps == RDMA_PS_IB) && (sid == (RDMA_IB_IP_PS_IB & mask))) {
                sid_ps = RDMA_IB_IP_PS_IB;
-               ps = &ib_ps;
+               ps = RDMA_PS_IB;
        } else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_TCP)) &&
                   (sid == (RDMA_IB_IP_PS_TCP & mask))) {
                sid_ps = RDMA_IB_IP_PS_TCP;
-               ps = &tcp_ps;
+               ps = RDMA_PS_TCP;
        } else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_UDP)) &&
                   (sid == (RDMA_IB_IP_PS_UDP & mask))) {
                sid_ps = RDMA_IB_IP_PS_UDP;
-               ps = &udp_ps;
+               ps = RDMA_PS_UDP;
        }
 
        if (ps) {
@@ -2539,7 +2578,7 @@ static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
 
 static int cma_get_port(struct rdma_id_private *id_priv)
 {
-       struct idr *ps;
+       enum rdma_port_space ps;
        int ret;
 
        if (cma_family(id_priv) != AF_IB)