aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_intr.c
diff options
context:
space:
mode:
authorArthur Jones <arthur.jones@qlogic.com>2007-09-14 15:22:49 -0400
committerRoland Dreier <rolandd@cisco.com>2007-10-09 23:56:23 -0400
commit70c51da2c4f84317bb13a2b564600afdcebd686f (patch)
treed7c39e3efaf6c90482cfe9d0e85012c3c9c511a7 /drivers/infiniband/hw/ipath/ipath_intr.c
parent542869a17eee2edf389273f40f757aa4e662b3da (diff)
IB/ipath: Use counters in ipath_poll and cleanup interrupts in ipath_close
ipath_poll() suffered from a couple subtle bugs. Under the right conditions we could leave recv interrupts enabled on an ipath user context on close, thereby taking potentially unwanted interrupts on the next open -- this is fixed by unconditionally turning off recv interrupts on close. Also, we now use counters rather than set/clear bits which allows us to make sure we catch all interrupts at the cost of changing the semantics slightly (it's now give me all events since the last time I called poll() rather than give me all events since I called _this_ poll routine). We also added some memory barriers which may help ensure we get all notifications in a timely manner. Signed-off-by: Arthur Jones <arthur.jones@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_intr.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c33
1 files changed, 10 insertions, 23 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 11b361408ae6..61eac8cc0d9f 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -688,17 +688,9 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
688 chkerrpkts = 1; 688 chkerrpkts = 1;
689 dd->ipath_lastrcvhdrqtails[i] = tl; 689 dd->ipath_lastrcvhdrqtails[i] = tl;
690 pd->port_hdrqfull++; 690 pd->port_hdrqfull++;
691 if (test_bit(IPATH_PORT_WAITING_OVERFLOW, 691 /* flush hdrqfull so that poll() sees it */
692 &pd->port_flag)) { 692 wmb();
693 clear_bit( 693 wake_up_interruptible(&pd->port_wait);
694 IPATH_PORT_WAITING_OVERFLOW,
695 &pd->port_flag);
696 set_bit(
697 IPATH_PORT_WAITING_OVERFLOW,
698 &pd->int_flag);
699 wake_up_interruptible(
700 &pd->port_wait);
701 }
702 } 694 }
703 } 695 }
704 } 696 }
@@ -960,6 +952,8 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
960 int i; 952 int i;
961 int rcvdint = 0; 953 int rcvdint = 0;
962 954
955 /* test_bit below needs this... */
956 rmb();
963 portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) & 957 portr = ((istat >> INFINIPATH_I_RCVAVAIL_SHIFT) &
964 dd->ipath_i_rcvavail_mask) 958 dd->ipath_i_rcvavail_mask)
965 | ((istat >> INFINIPATH_I_RCVURG_SHIFT) & 959 | ((istat >> INFINIPATH_I_RCVURG_SHIFT) &
@@ -967,22 +961,15 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
967 for (i = 1; i < dd->ipath_cfgports; i++) { 961 for (i = 1; i < dd->ipath_cfgports; i++) {
968 struct ipath_portdata *pd = dd->ipath_pd[i]; 962 struct ipath_portdata *pd = dd->ipath_pd[i];
969 if (portr & (1 << i) && pd && pd->port_cnt) { 963 if (portr & (1 << i) && pd && pd->port_cnt) {
970 if (test_bit(IPATH_PORT_WAITING_RCV, 964 if (test_and_clear_bit(IPATH_PORT_WAITING_RCV,
971 &pd->port_flag)) { 965 &pd->port_flag)) {
972 clear_bit(IPATH_PORT_WAITING_RCV,
973 &pd->port_flag);
974 set_bit(IPATH_PORT_WAITING_RCV,
975 &pd->int_flag);
976 clear_bit(i + INFINIPATH_R_INTRAVAIL_SHIFT, 966 clear_bit(i + INFINIPATH_R_INTRAVAIL_SHIFT,
977 &dd->ipath_rcvctrl); 967 &dd->ipath_rcvctrl);
978 wake_up_interruptible(&pd->port_wait); 968 wake_up_interruptible(&pd->port_wait);
979 rcvdint = 1; 969 rcvdint = 1;
980 } else if (test_bit(IPATH_PORT_WAITING_URG, 970 } else if (test_and_clear_bit(IPATH_PORT_WAITING_URG,
981 &pd->port_flag)) { 971 &pd->port_flag)) {
982 clear_bit(IPATH_PORT_WAITING_URG, 972 pd->port_urgent++;
983 &pd->port_flag);
984 set_bit(IPATH_PORT_WAITING_URG,
985 &pd->int_flag);
986 wake_up_interruptible(&pd->port_wait); 973 wake_up_interruptible(&pd->port_wait);
987 } 974 }
988 } 975 }