@@ -65,7 +65,6 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
6565static void ib_mad_complete_send_wr (struct ib_mad_send_wr_private * mad_send_wr ,
6666 struct ib_mad_send_wc * mad_send_wc );
6767static void timeout_sends (void * data );
68- static void cancel_sends (void * data );
6968static void local_completions (void * data );
7069static int add_nonoui_reg_req (struct ib_mad_reg_req * mad_reg_req ,
7170 struct ib_mad_agent_private * agent_priv ,
@@ -346,8 +345,6 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
346345 INIT_LIST_HEAD (& mad_agent_priv -> local_list );
347346 INIT_WORK (& mad_agent_priv -> local_work , local_completions ,
348347 mad_agent_priv );
349- INIT_LIST_HEAD (& mad_agent_priv -> canceled_list );
350- INIT_WORK (& mad_agent_priv -> canceled_work , cancel_sends , mad_agent_priv );
351348 atomic_set (& mad_agent_priv -> refcount , 1 );
352349 init_waitqueue_head (& mad_agent_priv -> wait );
353350
@@ -1775,6 +1772,13 @@ static void wait_for_response(struct ib_mad_send_wr_private *mad_send_wr)
17751772 }
17761773}
17771774
1775+ void ib_reset_mad_timeout (struct ib_mad_send_wr_private * mad_send_wr ,
1776+ int timeout_ms )
1777+ {
1778+ mad_send_wr -> timeout = msecs_to_jiffies (timeout_ms );
1779+ wait_for_response (mad_send_wr );
1780+ }
1781+
17781782/*
17791783 * Process a send work completion
17801784 */
@@ -2034,41 +2038,7 @@ find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv,
20342038 return NULL ;
20352039}
20362040
2037- void cancel_sends (void * data )
2038- {
2039- struct ib_mad_agent_private * mad_agent_priv ;
2040- struct ib_mad_send_wr_private * mad_send_wr ;
2041- struct ib_mad_send_wc mad_send_wc ;
2042- unsigned long flags ;
2043-
2044- mad_agent_priv = data ;
2045-
2046- mad_send_wc .status = IB_WC_WR_FLUSH_ERR ;
2047- mad_send_wc .vendor_err = 0 ;
2048-
2049- spin_lock_irqsave (& mad_agent_priv -> lock , flags );
2050- while (!list_empty (& mad_agent_priv -> canceled_list )) {
2051- mad_send_wr = list_entry (mad_agent_priv -> canceled_list .next ,
2052- struct ib_mad_send_wr_private ,
2053- agent_list );
2054-
2055- list_del (& mad_send_wr -> agent_list );
2056- spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
2057-
2058- mad_send_wc .wr_id = mad_send_wr -> wr_id ;
2059- mad_agent_priv -> agent .send_handler (& mad_agent_priv -> agent ,
2060- & mad_send_wc );
2061-
2062- kfree (mad_send_wr );
2063- if (atomic_dec_and_test (& mad_agent_priv -> refcount ))
2064- wake_up (& mad_agent_priv -> wait );
2065- spin_lock_irqsave (& mad_agent_priv -> lock , flags );
2066- }
2067- spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
2068- }
2069-
2070- void ib_cancel_mad (struct ib_mad_agent * mad_agent ,
2071- u64 wr_id )
2041+ int ib_modify_mad (struct ib_mad_agent * mad_agent , u64 wr_id , u32 timeout_ms )
20722042{
20732043 struct ib_mad_agent_private * mad_agent_priv ;
20742044 struct ib_mad_send_wr_private * mad_send_wr ;
@@ -2078,29 +2048,30 @@ void ib_cancel_mad(struct ib_mad_agent *mad_agent,
20782048 agent );
20792049 spin_lock_irqsave (& mad_agent_priv -> lock , flags );
20802050 mad_send_wr = find_send_by_wr_id (mad_agent_priv , wr_id );
2081- if (!mad_send_wr ) {
2051+ if (!mad_send_wr || mad_send_wr -> status != IB_WC_SUCCESS ) {
20822052 spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
2083- goto out ;
2053+ return - EINVAL ;
20842054 }
20852055
2086- if (mad_send_wr -> status == IB_WC_SUCCESS )
2087- mad_send_wr -> refcount -= (mad_send_wr -> timeout > 0 );
2088-
2089- if (mad_send_wr -> refcount != 0 ) {
2056+ if (!timeout_ms ) {
20902057 mad_send_wr -> status = IB_WC_WR_FLUSH_ERR ;
2091- spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
2092- goto out ;
2058+ mad_send_wr -> refcount -= (mad_send_wr -> timeout > 0 );
20932059 }
20942060
2095- list_del (& mad_send_wr -> agent_list );
2096- list_add_tail (& mad_send_wr -> agent_list , & mad_agent_priv -> canceled_list );
2097- adjust_timeout (mad_agent_priv );
2061+ mad_send_wr -> send_wr .wr .ud .timeout_ms = timeout_ms ;
2062+ if (!mad_send_wr -> timeout || mad_send_wr -> refcount > 1 )
2063+ mad_send_wr -> timeout = msecs_to_jiffies (timeout_ms );
2064+ else
2065+ ib_reset_mad_timeout (mad_send_wr , timeout_ms );
2066+
20982067 spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
2068+ return 0 ;
2069+ }
2070+ EXPORT_SYMBOL (ib_modify_mad );
20992071
2100- queue_work (mad_agent_priv -> qp_info -> port_priv -> wq ,
2101- & mad_agent_priv -> canceled_work );
2102- out :
2103- return ;
2072+ void ib_cancel_mad (struct ib_mad_agent * mad_agent , u64 wr_id )
2073+ {
2074+ ib_modify_mad (mad_agent , wr_id , 0 );
21042075}
21052076EXPORT_SYMBOL (ib_cancel_mad );
21062077
@@ -2207,8 +2178,6 @@ static void timeout_sends(void *data)
22072178 unsigned long flags , delay ;
22082179
22092180 mad_agent_priv = (struct ib_mad_agent_private * )data ;
2210-
2211- mad_send_wc .status = IB_WC_RESP_TIMEOUT_ERR ;
22122181 mad_send_wc .vendor_err = 0 ;
22132182
22142183 spin_lock_irqsave (& mad_agent_priv -> lock , flags );
@@ -2233,6 +2202,10 @@ static void timeout_sends(void *data)
22332202
22342203 spin_unlock_irqrestore (& mad_agent_priv -> lock , flags );
22352204
2205+ if (mad_send_wr -> status == IB_WC_SUCCESS )
2206+ mad_send_wc .status = IB_WC_RESP_TIMEOUT_ERR ;
2207+ else
2208+ mad_send_wc .status = mad_send_wr -> status ;
22362209 mad_send_wc .wr_id = mad_send_wr -> wr_id ;
22372210 mad_agent_priv -> agent .send_handler (& mad_agent_priv -> agent ,
22382211 & mad_send_wc );
0 commit comments