Re: [PATCH 2/7] IB/qib: allow PSM to select from multiple port assignment algorithms

2010-07-21 Thread Roland Dreier
thanks, applied
-- 
Roland Dreier  || For corporate legal information go to:
http://www.cisco.com/web/about/doing_business/legal/cri/index.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/7] IB/qib: allow PSM to select from multiple port assignment algorithms

2010-06-17 Thread Ralph Campbell
From: Dave Olson 

We formerly allowed only full specification, or using all contexts
within an HCA before moving to the next HCA.  We now allow an additional
method, of round-robining through HCAs, and make that the default.

Signed-off-by: Dave Olson 
---

 drivers/infiniband/hw/qib/qib_common.h   |   16 ++
 drivers/infiniband/hw/qib/qib_file_ops.c |  203 +++---
 2 files changed, 118 insertions(+), 101 deletions(-)

diff --git a/drivers/infiniband/hw/qib/qib_common.h 
b/drivers/infiniband/hw/qib/qib_common.h
index b3955ed..145da40 100644
--- a/drivers/infiniband/hw/qib/qib_common.h
+++ b/drivers/infiniband/hw/qib/qib_common.h
@@ -279,7 +279,7 @@ struct qib_base_info {
  * may not be implemented; the user code must deal with this if it
  * cares, or it must abort after initialization reports the difference.
  */
-#define QIB_USER_SWMINOR 10
+#define QIB_USER_SWMINOR 11
 
 #define QIB_USER_SWVERSION ((QIB_USER_SWMAJOR << 16) | QIB_USER_SWMINOR)
 
@@ -302,6 +302,18 @@ struct qib_base_info {
 #define QIB_KERN_SWVERSION ((QIB_KERN_TYPE << 31) | QIB_USER_SWVERSION)
 
 /*
+ * If the unit is specified via open, HCA choice is fixed.  If port is
+ * specified, it's also fixed.  Otherwise we try to spread contexts
+ * across ports and HCAs, using different algorithims.  WITHIN is
+ * the old default, prior to this mechanism.
+ */
+#define QIB_PORT_ALG_ACROSS 0 /* round robin contexts across HCAs, then
+  * ports; this is the default */
+#define QIB_PORT_ALG_WITHIN 1 /* use all contexts on an HCA (round robin
+  * active ports within), then next HCA */
+#define QIB_PORT_ALG_COUNT 2 /* number of algorithm choices */
+
+/*
  * This structure is passed to qib_userinit() to tell the driver where
  * user code buffers are, sizes, etc.   The offsets and sizes of the
  * fields must remain unchanged, for binary compatibility.  It can
@@ -319,7 +331,7 @@ struct qib_user_info {
/* size of struct base_info to write to */
__u32 spu_base_info_size;
 
-   __u32 _spu_unused3;
+   __u32 spu_port_alg; /* which QIB_PORT_ALG_*; unused user minor < 11 */
 
/*
 * If two or more processes wish to share a context, each process
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c 
b/drivers/infiniband/hw/qib/qib_file_ops.c
index a142a9e..6b11645 100644
--- a/drivers/infiniband/hw/qib/qib_file_ops.c
+++ b/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -1294,128 +1294,130 @@ bail:
return ret;
 }
 
-static inline int usable(struct qib_pportdata *ppd, int active_only)
+static inline int usable(struct qib_pportdata *ppd)
 {
struct qib_devdata *dd = ppd->dd;
-   u32 linkok = active_only ? QIBL_LINKACTIVE :
-(QIBL_LINKINIT | QIBL_LINKARMED | QIBL_LINKACTIVE);
 
return dd && (dd->flags & QIB_PRESENT) && dd->kregbase && ppd->lid &&
-   (ppd->lflags & linkok);
+   (ppd->lflags & QIBL_LINKACTIVE);
 }
 
-static int find_free_ctxt(int unit, struct file *fp,
- const struct qib_user_info *uinfo)
+/*
+ * Select a context on the given device, either using a requested port
+ * or the port based on the context number.
+ */
+static int choose_port_ctxt(struct file *fp, struct qib_devdata *dd, u32 port,
+   const struct qib_user_info *uinfo)
 {
-   struct qib_devdata *dd = qib_lookup(unit);
struct qib_pportdata *ppd = NULL;
-   int ret;
-   u32 ctxt;
+   int ret, ctxt;
 
-   if (!dd || (uinfo->spu_port && uinfo->spu_port > dd->num_pports)) {
-   ret = -ENODEV;
-   goto bail;
-   }
-
-   /*
-* If users requests specific port, only try that one port, else
-* select "best" port below, based on context.
-*/
-   if (uinfo->spu_port) {
-   ppd = dd->pport + uinfo->spu_port - 1;
-   if (!usable(ppd, 0)) {
+   if (port) {
+   if (!usable(dd->pport + port - 1)) {
ret = -ENETDOWN;
-   goto bail;
-   }
+   goto done;
+   } else
+   ppd = dd->pport + port - 1;
}
-
-   for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts; ctxt++) {
-   if (dd->rcd[ctxt])
-   continue;
-   /*
-* The setting and clearing of user context rcd[x] protected
-* by the qib_mutex
-*/
-   if (!ppd) {
-   /* choose port based on ctxt, if up, else 1st up */
-   ppd = dd->pport + (ctxt % dd->num_pports);
-   if (!usable(ppd, 0)) {
-   int i;
-   for (i = 0; i < dd->num_pports; i++) {
-   ppd = dd->pport + i;
-   if (usable(ppd, 0))
-