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

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
...@@ -86,8 +86,7 @@ static int get_ctxt_info(struct file *, void __user *, __u32); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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; dd = hfi1_lookup(devno);
} if (!dd)
if (devno >= 0) { return -ENODEV;
dd = hfi1_lookup(devno); else if (!dd->freectxts)
if (!dd) return -EBUSY;
ret = -ENODEV;
else if (!dd->freectxts) return allocate_ctxt(fp, dd, uinfo);
ret = -EBUSY;
} else {
struct hfi1_devdata *pdd;
if (alg == HFI1_ALG_ACROSS) {
unsigned free = 0U;
for (dev = 0; dev < devmax; dev++) {
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 = { ...@@ -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) ...@@ -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)
......
...@@ -75,7 +75,7 @@ ...@@ -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 @@ ...@@ -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 { ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment