<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.6000.16587" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>In one of our
clients systems we have noticed that during shutdown it is possibale that an
interrupt will be lost.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>This patch allows
the user to activate the thread and continue the shutdown.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>Thanks</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>Tzachi</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>Index:
mlx4/kernel/bus/ib/main.c</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>===================================================================</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>---
mlx4/kernel/bus/ib/main.c (revision 1763)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+++
mlx4/kernel/bus/ib/main.c (working copy)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>@@ -38,6 +38,11
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> #include
"ib_cache.h"<BR> #include
"net\mlx4.h"<BR> <BR>+#if WORKAROUND_POLL_EQ<BR>+void
mlx4_poll_eq(struct ib_device *dev, BOOLEAN
bStart);<BR>+#endif<BR>+<BR>+<BR> static void init_query_mad(struct ib_smp
*mad)<BR> {<BR> mad->base_version = 1;<BR>@@ -564,7
+569,9 @@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> ibdev->ib_dev.x.get_cached_pkey =
ib_get_cached_pkey;<BR> ibdev->ib_dev.x.register_ev_cb =
mlx4_reset_cb_register;<BR> ibdev->ib_dev.x.unregister_ev_cb =
mlx4_reset_cb_unregister;<BR>-<BR>+#if WORKAROUND_POLL_EQ<BR>+
ibdev->ib_dev.x.poll_eq
= mlx4_poll_eq;<BR>+#endif<BR> if
(mlx4_is_livefish(ibdev->dev))<BR> return
ibdev;<BR> <BR>@@ -674,3 +681,4 @@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> }<BR> <BR> <BR>+<BR>Index:
mlx4/kernel/bus/inc/ib_verbs_ex.h</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>===================================================================</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>---
mlx4/kernel/bus/inc/ib_verbs_ex.h (revision 1763)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+++
mlx4/kernel/bus/inc/ib_verbs_ex.h (working copy)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>@@ -52,6 +52,9
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> u8
port_num, __be16 pkey, u16 *index);<BR> int (*register_ev_cb) (struct
ib_event_handler *event_handler);<BR> int (*unregister_ev_cb) (struct
ib_event_handler *event_handler);<BR>+#if 1 //WORKAROUND_POLL_EQ<BR>+ void
(*poll_eq)(struct ib_device *device, BOOLEAN
bStart);<BR>+#endif<BR> };<BR> <BR> <BR>@@ -89,3 +92,4
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> };<BR> <BR> <BR>+<BR>Index:
mlx4/kernel/bus/net/eq.c</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>===================================================================</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>---
mlx4/kernel/bus/net/eq.c (revision 1763)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+++
mlx4/kernel/bus/net/eq.c (working copy)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>@@ -255,6 +255,103
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> return
(BOOLEAN)work;<BR> }<BR> <BR>+#if
WORKAROUND_POLL_EQ<BR>+<BR>+BOOLEAN<BR>+
IsrSynchronizeRoutine(<BR>+ IN PVOID
SynchronizeContext<BR>+ )<BR>+{<BR>+ struct
mlx4_dev *dev = (struct mlx4_dev *)SynchronizeContext;<BR>+
<BR>+
mlx4_interrupt(dev->pdev->int_obj,dev);<BR>+
<BR>+ return TRUE;<BR>+}<BR>+<BR>+<BR>+VOID
eq_polling_thread(void *ctx) <BR>+{<BR>+#define
POLLING_INTERVAL_MS 50<BR>+ NTSTATUS status;<BR>+ struct
mlx4_priv *priv = (struct mlx4_priv *)ctx;<BR>+ PVOID
wait_objects[2];<BR>+ LARGE_INTEGER
wait_time;<BR>+<BR>+ wait_objects[0] =
&priv->eq_table.thread_stop_event;<BR>+ wait_objects[1] =
&priv->eq_table.thread_start_event;<BR>+<BR>+ for(;;){<BR>+<BR>+ /*
before start polling */<BR>+ DbgPrint("Before
polling.\n");<BR>+ for (;;) {<BR>+ status =
KeWaitForMultipleObjects( 2, wait_objects,
<BR>+
WaitAny, Executive, KernelMode, FALSE, NULL, NULL
);<BR>+<BR>+ if ( status == STATUS_WAIT_0 ){/* thread stopped
*/<BR>+
//KeClearEvent(&priv->eq_table.thread_stop_event);<BR>+ DbgPrint("Signaled
to stop
polling.\n");<BR>+ break; <BR>+ }<BR>+<BR>+ /*
start polling */<BR>+ if ( status == STATUS_WAIT_1
){<BR>+ //KeClearEvent(&priv->eq_table.thread_start_event);<BR>+ DbgPrint("Signaled
to start
polling.\n");<BR>+ break; <BR>+ }<BR>+<BR>+ }<BR>+<BR>+ if(priv->eq_table.bTerminated)
break;<BR>+ if ( status == STATUS_WAIT_0 ) continue;/* thread
stopped, wait for start again */<BR>+<BR>+ /* polling
*/<BR>+ DbgPrint("Start
polling.\n");<BR>+ wait_time.QuadPart =
-(int64_t)(((uint64_t)POLLING_INTERVAL_MS) * 10000);<BR>+ for (;;)
{<BR>+ //mlx4_interrupt( NULL, &priv->dev
);<BR>+ KeSynchronizeExecution(priv->dev.pdev->int_obj,
IsrSynchronizeRoutine, &priv->dev);<BR>+<BR>+ status =
KeWaitForSingleObject( &priv->eq_table.thread_stop_event,
<BR>+ Executive,
KernelMode, FALSE, &wait_time );<BR>+ if ( status ==
STATUS_SUCCESS )
{<BR>+ //KeClearEvent(&priv->eq_table.thread_stop_event);<BR>+ DbgPrint("Signaled
to stop polling while in polling
mode.\n");<BR>+ break; /* thread stopped
*/<BR>+ }<BR>+ }<BR>+<BR>+ if(priv->eq_table.bTerminated)
break;<BR>+ }<BR>+<BR>+ DbgPrint("Polling thread
terminated.\n");<BR>+
PsTerminateSystemThread(STATUS_SUCCESS);<BR>+<BR>+}<BR>+<BR>+<BR>+void
mlx4_poll_eq(struct ib_device *device, BOOLEAN bStart)<BR>+{<BR>+ LONG
signalled=0;<BR>+ struct mlx4_priv *priv =
mlx4_priv(device->dma_device);<BR>+<BR>+ if(bStart){<BR>+ /*
signal start of polling */<BR>+ signalled = KeSetEvent(
<BR>+ &priv->eq_table.thread_start_event,
IO_NO_INCREMENT, FALSE );<BR>+ }else{<BR>+ /* signal end of
polling */<BR>+ signalled = KeSetEvent(
<BR>+ &priv->eq_table.thread_stop_event,
IO_NO_INCREMENT, FALSE
);<BR>+ }<BR>+<BR>+}<BR>+<BR>+#endif<BR>+<BR>+<BR> #ifdef
CONFIG_PCI_MSI<BR> <BR> /* not ported yet */<BR>@@ -548,6 +645,8
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> __free_page(dev->pdev,
priv->eq_table.icm_page);<BR> }<BR> <BR>+<BR>+<BR> int
mlx4_init_eq_table(struct mlx4_dev *dev)<BR> {<BR> struct
mlx4_priv *priv = mlx4_priv(dev);<BR>@@ -648,6 +747,42 @@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> for (i =
0; i < MLX4_NUM_EQ;
++i)<BR> eq_set_ci(&priv->eq_table.eq[i],
1);<BR> <BR>+<BR>+#if WORKAROUND_POLL_EQ<BR>+ { /* Create a thread for
polling EQs in case of missing interrupts from the card
*/<BR>+ NTSTATUS
status;<BR>+ OBJECT_ATTRIBUTES attr;<BR>+ HANDLE
handle;<BR>+<BR>+ KeInitializeEvent(&priv->eq_table.thread_start_event,
SynchronizationEvent,
FALSE);<BR>+ KeInitializeEvent(&priv->eq_table.thread_stop_event,
SynchronizationEvent,
FALSE);<BR>+ //KeInitializeEvent(&priv->eq_table.thread_start_event,
NotificationEvent ,
FALSE);<BR>+ //KeInitializeEvent(&priv->eq_table.thread_stop_event,
NotificationEvent , FALSE);<BR>+ priv->eq_table.bTerminated =
FALSE;<BR>+ priv->eq_table.threadObject =
NULL;<BR>+ InitializeObjectAttributes( &attr, NULL,
OBJ_KERNEL_HANDLE, NULL, NULL );<BR>+ status = PsCreateSystemThread(
&handle, <BR>+ THREAD_ALL_ACCESS, &attr, NULL, NULL,
eq_polling_thread, priv );<BR>+ if (NT_SUCCESS(status))
{<BR>+ status =
ObReferenceObjectByHandle(<BR>+ handle,<BR>+ THREAD_ALL_ACCESS,<BR>+ NULL,<BR>+ KernelMode,<BR>+ &priv->eq_table.threadObject,<BR>+ NULL<BR>+ );<BR>+<BR>+ ASSERT(status
== STATUS_SUCCESS); //<BR>+<BR>+ status =
ZwClose(handle);<BR>+<BR>+ ASSERT(NT_SUCCESS(status)); //
Should always
succeed<BR>+<BR>+ }<BR>+ }<BR>+#endif<BR>+<BR> return
0;<BR> <BR> #ifdef USE_WDM_INTERRUPTS<BR>@@ -737,6 +872,33
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> struct
mlx4_priv *priv = mlx4_priv(dev);<BR> int i;<BR> <BR>+#if
WORKAROUND_POLL_EQ<BR>+ /* stop the EQ polling thread */<BR>+ if
(priv->eq_table.threadObject) { <BR>+ #define
WAIT_TIME_MS 3000<BR>+ NTSTATUS
status;<BR>+ LARGE_INTEGER wait_time;<BR>+ LONG
signalled;<BR>+<BR>+ priv->eq_table.bTerminated =
TRUE;<BR>+<BR>+ /* signal polling stopped in case it is not
*/<BR>+ signalled = KeSetEvent(
<BR>+ &priv->eq_table.thread_stop_event,
IO_NO_INCREMENT, FALSE );<BR>+<BR>+ /* wait for completion of the
thread */<BR>+ wait_time.QuadPart =
-(int64_t)(((uint64_t)WAIT_TIME_MS) * 10000);<BR>+ status =
KeWaitForSingleObject(
priv->eq_table.threadObject,<BR>+ Executive, KernelMode,
FALSE, &wait_time );<BR>+ ASSERT(status ==
STATUS_SUCCESS);<BR>+<BR>+ ObDereferenceObject(priv->eq_table.threadObject);<BR>+<BR>+ /*
cleanup */<BR>+ priv->eq_table.threadObject =
NULL;<BR>+ }<BR>+#endif<BR>+<BR> mlx4_MAP_EQ(dev,
MLX4_ASYNC_EVENT_MASK, 1,<BR>
priv->eq_table.eq[MLX4_EQ_ASYNC].eqn);<BR> <BR>Index:
mlx4/kernel/bus/net/mlx4.h</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>===================================================================</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>---
mlx4/kernel/bus/net/mlx4.h (revision 1763)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+++
mlx4/kernel/bus/net/mlx4.h (working copy)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>@@ -233,6 +233,12
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> int have_irq;<BR> u8 inta_pin;<BR> u8 max_extra_eqs;<BR>+#if
WORKAROUND_POLL_EQ<BR>+ KEVENT thread_start_event;<BR>+ KEVENT thread_stop_event;<BR>+ BOOLEAN bTerminated;<BR>+ PVOID threadObject;<BR>+#endif<BR> };<BR> <BR> struct
mlx4_srq_table {<BR>Index: mlx4/kernel/hca/fw.c</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>===================================================================</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>---
mlx4/kernel/hca/fw.c (revision 1763)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+++
mlx4/kernel/hca/fw.c (working copy)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>@@ -404,8 +404,24
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> UNREFERENCED_PARAMETER(handle_array);</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> UNREFERENCED_PARAMETER(num_handles);</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> </SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>- if(
!p_umv_buf )</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>- return
IB_UNSUPPORTED;</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+
if(!p_umv_buf ) {</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+
#if 1 //WORKAROUND_POLL_EQ</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ if
((p_ci_op->command == FW_POLL_EQ_START) || (p_ci_op->command ==
FW_POLL_EQ_STOP)){ // poll EQ (in case of missed interrupt) </SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+
mlnx_hca_t *p_hca = (mlnx_hca_t *)h_ca;</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+
struct ib_device *p_ibdev = hca2ibdev(p_hca);</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ if(p_ci_op->command ==
FW_POLL_EQ_START)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ {</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ p_ibdev->x.poll_eq(p_ibdev,1);</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ }else</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ {</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ p_ibdev->x.poll_eq(p_ibdev,0);</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ }</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+
return IB_SUCCESS;</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+
}</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+
else</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+
#endif</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+ return
IB_UNSUPPORTED;</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+
}</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> </SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> if (
!p_ci_op )</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> return
IB_INVALID_PARAMETER;</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>@@ -475,3 +491,4
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> }</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> }</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008> </SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>+</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>Index:
mlx4/kernel/inc/vc.h</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008>===================================================================</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>---
mlx4/kernel/inc/vc.h (revision 1763)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>+++
mlx4/kernel/inc/vc.h (working copy)</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008>@@ -51,6 +51,11
@@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> #define
FW_OPEN_IF 0xe7<BR> #define
FW_CLOSE_IF 0x7e<BR> <BR>+#if WORKAROUND_POLL_EQ<BR>+#define
FW_POLL_EQ_START 0x0D<BR>+#define FW_POLL_EQ_STOP
0x0E<BR>+#endif<BR>+<BR> /* uplink info */<BR> typedef
struct {<BR> uint8_t bus_type; /* 1 - PCI, 2 - PCI-X, 3 -
PCI_E */<BR>@@ -74,3 +79,4 @@</SPAN></FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=223310721-22122008> }
uplink_info_t;<BR> <BR> <BR>+<BR></SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN
class=223310721-22122008></SPAN></FONT> </DIV></BODY></HTML>