Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aac978e1 authored by Haggai Eran's avatar Haggai Eran Committed by Doug Ledford
Browse files

IB/cma: Helper functions to access port space IDRs



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: default avatarHaggai Eran <haggaie@mellanox.com>
Signed-off-by: default avatarYotam Kenneth <yotamke@mellanox.com>
Signed-off-by: default avatarShachar Raindel <raindel@mellanox.com>
Signed-off-by: default avatarGuy Shapiro <guysh@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 0c505f70
Loading
Loading
Loading
Loading
+60 −21
Original line number Original line Diff line number Diff line
@@ -113,6 +113,22 @@ static DEFINE_IDR(udp_ps);
static DEFINE_IDR(ipoib_ps);
static DEFINE_IDR(ipoib_ps);
static DEFINE_IDR(ib_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 cma_device {
	struct list_head	list;
	struct list_head	list;
	struct ib_device	*device;
	struct ib_device	*device;
@@ -122,11 +138,33 @@ struct cma_device {
};
};


struct rdma_bind_list {
struct rdma_bind_list {
	struct idr		*ps;
	enum rdma_port_space	ps;
	struct hlist_head	owners;
	struct hlist_head	owners;
	unsigned short		port;
	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 {
enum {
	CMA_OPTION_AFONLY,
	CMA_OPTION_AFONLY,
};
};
@@ -1069,7 +1107,7 @@ static void cma_release_port(struct rdma_id_private *id_priv)
	mutex_lock(&lock);
	mutex_lock(&lock);
	hlist_del(&id_priv->node);
	hlist_del(&id_priv->node);
	if (hlist_empty(&bind_list->owners)) {
	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);
		kfree(bind_list);
	}
	}
	mutex_unlock(&lock);
	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);
	hlist_add_head(&id_priv->node, &bind_list->owners);
}
}


static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
static int cma_alloc_port(enum rdma_port_space ps,
			  unsigned short snum)
			  struct rdma_id_private *id_priv, unsigned short snum)
{
{
	struct rdma_bind_list *bind_list;
	struct rdma_bind_list *bind_list;
	int ret;
	int ret;
@@ -2378,7 +2416,7 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
	if (!bind_list)
	if (!bind_list)
		return -ENOMEM;
		return -ENOMEM;


	ret = idr_alloc(ps, bind_list, snum, snum + 1, GFP_KERNEL);
	ret = cma_ps_alloc(ps, bind_list, snum);
	if (ret < 0)
	if (ret < 0)
		goto err;
		goto err;


@@ -2391,7 +2429,8 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
	return ret == -ENOSPC ? -EADDRNOTAVAIL : ret;
	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;
	static unsigned int last_used_port;
	int low, high, remaining;
	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;
	rover = prandom_u32() % remaining + low;
retry:
retry:
	if (last_used_port != rover &&
	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);
		int ret = cma_alloc_port(ps, id_priv, rover);
		/*
		/*
		 * Remember previously used port number in order to avoid
		 * 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;
	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;
	struct rdma_bind_list *bind_list;
	unsigned short snum;
	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))
	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
		return -EACCES;
		return -EACCES;


	bind_list = idr_find(ps, snum);
	bind_list = cma_ps_find(ps, snum);
	if (!bind_list) {
	if (!bind_list) {
		ret = cma_alloc_port(ps, id_priv, snum);
		ret = cma_alloc_port(ps, id_priv, snum);
	} else {
	} else {
@@ -2490,25 +2530,24 @@ static int cma_bind_listen(struct rdma_id_private *id_priv)
	return ret;
	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) {
	switch (id_priv->id.ps) {
	case RDMA_PS_TCP:
	case RDMA_PS_TCP:
		return &tcp_ps;
	case RDMA_PS_UDP:
	case RDMA_PS_UDP:
		return &udp_ps;
	case RDMA_PS_IPOIB:
	case RDMA_PS_IPOIB:
		return &ipoib_ps;
	case RDMA_PS_IB:
	case RDMA_PS_IB:
		return &ib_ps;
		return id_priv->id.ps;
	default:
	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;
	struct sockaddr_ib *sib;
	u64 sid_ps, mask, sid;
	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))) {
	if ((id_priv->id.ps == RDMA_PS_IB) && (sid == (RDMA_IB_IP_PS_IB & mask))) {
		sid_ps = RDMA_IB_IP_PS_IB;
		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)) &&
	} else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_TCP)) &&
		   (sid == (RDMA_IB_IP_PS_TCP & mask))) {
		   (sid == (RDMA_IB_IP_PS_TCP & mask))) {
		sid_ps = RDMA_IB_IP_PS_TCP;
		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)) &&
	} else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_UDP)) &&
		   (sid == (RDMA_IB_IP_PS_UDP & mask))) {
		   (sid == (RDMA_IB_IP_PS_UDP & mask))) {
		sid_ps = RDMA_IB_IP_PS_UDP;
		sid_ps = RDMA_IB_IP_PS_UDP;
		ps = &udp_ps;
		ps = RDMA_PS_UDP;
	}
	}


	if (ps) {
	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)
static int cma_get_port(struct rdma_id_private *id_priv)
{
{
	struct idr *ps;
	enum rdma_port_space ps;
	int ret;
	int ret;


	if (cma_family(id_priv) != AF_IB)
	if (cma_family(id_priv) != AF_IB)