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

Commit 0eb62659 authored by Dennis Dalessandro's avatar Dennis Dalessandro Committed by Doug Ledford
Browse files

IB/hfi1: Remove multiple device cdev



hfi1 current exports a cdev that can be used to target all of the hfi's
in the system. However there is a problem with this approach in
that the devices could be on different subnets. This is a problem that
user space can figure out and explicitly tell the driver on which device
to create a context.

Remove the multi-purpose cdev leaving a dedicated cdev for each port.
Also remove the striping capability that is dependent upon the user
choosing the multi-purpose cdev. It is now up to user space to determine
how to stripe contexts.

Reviewed-by: default avatarDean Luick <dean.luick@intel.com>
Reviewed-by: default avatarMitko Haralanov <mitko.haralanov@intel.com>
Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Reviewed-by: default avatarIra Weiny <ira.weiny@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent f3225c3f
Loading
Loading
Loading
Loading
+19 −83
Original line number Original line Diff line number Diff line
@@ -86,8 +86,7 @@ static int get_ctxt_info(struct file *, void __user *, __u32);
static int get_base_info(struct file *, void __user *, __u32);
static int get_base_info(struct file *, void __user *, __u32);
static int setup_ctxt(struct file *);
static int setup_ctxt(struct file *);
static int setup_subctxt(struct hfi1_ctxtdata *);
static int setup_subctxt(struct hfi1_ctxtdata *);
static int get_user_context(struct file *, struct hfi1_user_info *,
static int get_user_context(struct file *, struct hfi1_user_info *, int);
			    int, unsigned);
static int find_shared_ctxt(struct file *, const struct hfi1_user_info *);
static int find_shared_ctxt(struct file *, const struct hfi1_user_info *);
static int allocate_ctxt(struct file *, struct hfi1_devdata *,
static int allocate_ctxt(struct file *, struct hfi1_devdata *,
			 struct hfi1_user_info *);
			 struct hfi1_user_info *);
@@ -836,7 +835,7 @@ static u64 kvirt_to_phys(void *addr)
static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)
static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)
{
{
	int i_minor, ret = 0;
	int i_minor, ret = 0;
	unsigned swmajor, swminor, alg = HFI1_ALG_ACROSS;
	unsigned int swmajor, swminor;


	swmajor = uinfo->userversion >> 16;
	swmajor = uinfo->userversion >> 16;
	if (swmajor != HFI1_USER_SWMAJOR) {
	if (swmajor != HFI1_USER_SWMAJOR) {
@@ -846,9 +845,6 @@ static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)


	swminor = uinfo->userversion & 0xffff;
	swminor = uinfo->userversion & 0xffff;


	if (uinfo->hfi1_alg < HFI1_ALG_COUNT)
		alg = uinfo->hfi1_alg;

	mutex_lock(&hfi1_mutex);
	mutex_lock(&hfi1_mutex);
	/* First, lets check if we need to setup a shared context? */
	/* First, lets check if we need to setup a shared context? */
	if (uinfo->subctxt_cnt) {
	if (uinfo->subctxt_cnt) {
@@ -868,7 +864,7 @@ static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)
	 */
	 */
	if (!ret) {
	if (!ret) {
		i_minor = iminor(file_inode(fp)) - HFI1_USER_MINOR_BASE;
		i_minor = iminor(file_inode(fp)) - HFI1_USER_MINOR_BASE;
		ret = get_user_context(fp, uinfo, i_minor - 1, alg);
		ret = get_user_context(fp, uinfo, i_minor);
	}
	}
done_unlock:
done_unlock:
	mutex_unlock(&hfi1_mutex);
	mutex_unlock(&hfi1_mutex);
@@ -876,71 +872,26 @@ static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)
	return ret;
	return ret;
}
}


/* return true if the device available for general use */
static int usable_device(struct hfi1_devdata *dd)
{
	struct hfi1_pportdata *ppd = dd->pport;

	return driver_lstate(ppd) == IB_PORT_ACTIVE;
}

static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo,
static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo,
			    int devno, unsigned alg)
			    int devno)
{
{
	struct hfi1_devdata *dd = NULL;
	struct hfi1_devdata *dd = NULL;
	int ret = 0, devmax, npresent, nup, dev;
	int devmax, npresent, nup;


	devmax = hfi1_count_units(&npresent, &nup);
	devmax = hfi1_count_units(&npresent, &nup);
	if (!npresent) {
	if (!npresent)
		ret = -ENXIO;
		return -ENXIO;
		goto done;

	}
	if (!nup)
	if (!nup) {
		return -ENETDOWN;
		ret = -ENETDOWN;

		goto done;
	}
	if (devno >= 0) {
	dd = hfi1_lookup(devno);
	dd = hfi1_lookup(devno);
	if (!dd)
	if (!dd)
			ret = -ENODEV;
		return -ENODEV;
	else if (!dd->freectxts)
	else if (!dd->freectxts)
			ret = -EBUSY;
		return -EBUSY;
	} else {
		struct hfi1_devdata *pdd;

		if (alg == HFI1_ALG_ACROSS) {
			unsigned free = 0U;


			for (dev = 0; dev < devmax; dev++) {
	return allocate_ctxt(fp, dd, uinfo);
				pdd = hfi1_lookup(dev);
				if (!pdd)
					continue;
				if (!usable_device(pdd))
					continue;
				if (pdd->freectxts &&
				    pdd->freectxts > free) {
					dd = pdd;
					free = pdd->freectxts;
				}
			}
		} else {
			for (dev = 0; dev < devmax; dev++) {
				pdd = hfi1_lookup(dev);
				if (!pdd)
					continue;
				if (!usable_device(pdd))
					continue;
				if (pdd->freectxts) {
					dd = pdd;
					break;
				}
			}
		}
		if (!dd)
			ret = -EBUSY;
	}
done:
	return ret ? ret : allocate_ctxt(fp, dd, uinfo);
}
}


