Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 206742
b: refs/heads/master
c: 7a70081
h: refs/heads/master
v: v3
  • Loading branch information
Bart Van Assche authored and Roland Dreier committed Aug 4, 2010
1 parent 9287e8b commit cf30dfa
Show file tree
Hide file tree
Showing 17 changed files with 173 additions and 197 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ba818afdc62590e95e45d63be96954ea568925bf
refs/heads/master: 7a7008110b94dfaa90db4b0cc5b0c3f964c80506
4 changes: 0 additions & 4 deletions trunk/drivers/infiniband/hw/qib/qib.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/fs.h>
#include <linux/completion.h>
Expand Down Expand Up @@ -327,9 +326,6 @@ struct qib_verbs_txreq {

#define QIB_DEFAULT_MTU 4096

/* max number of IB ports supported per HCA */
#define QIB_MAX_IB_PORTS 2

/*
* Possible IB config parameters for f_get/set_ib_table()
*/
Expand Down
16 changes: 2 additions & 14 deletions trunk/drivers/infiniband/hw/qib/qib_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 11
#define QIB_USER_SWMINOR 10

#define QIB_USER_SWVERSION ((QIB_USER_SWMAJOR << 16) | QIB_USER_SWMINOR)

Expand All @@ -301,18 +301,6 @@ 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
Expand All @@ -331,7 +319,7 @@ struct qib_user_info {
/* size of struct base_info to write to */
__u32 spu_base_info_size;

__u32 spu_port_alg; /* which QIB_PORT_ALG_*; unused user minor < 11 */
__u32 _spu_unused3;

/*
* If two or more processes wish to share a context, each process
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/infiniband/hw/qib/qib_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts)
smp_rmb(); /* prevent speculative reads of dma'ed hdrq */
}

for (last = 0, i = 1; !last && i <= 64; i += !last) {
for (last = 0, i = 1; !last; i += !last) {
hdr = dd->f_get_msgheader(dd, rhf_addr);
eflags = qib_hdrget_err_flags(rhf_addr);
etype = qib_hdrget_rcv_type(rhf_addr);
Expand Down
203 changes: 99 additions & 104 deletions trunk/drivers/infiniband/hw/qib/qib_file_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1294,130 +1294,128 @@ static int setup_ctxt(struct qib_pportdata *ppd, int ctxt,
return ret;
}

static inline int usable(struct qib_pportdata *ppd)
static inline int usable(struct qib_pportdata *ppd, int active_only)
{
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 & QIBL_LINKACTIVE);
}

/*
* 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_pportdata *ppd = NULL;
int ret, ctxt;

if (port) {
if (!usable(dd->pport + port - 1)) {
ret = -ENETDOWN;
goto done;
} else
ppd = dd->pport + port - 1;
}
for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts && dd->rcd[ctxt];
ctxt++)
;
if (ctxt == dd->cfgctxts) {
ret = -EBUSY;
goto done;
}
if (!ppd) {
u32 pidx = ctxt % dd->num_pports;
if (usable(dd->pport + pidx))
ppd = dd->pport + pidx;
else {
for (pidx = 0; pidx < dd->num_pports && !ppd;
pidx++)
if (usable(dd->pport + pidx))
ppd = dd->pport + pidx;
}
}
ret = ppd ? setup_ctxt(ppd, ctxt, fp, uinfo) : -ENETDOWN;
done:
return ret;
(ppd->lflags & linkok);
}

static int find_free_ctxt(int unit, struct file *fp,
const struct qib_user_info *uinfo)
{
struct qib_devdata *dd = qib_lookup(unit);
struct qib_pportdata *ppd = NULL;
int ret;
u32 ctxt;

if (!dd || (uinfo->spu_port && uinfo->spu_port > dd->num_pports))
if (!dd || (uinfo->spu_port && uinfo->spu_port > dd->num_pports)) {
ret = -ENODEV;
else
ret = choose_port_ctxt(fp, dd, uinfo->spu_port, uinfo);
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)) {
ret = -ENETDOWN;
goto bail;
}
}

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))
break;
}
if (i == dd->num_pports) {
ret = -ENETDOWN;
goto bail;
}
}
}
ret = setup_ctxt(ppd, ctxt, fp, uinfo);
goto bail;
}
ret = -EBUSY;

bail:
return ret;
}

static int get_a_ctxt(struct file *fp, const struct qib_user_info *uinfo,
unsigned alg)
static int get_a_ctxt(struct file *fp, const struct qib_user_info *uinfo)
{
struct qib_devdata *udd = NULL;
int ret = 0, devmax, npresent, nup, ndev, dusable = 0, i;
struct qib_pportdata *ppd;
int ret = 0, devmax;
int npresent, nup;
int ndev;
u32 port = uinfo->spu_port, ctxt;

devmax = qib_count_units(&npresent, &nup);
if (!npresent) {
ret = -ENXIO;
goto done;
}
if (nup == 0) {
ret = -ENETDOWN;
goto done;
}

if (alg == QIB_PORT_ALG_ACROSS) {
unsigned inuse = ~0U;
/* find device (with ACTIVE ports) with fewest ctxts in use */
for (ndev = 0; ndev < devmax; ndev++) {
struct qib_devdata *dd = qib_lookup(ndev);
unsigned cused = 0, cfree = 0;
if (!dd)
continue;
if (port && port <= dd->num_pports &&
usable(dd->pport + port - 1))
dusable = 1;
else
for (i = 0; i < dd->num_pports; i++)
if (usable(dd->pport + i))
dusable++;
if (!dusable)
for (ndev = 0; ndev < devmax; ndev++) {
struct qib_devdata *dd = qib_lookup(ndev);

/* device portion of usable() */
if (!(dd && (dd->flags & QIB_PRESENT) && dd->kregbase))
continue;
for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts; ctxt++) {
if (dd->rcd[ctxt])
continue;
for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts;
ctxt++)
if (dd->rcd[ctxt])
cused++;
else
cfree++;
if (cfree && cused < inuse) {
udd = dd;
inuse = cused;
if (port) {
if (port > dd->num_pports)
continue;
ppd = dd->pport + port - 1;
if (!usable(ppd, 0))
continue;
} else {
/*
* choose port based on ctxt, if up, else
* first port that's up for multi-port HCA
*/
ppd = dd->pport + (ctxt % dd->num_pports);
if (!usable(ppd, 0)) {
int j;

ppd = NULL;
for (j = 0; j < dd->num_pports &&
!ppd; j++)
if (usable(dd->pport + j, 0))
ppd = dd->pport + j;
if (!ppd)
continue; /* to next unit */
}
}
}
if (udd) {
ret = choose_port_ctxt(fp, udd, port, uinfo);
ret = setup_ctxt(ppd, ctxt, fp, uinfo);
goto done;
}
} else {
for (ndev = 0; ndev < devmax; ndev++) {
struct qib_devdata *dd = qib_lookup(ndev);
if (dd) {
ret = choose_port_ctxt(fp, dd, port, uinfo);
if (!ret)
goto done;
if (ret == -EBUSY)
dusable++;
}
}
}
ret = dusable ? -EBUSY : -ENETDOWN;

if (npresent) {
if (nup == 0)
ret = -ENETDOWN;
else
ret = -EBUSY;
} else
ret = -ENXIO;

done:
return ret;
Expand Down Expand Up @@ -1483,7 +1481,7 @@ static int qib_assign_ctxt(struct file *fp, const struct qib_user_info *uinfo)
{
int ret;
int i_minor;
unsigned swmajor, swminor, alg = QIB_PORT_ALG_ACROSS;
unsigned swmajor, swminor;

/* Check to be sure we haven't already initialized this file */
if (ctxt_fp(fp)) {
Expand All @@ -1500,9 +1498,6 @@ static int qib_assign_ctxt(struct file *fp, const struct qib_user_info *uinfo)

swminor = uinfo->spu_userversion & 0xffff;

if (swminor >= 11 && uinfo->spu_port_alg < QIB_PORT_ALG_COUNT)
alg = uinfo->spu_port_alg;

mutex_lock(&qib_mutex);

if (qib_compatible_subctxts(swmajor, swminor) &&
Expand All @@ -1519,7 +1514,7 @@ static int qib_assign_ctxt(struct file *fp, const struct qib_user_info *uinfo)
if (i_minor)
ret = find_free_ctxt(i_minor - 1, fp, uinfo);
else
ret = get_a_ctxt(fp, uinfo, alg);
ret = get_a_ctxt(fp, uinfo);

done_chk_sdma:
if (!ret) {
Expand Down Expand Up @@ -1867,7 +1862,7 @@ static int disarm_req_delay(struct qib_ctxtdata *rcd)
{
int ret = 0;

if (!usable(rcd->ppd)) {
if (!usable(rcd->ppd, 1)) {
int i;
/*
* if link is down, or otherwise not usable, delay
Expand All @@ -1886,7 +1881,7 @@ static int disarm_req_delay(struct qib_ctxtdata *rcd)
set_bit(_QIB_EVENT_DISARM_BUFS_BIT,
&rcd->user_event_mask[i]);
}
for (i = 0; !usable(rcd->ppd) && i < 300; i++)
for (i = 0; !usable(rcd->ppd, 1) && i < 300; i++)
msleep(100);
ret = -ENETDOWN;
}
Expand Down
18 changes: 9 additions & 9 deletions trunk/drivers/infiniband/hw/qib/qib_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ static ssize_t driver_names_read(struct file *file, char __user *buf,
}

static const struct file_operations driver_ops[] = {
{ .read = driver_stats_read, .llseek = generic_file_llseek, },
{ .read = driver_names_read, .llseek = generic_file_llseek, },
{ .read = driver_stats_read, },
{ .read = driver_names_read, },
};

/* read the per-device counters */
Expand Down Expand Up @@ -164,8 +164,8 @@ static ssize_t dev_names_read(struct file *file, char __user *buf,
}

static const struct file_operations cntr_ops[] = {
{ .read = dev_counters_read, .llseek = generic_file_llseek, },
{ .read = dev_names_read, .llseek = generic_file_llseek, },
{ .read = dev_counters_read, },
{ .read = dev_names_read, },
};

/*
Expand Down Expand Up @@ -210,9 +210,9 @@ static ssize_t portcntrs_2_read(struct file *file, char __user *buf,
}

static const struct file_operations portcntr_ops[] = {
{ .read = portnames_read, .llseek = generic_file_llseek, },
{ .read = portcntrs_1_read, .llseek = generic_file_llseek, },
{ .read = portcntrs_2_read, .llseek = generic_file_llseek, },
{ .read = portnames_read, },
{ .read = portcntrs_1_read, },
{ .read = portcntrs_2_read, },
};

/*
Expand Down Expand Up @@ -261,8 +261,8 @@ static ssize_t qsfp_2_read(struct file *file, char __user *buf,
}

static const struct file_operations qsfp_ops[] = {
{ .read = qsfp_1_read, .llseek = generic_file_llseek, },
{ .read = qsfp_2_read, .llseek = generic_file_llseek, },
{ .read = qsfp_1_read, },
{ .read = qsfp_2_read, },
};

static ssize_t flash_read(struct file *file, char __user *buf,
Expand Down
Loading

0 comments on commit cf30dfa

Please sign in to comment.