aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
diff options
context:
space:
mode:
authorSteve Wise <swise@opengridcomputing.com>2011-05-09 22:06:23 -0700
committerRoland Dreier <roland@purestorage.com>2011-05-09 22:06:23 -0700
commit2f25e9a540951ebd533b9b98d2259deb44b0b476 (patch)
treea2548d5cbcb9e26b679e9f783c78cf088f7b2123 /drivers/infiniband/hw/cxgb4/iw_cxgb4.h
parentRDMA/cxgb4: Reset wait condition atomically (diff)
downloadlinux-dev-2f25e9a540951ebd533b9b98d2259deb44b0b476.tar.xz
linux-dev-2f25e9a540951ebd533b9b98d2259deb44b0b476.zip
RDMA/cxgb4: EEH errors can hang the driver
A few more EEH fixes: c4iw_wait_for_reply(): detect fatal EEH condition on timeout and return an error. The iw_cxgb4 driver was only calling ib_deregister_device() on an EEH event followed by a ib_register_device() when the device was reinitialized. However, the RDMA core doesn't allow multiple iterations of register/deregister by the provider. See drivers/infiniband/core/sysfs.c: ib_device_unregister_sysfs() where the kobject ref is held until the device is deallocated in ib_deallocate_device(). Calling deregister adds this kobj reference, and then a subsequent register call will generate a WARN_ON() from the kobject subsystem because the kobject is being initialized but is already initialized with the ref held. So the provider must deregister and dealloc when resetting for an EEH event, then alloc/register to re-initialize. To do this, we cannot use the device ptr as our ULD handle since it will change with each reallocation. This commit adds a ULD context struct which is used as the ULD handle, and then contains the device pointer and other state needed. Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/cxgb4/iw_cxgb4.h')
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 3dcfe82b1248..35d2a5dd9bb4 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -170,6 +170,10 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev,
printk(KERN_ERR MOD "%s - Device %s not responding - "
"tid %u qpid %u\n", func,
pci_name(rdev->lldi.pdev), hwtid, qpid);
+ if (c4iw_fatal_error(rdev)) {
+ wr_waitp->ret = -EIO;
+ break;
+ }
to = to << 2;
}
} while (!ret);
@@ -187,9 +191,7 @@ struct c4iw_dev {
struct idr qpidr;
struct idr mmidr;
spinlock_t lock;
- struct list_head entry;
struct dentry *debugfs_root;
- u8 registered;
};
static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)