static int find_shared_ctxt(struct file *fp,
static int find_shared_ctxt(struct file *fp,
@@ -1698,15 +1649,8 @@ static const struct file_operations ui_file_ops = {
#define UI_OFFSET 192	/* device minor offset for UI devices */
#define UI_OFFSET 192	/* device minor offset for UI devices */
static int create_ui = 1;
static int create_ui = 1;


static struct cdev wildcard_cdev;
static struct device *wildcard_device;

static atomic_t user_count = ATOMIC_INIT(0);

static void user_remove(struct hfi1_devdata *dd)
static void user_remove(struct hfi1_devdata *dd)
{
{
	if (atomic_dec_return(&user_count) == 0)
		hfi1_cdev_cleanup(&wildcard_cdev, &wildcard_device);


	hfi1_cdev_cleanup(&dd->user_cdev, &dd->user_device);
	hfi1_cdev_cleanup(&dd->user_cdev, &dd->user_device);
	hfi1_cdev_cleanup(&dd->ui_cdev, &dd->ui_device);
	hfi1_cdev_cleanup(&dd->ui_cdev, &dd->ui_device);
@@ -1717,16 +1661,8 @@ static int user_add(struct hfi1_devdata *dd)
	char name[10];
	char name[10];
	int ret;
	int ret;


	if (atomic_inc_return(&user_count) == 1) {
		ret = hfi1_cdev_init(0, class_name(), &hfi1_file_ops,
				     &wildcard_cdev, &wildcard_device,
				     true);
		if (ret)
			goto done;
	}

	snprintf(name, sizeof(name), "%s_%d", class_name(), dd->unit);
	snprintf(name, sizeof(name), "%s_%d", class_name(), dd->unit);
	ret = hfi1_cdev_init(dd->unit + 1, name, &hfi1_file_ops,
	ret = hfi1_cdev_init(dd->unit, name, &hfi1_file_ops,
			     &dd->user_cdev, &dd->user_device,
			     &dd->user_cdev, &dd->user_device,
			     true);
			     true);
	if (ret)
	if (ret)
+2 −17
Original line number Original line Diff line number Diff line
@@ -75,7 +75,7 @@
 * may not be implemented; the user code must deal with this if it
 * may not be implemented; the user code must deal with this if it
 * cares, or it must abort after initialization reports the difference.
 * cares, or it must abort after initialization reports the difference.
 */
 */
#define HFI1_USER_SWMINOR 0
#define HFI1_USER_SWMINOR 1


/*
/*
 * Set of HW and driver capability/feature bits.
 * Set of HW and driver capability/feature bits.
@@ -107,19 +107,6 @@
#define HFI1_RCVHDR_ENTSIZE_16   (1UL << 1)
#define HFI1_RCVHDR_ENTSIZE_16   (1UL << 1)
#define HFI1_RCVDHR_ENTSIZE_32   (1UL << 2)
#define HFI1_RCVDHR_ENTSIZE_32   (1UL << 2)


/*
 * If the unit is specified via open, HFI choice is fixed.  If port is
 * specified, it's also fixed.  Otherwise we try to spread contexts
 * across ports and HFIs, using different algorithms.  WITHIN is
 * the old default, prior to this mechanism.
 */
#define HFI1_ALG_ACROSS 0 /* round robin contexts across HFIs, then
			  * ports; this is the default */
#define HFI1_ALG_WITHIN 1 /* use all contexts on an HFI (round robin
			  * active ports within), then next HFI */
#define HFI1_ALG_COUNT  2 /* number of algorithm choices */


/* User commands. */
/* User commands. */
#define HFI1_CMD_ASSIGN_CTXT     1	/* allocate HFI and context */
#define HFI1_CMD_ASSIGN_CTXT     1	/* allocate HFI and context */
#define HFI1_CMD_CTXT_INFO       2	/* find out what resources we got */
#define HFI1_CMD_CTXT_INFO       2	/* find out what resources we got */
@@ -199,9 +186,7 @@ struct hfi1_user_info {
	 * Should be set to HFI1_USER_SWVERSION.
	 * Should be set to HFI1_USER_SWVERSION.
	 */
	 */
	__u32 userversion;
	__u32 userversion;
	__u16 pad;
	__u32 pad;
	/* HFI selection algorithm, if unit has not selected */
	__u16 hfi1_alg;
	/*
	/*
	 * If two or more processes wish to share a context, each process
	 * If two or more processes wish to share a context, each process
	 * must set the subcontext_cnt and subcontext_id to the same
	 * must set the subcontext_cnt and subcontext_id to the same