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

Commit 2f0304d2 authored by Steve Wise's avatar Steve Wise Committed by Roland Dreier
Browse files

RDMA/iwcm: Use a default listen backlog if needed



If the user creates a listening cm_id with backlog of 0 the IWCM ends
up not allowing any connection requests at all.  The correct behavior
is for the IWCM to pick a default value if the user backlog parameter
is zero.

Lustre from version 1.8.8 onward uses a backlog of 0, which breaks
iwarp support without this fix.

Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 64aa90f2
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include <linux/completion.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/sysctl.h>

#include <rdma/iw_cm.h>
#include <rdma/ib_addr.h>
@@ -65,6 +66,20 @@ struct iwcm_work {
	struct list_head free_list;
};

static unsigned int default_backlog = 256;

static struct ctl_table_header *iwcm_ctl_table_hdr;
static struct ctl_table iwcm_ctl_table[] = {
	{
		.procname	= "default_backlog",
		.data		= &default_backlog,
		.maxlen		= sizeof(default_backlog),
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
	},
	{ }
};

/*
 * The following services provide a mechanism for pre-allocating iwcm_work
 * elements.  The design pre-allocates them  based on the cm_id type:
@@ -425,6 +440,9 @@ int iw_cm_listen(struct iw_cm_id *cm_id, int backlog)

	cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);

	if (!backlog)
		backlog = default_backlog;

	ret = alloc_work_entries(cm_id_priv, backlog);
	if (ret)
		return ret;
@@ -1030,11 +1048,20 @@ static int __init iw_cm_init(void)
	if (!iwcm_wq)
		return -ENOMEM;

	iwcm_ctl_table_hdr = register_net_sysctl(&init_net, "net/iw_cm",
						 iwcm_ctl_table);
	if (!iwcm_ctl_table_hdr) {
		pr_err("iw_cm: couldn't register sysctl paths\n");
		destroy_workqueue(iwcm_wq);
		return -ENOMEM;
	}

	return 0;
}

static void __exit iw_cm_cleanup(void)
{
	unregister_net_sysctl_table(iwcm_ctl_table_hdr);
	destroy_workqueue(iwcm_wq);
}