summaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/ehca/ehca_cq.c
diff options
context:
space:
mode:
authorDaniel Schaeffer <daniel@dschaeffer.localdomain>2008-01-30 15:42:41 -0500
committerDaniel Schaeffer <daniel@dschaeffer.localdomain>2008-01-30 15:42:41 -0500
commit648b932d8cf61f38d08a84e6388036b22766c2df (patch)
tree3c48859a194482b645b93c1bead3bcc323327fb7 /drivers/infiniband/hw/ehca/ehca_cq.c
parent2506ae0663e660d8dc7624fcdae1814c8ee3d10a (diff)
parentbbf25010f1a6b761914430f5fca081ec8c7accd1 (diff)
Merge branch '2.6.23' into 2.6.22.6-imx27
Conflicts: Documentation/kernel-parameters.txt Makefile arch/arm/Kconfig arch/arm/Makefile arch/arm/mach-mx3/Kconfig arch/arm/mach-mx3/Makefile arch/arm/mach-mx3/mm.c arch/arm/mach-mx3/mx31ads.c arch/arm/mm/Kconfig arch/arm/plat-mxc/Kconfig arch/arm/plat-mxc/Makefile arch/arm/plat-mxc/irq.c block/cfq-iosched.c drivers/ata/ahci.c drivers/ata/libata-core.c drivers/char/watchdog/Kconfig drivers/firewire/fw-sbp2.c drivers/md/dm-crypt.c drivers/media/video/pwc/pwc-if.c drivers/mmc/card/Kconfig drivers/mmc/card/queue.c drivers/mmc/core/Makefile drivers/mmc/core/bus.c drivers/mmc/core/core.c drivers/mmc/core/host.c drivers/mmc/core/mmc.c drivers/mmc/core/sd.c drivers/mmc/core/sd_ops.c drivers/mmc/host/at91_mci.c drivers/mmc/host/sdhci.c drivers/net/bonding/bond_main.c drivers/net/fec.c drivers/net/forcedeth.c drivers/net/r8169.c drivers/net/sky2.c drivers/rtc/Kconfig drivers/rtc/Makefile drivers/spi/Kconfig drivers/spi/Makefile drivers/usb/gadget/Makefile drivers/usb/gadget/gadget_chips.h drivers/usb/host/ehci.h drivers/video/logo/logo.c drivers/w1/slaves/Makefile fs/9p/conv.c fs/direct-io.c fs/exec.c fs/ocfs2/file.c fs/signalfd.c fs/sysfs/file.c include/asm-arm/arch-mxc/dma.h include/asm-arm/arch-mxc/entry-macro.S include/asm-arm/arch-mxc/hardware.h include/asm-arm/arch-mxc/io.h include/asm-arm/arch-mxc/irqs.h include/asm-arm/arch-mxc/memory.h include/asm-arm/arch-mxc/mx31.h include/asm-arm/arch-mxc/mxc.h include/asm-arm/arch-mxc/system.h include/asm-arm/arch-mxc/timex.h include/asm-arm/arch-mxc/uncompress.h include/asm-arm/arch-mxc/vmalloc.h include/linux/fsl_devices.h include/linux/ioprio.h kernel/lockdep_proc.c kernel/signal.c mm/hugetlb.c mm/readahead.c net/bluetooth/rfcomm/tty.c net/bridge/br_device.c net/core/dev.c net/ieee80211/softmac/ieee80211softmac_assoc.c net/ieee80211/softmac/ieee80211softmac_wx.c net/ipv4/netfilter/nf_conntrack_proto_icmp.c net/ipv4/tcp_input.c net/netfilter/nf_conntrack_proto_sctp.c
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_cq.c')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c62
1 files changed, 27 insertions, 35 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 67f0670fe3b1..81aff36101ba 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -56,11 +56,11 @@ int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp)
{
unsigned int qp_num = qp->real_qp_num;
unsigned int key = qp_num & (QP_HASHTAB_LEN-1);
- unsigned long spl_flags;
+ unsigned long flags;
- spin_lock_irqsave(&cq->spinlock, spl_flags);
+ spin_lock_irqsave(&cq->spinlock, flags);
hlist_add_head(&qp->list_entries, &cq->qp_hashtab[key]);
- spin_unlock_irqrestore(&cq->spinlock, spl_flags);
+ spin_unlock_irqrestore(&cq->spinlock, flags);
ehca_dbg(cq->ib_cq.device, "cq_num=%x real_qp_num=%x",
cq->cq_number, qp_num);
@@ -74,9 +74,9 @@ int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
struct hlist_node *iter;
struct ehca_qp *qp;
- unsigned long spl_flags;
+ unsigned long flags;
- spin_lock_irqsave(&cq->spinlock, spl_flags);
+ spin_lock_irqsave(&cq->spinlock, flags);
hlist_for_each(iter, &cq->qp_hashtab[key]) {
qp = hlist_entry(iter, struct ehca_qp, list_entries);
if (qp->real_qp_num == real_qp_num) {
@@ -88,7 +88,7 @@ int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
break;
}
}
- spin_unlock_irqrestore(&cq->spinlock, spl_flags);
+ spin_unlock_irqrestore(&cq->spinlock, flags);
if (ret)
ehca_err(cq->ib_cq.device,
"qp not found cq_num=%x real_qp_num=%x",
@@ -97,7 +97,7 @@ int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
return ret;
}
-struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
+struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
{
struct ehca_qp *ret = NULL;
unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
@@ -146,6 +146,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
spin_lock_init(&my_cq->spinlock);
spin_lock_init(&my_cq->cb_lock);
spin_lock_init(&my_cq->task_lock);
+ atomic_set(&my_cq->nr_events, 0);
init_waitqueue_head(&my_cq->wait_completion);
my_cq->ownpid = current->tgid;
@@ -162,9 +163,9 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
goto create_cq_exit1;
}
- spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+ write_lock_irqsave(&ehca_cq_idr_lock, flags);
ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token);
- spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+ write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
} while (ret == -EAGAIN);
@@ -189,8 +190,8 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
goto create_cq_exit2;
}
- ipz_rc = ipz_queue_ctor(&my_cq->ipz_queue, param.act_pages,
- EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0);
+ ipz_rc = ipz_queue_ctor(NULL, &my_cq->ipz_queue, param.act_pages,
+ EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0, 0);
if (!ipz_rc) {
ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%x device=%p",
ipz_rc, device);
@@ -284,7 +285,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
return cq;
create_cq_exit4:
- ipz_queue_dtor(&my_cq->ipz_queue);
+ ipz_queue_dtor(NULL, &my_cq->ipz_queue);
create_cq_exit3:
h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1);
@@ -293,9 +294,9 @@ create_cq_exit3:
"cq_num=%x h_ret=%lx", my_cq, my_cq->cq_number, h_ret);
create_cq_exit2:
- spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+ write_lock_irqsave(&ehca_cq_idr_lock, flags);
idr_remove(&ehca_cq_idr, my_cq->token);
- spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+ write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
create_cq_exit1:
kmem_cache_free(cq_cache, my_cq);
@@ -303,16 +304,6 @@ create_cq_exit1:
return cq;
}
-static int get_cq_nr_events(struct ehca_cq *my_cq)
-{
- int ret;
- unsigned long flags;
- spin_lock_irqsave(&ehca_cq_idr_lock, flags);
- ret = my_cq->nr_events;
- spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
- return ret;
-}
-
int ehca_destroy_cq(struct ib_cq *cq)
{
u64 h_ret;
@@ -339,17 +330,18 @@ int ehca_destroy_cq(struct ib_cq *cq)
}
}
- spin_lock_irqsave(&ehca_cq_idr_lock, flags);
- while (my_cq->nr_events) {
- spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
- wait_event(my_cq->wait_completion, !get_cq_nr_events(my_cq));
- spin_lock_irqsave(&ehca_cq_idr_lock, flags);
- /* recheck nr_events to assure no cqe has just arrived */
- }
-
+ /*
+ * remove the CQ from the idr first to make sure
+ * no more interrupt tasklets will touch this CQ
+ */
+ write_lock_irqsave(&ehca_cq_idr_lock, flags);
idr_remove(&ehca_cq_idr, my_cq->token);
- spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+ write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+
+ /* now wait until all pending events have completed */
+ wait_event(my_cq->wait_completion, !atomic_read(&my_cq->nr_events));
+ /* nobody's using our CQ any longer -- we can destroy it */
h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0);
if (h_ret == H_R_STATE) {
/* cq in err: read err data and destroy it forcibly */
@@ -367,7 +359,7 @@ int ehca_destroy_cq(struct ib_cq *cq)
"ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num);
return ehca2ib_return_code(h_ret);
}
- ipz_queue_dtor(&my_cq->ipz_queue);
+ ipz_queue_dtor(NULL, &my_cq->ipz_queue);
kmem_cache_free(cq_cache, my_cq);
return 0;
@@ -395,7 +387,7 @@ int ehca_init_cq_cache(void)
cq_cache = kmem_cache_create("ehca_cache_cq",
sizeof(struct ehca_cq), 0,
SLAB_HWCACHE_ALIGN,
- NULL, NULL);
+ NULL);
if (!cq_cache)
return -ENOMEM;
return 0;