2006-05-23 18:34:07

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 0 of 10] ipath patches for 2.6.17

Hi, Roland -

Here are some patches for 2.6.17. They all fix kernel or userspace
crasher bugs. I may have a few more for you in a while, too.

Regards,

<b


2006-05-23 18:34:01

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 7 of 10] ipath - enable PE800 receive interrupts on user ports

Fixed so it works on the PE-800. It had not previously been updated to
match PE-800 receive interrupt differences from HT-400.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r 5d7e365286b3 -r 8d87788e21b1 drivers/infiniband/hw/ipath/ipath_file_ops.c
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c Tue May 23 11:29:16 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c Tue May 23 11:29:16 2006 -0700
@@ -1224,6 +1224,10 @@ static unsigned int ipath_poll(struct fi

if (tail == head) {
set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
+ if(dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
+ (void)ipath_write_ureg(dd, ur_rcvhdrhead,
+ dd->ipath_rhdrhead_intr_off
+ | head, pd->port_port);
poll_wait(fp, &pd->port_wait, pt);

if (test_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag)) {

2006-05-23 18:34:06

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 10 of 10] ipath - deref correct pointer when using kernel SMA

At this point, the core QP structure hasn't been initialized, so what's
in there isn't valid. Get the same information elsewhere.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r 3d844dee2f61 -r c892bcb21ac1 drivers/infiniband/hw/ipath/ipath_qp.c
--- a/drivers/infiniband/hw/ipath/ipath_qp.c Tue May 23 11:29:16 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c Tue May 23 11:29:16 2006 -0700
@@ -734,7 +734,7 @@ struct ib_qp *ipath_create_qp(struct ib_
ipath_reset_qp(qp);

/* Tell the core driver that the kernel SMA is present. */
- if (qp->ibqp.qp_type == IB_QPT_SMI)
+ if (init_attr->qp_type == IB_QPT_SMI)
ipath_layer_set_verbs_flags(dev->dd,
IPATH_VERBS_KERNEL_SMA);
break;

2006-05-23 18:33:36

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 3 of 10] ipath - fix reporting of driver version to userspace

Fix the interface version that gets exported to userspace.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r bb640dcf4d9d -r 386fe7306b31 drivers/infiniband/hw/ipath/ipath_file_ops.c
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c Tue May 23 11:29:15 2006 -0700
@@ -139,7 +139,7 @@ static int ipath_get_base_info(struct ip
kinfo->spi_piosize = dd->ipath_ibmaxlen;
kinfo->spi_mtu = dd->ipath_ibmaxlen; /* maxlen, not ibmtu */
kinfo->spi_port = pd->port_port;
- kinfo->spi_sw_version = IPATH_USER_SWVERSION;
+ kinfo->spi_sw_version = IPATH_KERN_SWVERSION;
kinfo->spi_hw_version = dd->ipath_revision;

if (copy_to_user(ubase, kinfo, sizeof(*kinfo)))

2006-05-23 18:33:36

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 1 of 10] ipath - fix spinlock recursion bug

The local loopback path for RC can lock the rkey table lock without
blocking interrupts. The receive interrupt path can then call
ipath_rkey_ok() and deadlock. Remove the redundant lock.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r abcc41d46f4c -r bc968dacc860 drivers/infiniband/hw/ipath/ipath_keys.c
--- a/drivers/infiniband/hw/ipath/ipath_keys.c Tue May 23 11:29:11 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_keys.c Tue May 23 11:29:15 2006 -0700
@@ -136,9 +136,7 @@ int ipath_lkey_ok(struct ipath_lkey_tabl
ret = 1;
goto bail;
}
- spin_lock(&rkt->lock);
mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))];
- spin_unlock(&rkt->lock);
if (unlikely(mr == NULL || mr->lkey != sge->lkey)) {
ret = 0;
goto bail;
@@ -184,8 +182,6 @@ bail:
* @acc: access flags
*
* Return 1 if successful, otherwise 0.
- *
- * The QP r_rq.lock should be held.
*/
int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
u32 len, u64 vaddr, u32 rkey, int acc)
@@ -196,9 +192,7 @@ int ipath_rkey_ok(struct ipath_ibdev *de
size_t off;
int ret;

- spin_lock(&rkt->lock);
mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
- spin_unlock(&rkt->lock);
if (unlikely(mr == NULL || mr->lkey != rkey)) {
ret = 0;
goto bail;

2006-05-23 18:34:08

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 2 of 10] ipath - don't modify QP if changes fail

Make sure modify_qp won't modify the QP if any of the changes failed.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r bc968dacc860 -r bb640dcf4d9d drivers/infiniband/hw/ipath/ipath_qp.c
--- a/drivers/infiniband/hw/ipath/ipath_qp.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c Tue May 23 11:29:15 2006 -0700
@@ -427,6 +427,7 @@ int ipath_modify_qp(struct ib_qp *ibqp,
int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
int attr_mask)
{
+ struct ipath_ibdev *dev = to_idev(ibqp->device);
struct ipath_qp *qp = to_iqp(ibqp);
enum ib_qp_state cur_state, new_state;
unsigned long flags;
@@ -443,6 +444,19 @@ int ipath_modify_qp(struct ib_qp *ibqp,
attr_mask))
goto inval;

+ if (attr_mask & IB_QP_AV)
+ if (attr->ah_attr.dlid == 0 ||
+ attr->ah_attr.dlid >= IPS_MULTICAST_LID_BASE)
+ goto inval;
+
+ if (attr_mask & IB_QP_PKEY_INDEX)
+ if (attr->pkey_index >= ipath_layer_get_npkeys(dev->dd))
+ goto inval;
+
+ if (attr_mask & IB_QP_MIN_RNR_TIMER)
+ if (attr->min_rnr_timer > 31)
+ goto inval;
+
switch (new_state) {
case IB_QPS_RESET:
ipath_reset_qp(qp);
@@ -457,13 +471,8 @@ int ipath_modify_qp(struct ib_qp *ibqp,

}

- if (attr_mask & IB_QP_PKEY_INDEX) {
- struct ipath_ibdev *dev = to_idev(ibqp->device);
-
- if (attr->pkey_index >= ipath_layer_get_npkeys(dev->dd))
- goto inval;
+ if (attr_mask & IB_QP_PKEY_INDEX)
qp->s_pkey_index = attr->pkey_index;
- }

if (attr_mask & IB_QP_DEST_QPN)
qp->remote_qpn = attr->dest_qp_num;
@@ -479,12 +488,8 @@ int ipath_modify_qp(struct ib_qp *ibqp,
if (attr_mask & IB_QP_ACCESS_FLAGS)
qp->qp_access_flags = attr->qp_access_flags;

- if (attr_mask & IB_QP_AV) {
- if (attr->ah_attr.dlid == 0 ||
- attr->ah_attr.dlid >= IPS_MULTICAST_LID_BASE)
- goto inval;
+ if (attr_mask & IB_QP_AV)
qp->remote_ah_attr = attr->ah_attr;
- }

if (attr_mask & IB_QP_PATH_MTU)
qp->path_mtu = attr->path_mtu;
@@ -499,11 +504,8 @@ int ipath_modify_qp(struct ib_qp *ibqp,
qp->s_rnr_retry_cnt = qp->s_rnr_retry;
}

- if (attr_mask & IB_QP_MIN_RNR_TIMER) {
- if (attr->min_rnr_timer > 31)
- goto inval;
+ if (attr_mask & IB_QP_MIN_RNR_TIMER)
qp->s_min_rnr_timer = attr->min_rnr_timer;
- }

if (attr_mask & IB_QP_QKEY)
qp->qkey = attr->qkey;

2006-05-23 18:34:07

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 8 of 10] ipath - register as IB device owner

This fixes an oops.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r 8d87788e21b1 -r 551717ecc3db drivers/infiniband/hw/ipath/ipath_verbs.c
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c Tue May 23 11:29:16 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c Tue May 23 11:29:16 2006 -0700
@@ -951,6 +951,7 @@ static void *ipath_register_ib_device(in
idev->dd = dd;

strlcpy(dev->name, "ipath%d", IB_DEVICE_NAME_MAX);
+ dev->owner = THIS_MODULE;
dev->node_guid = ipath_layer_get_guid(dd);
dev->uverbs_abi_ver = IPATH_UVERBS_ABI_VERSION;
dev->uverbs_cmd_mask =

2006-05-23 18:34:08

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 5 of 10] ipath - fix NULL dereference during cleanup

Fix NULL deref due to pcidev being clobbered before dd->ipath_f_cleanup()
was called.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r c7cf56636dd1 -r 6bf52c0f0f0d drivers/infiniband/hw/ipath/ipath_driver.c
--- a/drivers/infiniband/hw/ipath/ipath_driver.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c Tue May 23 11:29:15 2006 -0700
@@ -1905,19 +1905,19 @@ static void __exit infinipath_cleanup(vo
} else
ipath_dbg("irq is 0, not doing free_irq "
"for unit %u\n", dd->ipath_unit);
+
+ /*
+ * we check for NULL here, because it's outside
+ * the kregbase check, and we need to call it
+ * after the free_irq. Thus it's possible that
+ * the function pointers were never initialized.
+ */
+ if (dd->ipath_f_cleanup)
+ /* clean up chip-specific stuff */
+ dd->ipath_f_cleanup(dd);
+
dd->pcidev = NULL;
}
-
- /*
- * we check for NULL here, because it's outside the kregbase
- * check, and we need to call it after the free_irq. Thus
- * it's possible that the function pointers were never
- * initialized.
- */
- if (dd->ipath_f_cleanup)
- /* clean up chip-specific stuff */
- dd->ipath_f_cleanup(dd);
-
spin_lock_irqsave(&ipath_devs_lock, flags);
}

