aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Dalessandro <dennis.dalessandro@intel.com>2016-05-19 08:25:50 -0400
committerDoug Ledford <dledford@redhat.com>2016-05-26 11:23:17 -0400
commit0eb626590dcf1280c6d01a784e9d53a3de6d5e8e (patch)
treefa8a4b60c2b69da52801b79fa61add9f75da7075
parentf3225c3f1107104f5e143797550476182b844cfb (diff)
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: Dean Luick <dean.luick@intel.com> Reviewed-by: Mitko Haralanov <mitko.haralanov@intel.com> Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/staging/rdma/hfi1/file_ops.c102
-rw-r--r--include/uapi/rdma/hfi/hfi1_user.h19
2 files changed, 21 insertions, 100 deletions
diff --git a/drivers/staging/rdma/hfi1/file_ops.c b/drivers/staging/rdma/hfi1/file_ops.c
index c1c5bf82addb..518cd891b63d 100644
--- a/drivers/staging/rdma/hfi1/file_ops.c
+++ b/drivers/staging/rdma/hfi1/file_ops.c
@@ -86,8 +86,7 @@ static int get_ctxt_info(struct file *, void __user *, __u32);
86static int get_base_info(struct file *, void __user *, __u32); 86static int get_base_info(struct file *, void __user *, __u32);
87static int setup_ctxt(struct file *); 87static int setup_ctxt(struct file *);
88static int setup_subctxt(struct hfi1_ctxtdata *); 88static int setup_subctxt(struct hfi1_ctxtdata *);
89static int get_user_context(struct file *, struct hfi1_user_info *, 89static int get_user_context(struct file *, struct hfi1_user_info *, int);
90 int, unsigned);
91static int find_shared_ctxt(struct file *, const struct hfi1_user_info *); 90static int find_shared_ctxt(struct file *, const struct hfi1_user_info *);
92static int allocate_ctxt(struct file *, struct hfi1_devdata *, 91static int allocate_ctxt(struct file *, struct hfi1_devdata *,
93 struct hfi1_user_info *); 92 struct hfi1_user_info *);
@@ -836,7 +835,7 @@ static u64 kvirt_to_phys(void *addr)
836static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo) 835static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)
837{ 836{
838 int i_minor, ret = 0; 837 int i_minor, ret = 0;
839 unsigned swmajor, swminor, alg = HFI1_ALG_ACROSS; 838 unsigned int swmajor, swminor;
840 839
841 swmajor = uinfo->userversion >> 16; 840 swmajor = uinfo->userversion >> 16;
842 if (swmajor != HFI1_USER_SWMAJOR) { 841 if (swmajor != HFI1_USER_SWMAJOR) {
@@ -846,9 +845,6 @@ static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)
846 845
847 swminor = uinfo->userversion & 0xffff; 846 swminor = uinfo->userversion & 0xffff;
848 847
849 if (uinfo->hfi1_alg < HFI1_ALG_COUNT)
850 alg = uinfo->hfi1_alg;
851
852 mutex_lock(&hfi1_mutex); 848 mutex_lock(&hfi1_mutex);
853 /* First, lets check if we need to setup a shared context? */ 849 /* First, lets check if we need to setup a shared context? */
854 if (uinfo->subctxt_cnt) { 850 if (uinfo->subctxt_cnt) {
@@ -868,7 +864,7 @@ static int assign_ctxt(struct file *fp, struct hfi1_user_info *uinfo)
868 */ 864 */
869 if (!ret) { 865 if (!ret) {
870 i_minor = iminor(file_inode(fp)) - HFI1_USER_MINOR_BASE; 866 i_minor = iminor(file_inode(fp)) - HFI1_USER_MINOR_BASE;
871 ret = get_user_context(fp, uinfo, i_minor - 1, alg); 867 ret = get_user_context(fp, uinfo, i_minor);
872 } 868 }
873done_unlock: 869done_unlock:
874 mutex_unlock(&hfi1_mutex); 870 mutex_unlock(&hfi1_mutex);
@@ -876,71 +872,26 @@ done:
876 return ret; 872 return ret;
877} 873}
878 874
879/* return true if the device available for general use */
880static int usable_device(struct hfi1_devdata *dd)
881{
882 struct hfi1_pportdata *ppd = dd->pport;
883
884 return driver_lstate(ppd) == IB_PORT_ACTIVE;
885}
886
887static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo, 875static int get_user_context(struct file *fp, struct hfi1_user_info *uinfo,
888 int devno, unsigned alg) 876 int devno)
889{ 877{
890 struct hfi1_devdata *dd = NULL; 878 struct hfi1_devdata *dd = NULL;
891 int ret = 0, devmax, npresent, nup, dev; 879 int devmax, npresent, nup;
892 880
893 devmax = hfi1_count_units(&npresent, &nup); 881 devmax = hfi1_count_units(&npresent, &nup);
894 if (!npresent) { 882 if (!npresent)
895 ret = -ENXIO; 883 return -ENXIO;
896 goto done; 884
897 } 885 if (!nup)
898 if (!nup) { 886 return -ENETDOWN;
899 ret = -ENETDOWN; 887
900 goto done; 888 dd = hfi1_lookup(devno);
901 } 889 if (!dd)
902 if (devno >= 0) { 890 return -ENODEV;
903 dd = hfi1_lookup(devno); 891 else if (!dd->freectxts)
904 if (!dd) 892 return -EBUSY;
905 ret = -ENODEV; 893
906 else if (!dd->freectxts) 894 return allocate_ctxt(fp, dd, uinfo);
907 ret = -EBUSY;
908 } else {
909 struct hfi1_devdata *pdd;
910
911 if (alg == HFI1_ALG_ACROSS) {
912 unsigned free = 0U;
913
914 for (dev = 0; dev < devmax; dev++) {
915 pdd = hfi1_lookup(dev);
916 if (!pdd)
917 continue;
918 if (!usable_device(pdd))
919 continue;
920 if (pdd->freectxts &&
921 pdd->freectxts > free) {
922 dd = pdd;
923 free = pdd->freectxts;
924 }
925 }
926 } else {
927 for (dev = 0; dev < devmax; dev++) {
928 pdd = hfi1_lookup(dev);
929 if (!pdd)
930 continue;
931 if (!usable_device(pdd))
932 continue;
933 if (pdd->freectxts) {
934 dd = pdd;
935 break;
936 }
937 }
938 }
939 if (!dd)
940 ret = -EBUSY;
941 }
942done:
943 return ret ? ret : allocate_ctxt(fp, dd, uinfo);
944} 895}
945 896
946static int find_shared_ctxt(struct file *fp, 897static int find_shared_ctxt(struct file *fp,
@@ -1698,15 +1649,8 @@ static const struct file_operations ui_file_ops = {
1698#define UI_OFFSET 192 /* device minor offset for UI devices */ 1649#define UI_OFFSET 192 /* device minor offset for UI devices */
1699static int create_ui = 1; 1650static int create_ui = 1;
1700 1651
1701static struct cdev wildcard_cdev;
1702static struct device *wildcard_device;
1703
1704static atomic_t user_count = ATOMIC_INIT(0);
1705
1706static void user_remove(struct hfi1_devdata *dd) 1652static void user_remove(struct hfi1_devdata *dd)
1707{ 1653{
1708 if (atomic_dec_return(&user_count) == 0)
1709 hfi1_cdev_cleanup(&wildcard_cdev, &wildcard_device);
1710 1654
1711 hfi1_cdev_cleanup(&dd->user_cdev, &dd->user_device); 1655 hfi1_cdev_cleanup(&dd->user_cdev, &dd->user_device);
1712 hfi1_cdev_cleanup(&dd->ui_cdev, &dd->ui_device); 1656 hfi1_cdev_cleanup(&dd->ui_cdev, &dd->ui_device);
@@ -1717,16 +1661,8 @@ static int user_add(struct hfi1_devdata *dd)
1717 char name[10]; 1661 char name[10];
1718 int ret; 1662 int ret;
1719 1663
1720 if (atomic_inc_return(&user_count) == 1) {
1721 ret = hfi1_cdev_init(0, class_name(), &hfi1_file_ops,
1722 &wildcard_cdev, &wildcard_device,
1723 true);
1724 if (ret)
1725 goto done;
1726 }
1727
1728 snprintf(name, sizeof(name), "%s_%d", class_name(), dd->unit); 1664 snprintf(name, sizeof(name), "%s_%d", class_name(), dd->unit);
1729 ret = hfi1_cdev_init(dd->unit + 1, name, &hfi1_file_ops, 1665 ret = hfi1_cdev_init(dd->unit, name, &hfi1_file_ops,
1730 &dd->user_cdev, &dd->user_device, 1666 &dd->user_cdev, &dd->user_device,
1731 true); 1667 true);
1732 if (ret) 1668 if (ret)
diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h
index a533cecab14f..09558999ca1d 100644
--- a/include/uapi/rdma/hfi/hfi1_user.h
+++ b/include/uapi/rdma/hfi/hfi1_user.h
@@ -75,7 +75,7 @@
75 * may not be implemented; the user code must deal with this if it 75 * may not be implemented; the user code must deal with this if it
76 * cares, or it must abort after initialization reports the difference. 76 * cares, or it must abort after initialization reports the difference.
77 */ 77 */
78#define HFI1_USER_SWMINOR 0 78#define HFI1_USER_SWMINOR 1
79 79
80/* 80/*
81 * Set of HW and driver capability/feature bits. 81 * Set of HW and driver capability/feature bits.
@@ -107,19 +107,6 @@
107#define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1) 107#define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1)
108#define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2) 108#define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2)
109 109
110/*
111 * If the unit is specified via open, HFI choice is fixed. If port is
112 * specified, it's also fixed. Otherwise we try to spread contexts
113 * across ports and HFIs, using different algorithms. WITHIN is
114 * the old default, prior to this mechanism.
115 */
116#define HFI1_ALG_ACROSS 0 /* round robin contexts across HFIs, then
117 * ports; this is the default */
118#define HFI1_ALG_WITHIN 1 /* use all contexts on an HFI (round robin
119 * active ports within), then next HFI */
120#define HFI1_ALG_COUNT 2 /* number of algorithm choices */
121
122
123/* User commands. */ 110/* User commands. */
124#define HFI1_CMD_ASSIGN_CTXT 1 /* allocate HFI and context */ 111#define HFI1_CMD_ASSIGN_CTXT 1 /* allocate HFI and context */
125#define HFI1_CMD_CTXT_INFO 2 /* find out what resources we got */ 112#define HFI1_CMD_CTXT_INFO 2 /* find out what resources we got */
@@ -199,9 +186,7 @@ struct hfi1_user_info {
199 * Should be set to HFI1_USER_SWVERSION. 186 * Should be set to HFI1_USER_SWVERSION.
200 */ 187 */
201 __u32 userversion; 188 __u32 userversion;
202 __u16 pad; 189 __u32 pad;
203 /* HFI selection algorithm, if unit has not selected */
204 __u16 hfi1_alg;
205 /* 190 /*
206 * If two or more processes wish to share a context, each process 191 * If two or more processes wish to share a context, each process
207 * must set the subcontext_cnt and subcontext_id to the same 192 * must set the subcontext_cnt and subcontext_id to the same