Skip to content

Commit 03b61ad

Browse files
Hal RosenstockLinus Torvalds
authored andcommitted
[PATCH] IB: Add ib_modify_mad API to MAD
Add new MAD layer call to modify (ib_modify_mad) the timeout of a sent MAD, and simplify cancel code. Signed-off-by: Sean Hefty <[email protected]> Signed-off-by: Hal Rosenstock <[email protected]> Cc: Roland Dreier <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 2c153b9 commit 03b61ad

File tree

3 files changed

+40
-59
lines changed

3 files changed

+40
-59
lines changed

drivers/infiniband/core/mad.c

Lines changed: 28 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
6565
static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
6666
struct ib_mad_send_wc *mad_send_wc);
6767
static void timeout_sends(void *data);
68-
static void cancel_sends(void *data);
6968
static void local_completions(void *data);
7069
static 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
}
21052076
EXPORT_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);

drivers/infiniband/core/mad_priv.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ struct ib_mad_agent_private {
9797
unsigned long timeout;
9898
struct list_head local_list;
9999
struct work_struct local_work;
100-
struct list_head canceled_list;
101-
struct work_struct canceled_work;
102100

103101
atomic_t refcount;
104102
wait_queue_head_t wait;

drivers/infiniband/include/ib_mad.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,18 @@ void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc);
385385
* MADs will be returned to the user through the corresponding
386386
* ib_mad_send_handler.
387387
*/
388-
void ib_cancel_mad(struct ib_mad_agent *mad_agent,
389-
u64 wr_id);
388+
void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id);
389+
390+
/**
391+
* ib_modify_mad - Modifies an outstanding send MAD operation.
392+
* @mad_agent: Specifies the registration associated with sent MAD.
393+
* @wr_id: Indicates the work request identifier of the MAD to modify.
394+
* @timeout_ms: New timeout value for sent MAD.
395+
*
396+
* This call will reset the timeout value for a sent MAD to the specified
397+
* value.
398+
*/
399+
int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms);
390400

391401
/**
392402
* ib_redirect_mad_qp - Registers a QP for MAD services.

0 commit comments

Comments
 (0)