2006-05-23 18:34:07

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 4 of 10] ipath - replace uses of LIST_POISON

Per Andrew's request.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r 386fe7306b31 -r c7cf56636dd1 drivers/infiniband/hw/ipath/ipath_qp.c
--- a/drivers/infiniband/hw/ipath/ipath_qp.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c Tue May 23 11:29:15 2006 -0700
@@ -375,10 +375,10 @@ static void ipath_error_qp(struct ipath_

spin_lock(&dev->pending_lock);
/* XXX What if its already removed by the timeout code? */
- if (qp->timerwait.next != LIST_POISON1)
- list_del(&qp->timerwait);
- if (qp->piowait.next != LIST_POISON1)
- list_del(&qp->piowait);
+ if (!list_empty(&qp->timerwait))
+ list_del_init(&qp->timerwait);
+ if (!list_empty(&qp->piowait))
+ list_del_init(&qp->piowait);
spin_unlock(&dev->pending_lock);

wc.status = IB_WC_WR_FLUSH_ERR;
@@ -712,10 +712,8 @@ struct ib_qp *ipath_create_qp(struct ib_
init_attr->qp_type == IB_QPT_RC ?
ipath_do_rc_send : ipath_do_uc_send,
(unsigned long)qp);
- qp->piowait.next = LIST_POISON1;
- qp->piowait.prev = LIST_POISON2;
- qp->timerwait.next = LIST_POISON1;
- qp->timerwait.prev = LIST_POISON2;
+ INIT_LIST_HEAD(&qp->piowait);
+ INIT_LIST_HEAD(&qp->timerwait);
qp->state = IB_QPS_RESET;
qp->s_wq = swq;
qp->s_size = init_attr->cap.max_send_wr + 1;
@@ -785,10 +783,10 @@ int ipath_destroy_qp(struct ib_qp *ibqp)

/* Make sure the QP isn't on the timeout list. */
spin_lock_irqsave(&dev->pending_lock, flags);
- if (qp->timerwait.next != LIST_POISON1)
- list_del(&qp->timerwait);
- if (qp->piowait.next != LIST_POISON1)
- list_del(&qp->piowait);
+ if (!list_empty(&qp->timerwait))
+ list_del_init(&qp->timerwait);
+ if (!list_empty(&qp->piowait))
+ list_del_init(&qp->piowait);
spin_unlock_irqrestore(&dev->pending_lock, flags);

/*
@@ -857,10 +855,10 @@ void ipath_sqerror_qp(struct ipath_qp *q

spin_lock(&dev->pending_lock);
/* XXX What if its already removed by the timeout code? */
- if (qp->timerwait.next != LIST_POISON1)
- list_del(&qp->timerwait);
- if (qp->piowait.next != LIST_POISON1)
- list_del(&qp->piowait);
+ if (!list_empty(&qp->timerwait))
+ list_del_init(&qp->timerwait);
+ if (!list_empty(&qp->piowait))
+ list_del_init(&qp->piowait);
spin_unlock(&dev->pending_lock);

ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
diff -r 386fe7306b31 -r c7cf56636dd1 drivers/infiniband/hw/ipath/ipath_rc.c
--- a/drivers/infiniband/hw/ipath/ipath_rc.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c Tue May 23 11:29:15 2006 -0700
@@ -57,7 +57,7 @@ static void ipath_init_restart(struct ip
qp->s_len = wqe->length - len;
dev = to_idev(qp->ibqp.device);
spin_lock(&dev->pending_lock);
- if (qp->timerwait.next == LIST_POISON1)
+ if (list_empty(&qp->timerwait))
list_add_tail(&qp->timerwait,
&dev->pending[dev->pending_index]);
spin_unlock(&dev->pending_lock);
@@ -356,7 +356,7 @@ static inline int ipath_make_rc_req(stru
if ((int)(qp->s_psn - qp->s_next_psn) > 0)
qp->s_next_psn = qp->s_psn;
spin_lock(&dev->pending_lock);
- if (qp->timerwait.next == LIST_POISON1)
+ if (list_empty(&qp->timerwait))
list_add_tail(&qp->timerwait,
&dev->pending[dev->pending_index]);
spin_unlock(&dev->pending_lock);
@@ -726,8 +726,8 @@ void ipath_restart_rc(struct ipath_qp *q
*/
dev = to_idev(qp->ibqp.device);
spin_lock(&dev->pending_lock);
- if (qp->timerwait.next != LIST_POISON1)
- list_del(&qp->timerwait);
+ if (!list_empty(&qp->timerwait))
+ list_del_init(&qp->timerwait);
spin_unlock(&dev->pending_lock);

if (wqe->wr.opcode == IB_WR_RDMA_READ)
@@ -886,8 +886,8 @@ static int do_rc_ack(struct ipath_qp *qp
* just won't find anything to restart if we ACK everything.
*/
spin_lock(&dev->pending_lock);
- if (qp->timerwait.next != LIST_POISON1)
- list_del(&qp->timerwait);
+ if (!list_empty(&qp->timerwait))
+ list_del_init(&qp->timerwait);
spin_unlock(&dev->pending_lock);

/*
@@ -1194,8 +1194,7 @@ static inline void ipath_rc_rcv_resp(str
IB_WR_RDMA_READ))
goto ack_done;
spin_lock(&dev->pending_lock);
- if (qp->s_rnr_timeout == 0 &&
- qp->timerwait.next != LIST_POISON1)
+ if (qp->s_rnr_timeout == 0 && !list_empty(&qp->timerwait))
list_move_tail(&qp->timerwait,
&dev->pending[dev->pending_index]);
spin_unlock(&dev->pending_lock);
diff -r 386fe7306b31 -r c7cf56636dd1 drivers/infiniband/hw/ipath/ipath_ruc.c
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c Tue May 23 11:29:15 2006 -0700
@@ -435,7 +435,7 @@ void ipath_no_bufs_available(struct ipat
unsigned long flags;

spin_lock_irqsave(&dev->pending_lock, flags);
- if (qp->piowait.next == LIST_POISON1)
+ if (list_empty(&qp->piowait))
list_add_tail(&qp->piowait, &dev->piowait);
spin_unlock_irqrestore(&dev->pending_lock, flags);
/*
diff -r 386fe7306b31 -r c7cf56636dd1 drivers/infiniband/hw/ipath/ipath_verbs.c
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c Tue May 23 11:29:15 2006 -0700
@@ -464,7 +464,7 @@ static void ipath_ib_timer(void *arg)
last = &dev->pending[dev->pending_index];
while (!list_empty(last)) {
qp = list_entry(last->next, struct ipath_qp, timerwait);
- list_del(&qp->timerwait);
+ list_del_init(&qp->timerwait);
qp->timer_next = resend;
resend = qp;
atomic_inc(&qp->refcount);
@@ -474,7 +474,7 @@ static void ipath_ib_timer(void *arg)
qp = list_entry(last->next, struct ipath_qp, timerwait);
if (--qp->s_rnr_timeout == 0) {
do {
- list_del(&qp->timerwait);
+ list_del_init(&qp->timerwait);
tasklet_hi_schedule(&qp->s_task);
if (list_empty(last))
break;
@@ -554,7 +554,7 @@ static int ipath_ib_piobufavail(void *ar
while (!list_empty(&dev->piowait)) {
qp = list_entry(dev->piowait.next, struct ipath_qp,
piowait);
- list_del(&qp->piowait);
+ list_del_init(&qp->piowait);
tasklet_hi_schedule(&qp->s_task);
}
spin_unlock_irqrestore(&dev->pending_lock, flags);

2006-05-23 18:34:03

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 9 of 10] ipath - fix null deref during rdma ops

The problem was that node A's sending thread, which handles sending RDMA
read response data, would write the trigger word, the last packet would
be sent, node B would send a new RDMA read request, node A's interrupt
handler would initialize s_rdma_sge, then node A's sending thread would
update s_rdma_sge. This didn't happen very often naturally but was more
frequent with 1 byte RDMA reads. Rather than adding more locking or
increasing the QP structure size and copying sge data, I modified the
copy routine to update the pointers before writing the trigger word to
avoid the update race.

Signed-off-by: Ralph Campbell <[email protected]>
Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r 551717ecc3db -r 3d844dee2f61 drivers/infiniband/hw/ipath/ipath_layer.c
--- a/drivers/infiniband/hw/ipath/ipath_layer.c Tue May 23 11:29:16 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_layer.c Tue May 23 11:29:16 2006 -0700
@@ -872,12 +872,13 @@ static void copy_io(u32 __iomem *piobuf,
update_sge(ss, len);
length -= len;
}
+ /* Update address before sending packet. */
+ update_sge(ss, length);
/* must flush early everything before trigger word */
ipath_flush_wc();
__raw_writel(last, piobuf);
/* be sure trigger word is written */
ipath_flush_wc();
- update_sge(ss, length);
}

/**
@@ -943,17 +944,18 @@ int ipath_verbs_send(struct ipath_devdat
if (likely(ss->num_sge == 1 && len <= ss->sge.length &&
!((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) {
u32 w;
-
+ u32 *addr = (u32 *) ss->sge.vaddr;
+
+ /* Update address before sending packet. */
+ update_sge(ss, len);
/* Need to round up for the last dword in the packet. */
w = (len + 3) >> 2;
- __iowrite32_copy(piobuf, ss->sge.vaddr, w - 1);
+ __iowrite32_copy(piobuf, addr, w - 1);
/* must flush early everything before trigger word */
ipath_flush_wc();
- __raw_writel(((u32 *) ss->sge.vaddr)[w - 1],
- piobuf + w - 1);
+ __raw_writel(addr[w - 1], piobuf + w - 1);
/* be sure trigger word is written */
ipath_flush_wc();
- update_sge(ss, len);
ret = 0;
goto bail;
}

2006-05-23 18:34:06

by Bryan O'Sullivan

[permalink] [raw]
Subject: [PATCH 6 of 10] ipath - enable GPIO interrupt on HT-460

This is required for even semi-decent performance on OpenIB.

Signed-off-by: Bryan O'Sullivan <[email protected]>

diff -r 6bf52c0f0f0d -r 5d7e365286b3 drivers/infiniband/hw/ipath/ipath_eeprom.c
--- a/drivers/infiniband/hw/ipath/ipath_eeprom.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c Tue May 23 11:29:16 2006 -0700
@@ -505,11 +505,10 @@ static u8 flash_csum(struct ipath_flash
* ipath_get_guid - get the GUID from the i2c device
* @dd: the infinipath device
*
- * When we add the multi-chip support, we will probably have to add
- * the ability to use the number of guids field, and get the guid from
- * the first chip's flash, to use for all of them.
- */
-void ipath_get_guid(struct ipath_devdata *dd)
+ * We have the capability to use the ipath_nguid field, and get
+ * the guid from the first chip's flash, to use for all of them.
+ */
+void ipath_get_eeprom_info(struct ipath_devdata *dd)
{
void *buf;
struct ipath_flash *ifp;
diff -r 6bf52c0f0f0d -r 5d7e365286b3 drivers/infiniband/hw/ipath/ipath_ht400.c
--- a/drivers/infiniband/hw/ipath/ipath_ht400.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_ht400.c Tue May 23 11:29:16 2006 -0700
@@ -607,7 +607,12 @@ static int ipath_ht_boardname(struct ipa
case 4: /* Ponderosa is one of the bringup boards */
n = "Ponderosa";
break;
- case 5: /* HT-460 original production board */
+ case 5:
+ /*
+ * HT-460 original production board; two production levels, with
+ * different serial number ranges. See ipath_ht_early_init() for
+ * case where we enable IPATH_GPIO_INTR for later serial # range.
+ */
n = "InfiniPath_HT-460";
break;
case 6:
@@ -642,7 +647,7 @@ static int ipath_ht_boardname(struct ipa
if (n)
snprintf(name, namelen, "%s", n);

- if (dd->ipath_majrev != 3 || dd->ipath_minrev != 2) {
+ if (dd->ipath_majrev != 3 || (dd->ipath_minrev < 2 || dd->ipath_minrev > 3)) {
/*
* This version of the driver only supports the HT-400
* Rev 3.2
@@ -1520,6 +1525,18 @@ static int ipath_ht_early_init(struct ip
*/
ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
INFINIPATH_S_ABORT);
+
+ ipath_get_eeprom_info(dd);
+ if(dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' &&
+ dd->ipath_serial[1] == '2' && dd->ipath_serial[2] == '8') {
+ /*
+ * Later production HT-460 has same changes as HT-465, so
+ * can use GPIO interrupts. They have serial #'s starting
+ * with 128, rather than 112.
+ */
+ dd->ipath_flags |= IPATH_GPIO_INTR;
+ dd->ipath_flags &= ~IPATH_POLL_RX_INTR;
+ }
return 0;
}

diff -r 6bf52c0f0f0d -r 5d7e365286b3 drivers/infiniband/hw/ipath/ipath_init_chip.c
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c Tue May 23 11:29:16 2006 -0700
@@ -879,7 +879,6 @@ int ipath_init_chip(struct ipath_devdata

done:
if (!ret) {
- ipath_get_guid(dd);
*dd->ipath_statusp |= IPATH_STATUS_CHIP_PRESENT;
if (!dd->ipath_f_intrsetup(dd)) {
/* now we can enable all interrupts from the chip */
diff -r 6bf52c0f0f0d -r 5d7e365286b3 drivers/infiniband/hw/ipath/ipath_kernel.h
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h Tue May 23 11:29:16 2006 -0700
@@ -650,7 +650,7 @@ void ipath_init_pe800_funcs(struct ipath
void ipath_init_pe800_funcs(struct ipath_devdata *);
/* init HT-400-specific func */
void ipath_init_ht400_funcs(struct ipath_devdata *);
-void ipath_get_guid(struct ipath_devdata *);
+void ipath_get_eeprom_info(struct ipath_devdata *);
u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);

/*
diff -r 6bf52c0f0f0d -r 5d7e365286b3 drivers/infiniband/hw/ipath/ipath_pe800.c
--- a/drivers/infiniband/hw/ipath/ipath_pe800.c Tue May 23 11:29:15 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_pe800.c Tue May 23 11:29:16 2006 -0700
@@ -1180,6 +1180,8 @@ static int ipath_pe_early_init(struct ip
*/
dd->ipath_rhdrhead_intr_off = 1ULL<<32;

+ ipath_get_eeprom_info(dd);
+
return 0;
}

2006-05-23 21:09:48

by Roland Dreier

[permalink] [raw]
Subject: Re: [PATCH 1 of 10] ipath - fix spinlock recursion bug

Thanks, I've put 1 through 10 into my git tree and asked Linus to pull.

BTW, I just tried SRP with 2.6.17-rc4 + my for-2.6.18 tree + all of
these patches, and immediately after connecting to a storage target I
get the following:

Kernel BUG at drivers/infiniband/hw/ipath/ipath_layer.c:761
invalid opcode: 0000 [1] SMP
CPU 0
Modules linked in: ib_srp ib_cm ib_sa ib_mad ib_ipath ib_core ipv6 thermal fan button processor ac battery nfs lockd nfs_acl sunrpc dm_mod ide_generic ide_disk ide_cd cdrom e1000 amd74xx shpchp generic pci_hotplug ipath_core parport_pc parport psmouse ohci_hcd ide_core ehci_hcd serio_raw pcspkr
Pid: 3623, comm: udevd Not tainted 2.6.17-rc4 #4
RIP: 0010:[<ffffffff880737d5>] <ffffffff880737d5>{:ipath_core:ipath_verbs_send+364}
RSP: 0000:ffffffff804e1e28 EFLAGS: 00010246
RAX: ffff8101a02b4148 RBX: 0000000000000000 RCX: 0000000000000000
RDX: ffff8101a02b4148 RSI: ffff8101a02b40b0 RDI: ffffc200001c8020
RBP: 0000000000000000 R08: ffff8101a02b4148 R09: 0000000000000002
R10: ffff8101a02b41b0 R11: 000000021e056480 R12: 0000000000000000
R13: ffffc200001c8020 R14: 0000000000000040 R15: 0000000000000010
FS: 00002b8024bbcae0(0000) GS:ffffffff80537000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00002b8024513350 CR3: 00000001a0075000 CR4: 00000000000006e0
Process udevd (pid: 3623, threadinfo ffff81021cc8e000, task ffff8101a02b8770)
Stack: 0000000000000092 ffff8101a02b4148 ffff8101a02b4098 0000000016000003
ffff8101a02b4000 000000000000000a 0000000000000000 0000000000000014
ffff8101a02b40a0 ffffffff881e29ec
Call Trace: <IRQ> <ffffffff881e29ec>{:ib_ipath:ipath_do_rc_send+384}
<ffffffff8820aea9>{:ib_srp:srp_completion+631} <ffffffff8022e523>{tasklet_hi_action+96}
<ffffffff8022e5c3>{__do_softirq+86} <ffffffff8020a97a>{call_softirq+30}
<ffffffff8020c39a>{do_softirq+44} <ffffffff8020c3df>{do_IRQ+65}
<ffffffff80209cd8>{ret_from_intr+0} <EOI> <ffffffff80258d12>{__handle_mm_fault+1278}
<ffffffff80219024>{do_page_fault+796} <ffffffff80219007>{do_page_fault+767}
<ffffffff80391b6e>{datagram_poll+0} <ffffffff8020a471>{error_exit+0}

Code: 0f 0b 68 22 e9 07 88 c2 f9 02 eb 07 44 39 f5 41 0f 47 ee 48
RIP <ffffffff880737d5>{:ipath_core:ipath_verbs_send+364} RSP <ffffffff804e1e28>

2006-05-23 21:26:53

by Bryan O'Sullivan

[permalink] [raw]
Subject: Re: [PATCH 1 of 10] ipath - fix spinlock recursion bug

On Tue, 2006-05-23 at 14:09 -0700, Roland Dreier wrote:
> Thanks, I've put 1 through 10 into my git tree and asked Linus to pull.

Thanks.

> BTW, I just tried SRP with 2.6.17-rc4 + my for-2.6.18 tree + all of
> these patches, and immediately after connecting to a storage target I
> get the following:

Yes, I have another large pile of fixes to sort out. Unfortunately, all
of them depend on some "code motion" driver changes that, in an ideal
world, should be deferred until 2.6.18. Regenerating and testing them
against 2.6.17, without the code motion, is a big pain in the big
painful body region.

How do you feel about taking one code motion patch for 2.6.17? :-)

<b

2006-05-23 21:31:07

by Roland Dreier

[permalink] [raw]
Subject: Re: [PATCH 1 of 10] ipath - fix spinlock recursion bug

Bryan> How do you feel about taking one code motion patch for
Bryan> 2.6.17? :-)

It's probably OK as long as it's pure code motion. In other words
separate the actual fixes from moving code around. What I want to
avoid is the giant combo patch that does several different things,
because if someone later bisects a regression back to that patch,
we're kind of screwed...

- R.

2006-05-24 14:45:59

by Bryan O'Sullivan

[permalink] [raw]
Subject: Re: [PATCH 1 of 10] ipath - fix spinlock recursion bug

On Tue, 2006-05-23 at 14:31 -0700, Roland Dreier wrote:

> It's probably OK as long as it's pure code motion.

I'll recheck and make sure that it is before I send you anything.
Thanks.

> What I want to
> avoid is the giant combo patch that does several different things,
> because if someone later bisects a regression back to that patch,
> we're kind of screwed...

Yeah, I've been doing some educating lately about that :-)

<b