Commit 4a0754fa authored by Hal Rosenstock's avatar Hal Rosenstock Committed by Linus Torvalds

[PATCH] IB: Combine some MAD routines

Combine response_mad() and solicited_mad() routines into a single function and
simplify/encapsulate its usage.
Signed-off-by: default avatarSean Hefty <sean.hefty@intel.com>
Signed-off-by: default avatarHal Rosenstock <halr@voltaire.com>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 824c8ae7
...@@ -58,7 +58,7 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method, ...@@ -58,7 +58,7 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method,
static void remove_mad_reg_req(struct ib_mad_agent_private *priv); static void remove_mad_reg_req(struct ib_mad_agent_private *priv);
static struct ib_mad_agent_private *find_mad_agent( static struct ib_mad_agent_private *find_mad_agent(
struct ib_mad_port_private *port_priv, struct ib_mad_port_private *port_priv,
struct ib_mad *mad, int solicited); struct ib_mad *mad);
static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
struct ib_mad_private *mad); struct ib_mad_private *mad);
static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv); static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
...@@ -67,7 +67,6 @@ static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, ...@@ -67,7 +67,6 @@ static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
static void timeout_sends(void *data); static void timeout_sends(void *data);
static void cancel_sends(void *data); static void cancel_sends(void *data);
static void local_completions(void *data); static void local_completions(void *data);
static int solicited_mad(struct ib_mad *mad);
static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req, static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
struct ib_mad_agent_private *agent_priv, struct ib_mad_agent_private *agent_priv,
u8 mgmt_class); u8 mgmt_class);
...@@ -558,6 +557,13 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent) ...@@ -558,6 +557,13 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent)
} }
EXPORT_SYMBOL(ib_unregister_mad_agent); EXPORT_SYMBOL(ib_unregister_mad_agent);
static inline int response_mad(struct ib_mad *mad)
{
/* Trap represses are responses although response bit is reset */
return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
(mad->mad_hdr.method & IB_MGMT_METHOD_RESP));
}
static void dequeue_mad(struct ib_mad_list_head *mad_list) static void dequeue_mad(struct ib_mad_list_head *mad_list)
{ {
struct ib_mad_queue *mad_queue; struct ib_mad_queue *mad_queue;
...@@ -650,7 +656,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, ...@@ -650,7 +656,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
struct ib_smp *smp, struct ib_smp *smp,
struct ib_send_wr *send_wr) struct ib_send_wr *send_wr)
{ {
int ret, solicited; int ret;
unsigned long flags; unsigned long flags;
struct ib_mad_local_private *local; struct ib_mad_local_private *local;
struct ib_mad_private *mad_priv; struct ib_mad_private *mad_priv;
...@@ -696,11 +702,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, ...@@ -696,11 +702,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
switch (ret) switch (ret)
{ {
case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY: case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
/* if (response_mad(&mad_priv->mad.mad) &&
* See if response is solicited and
* there is a recv handler
*/
if (solicited_mad(&mad_priv->mad.mad) &&
mad_agent_priv->agent.recv_handler) { mad_agent_priv->agent.recv_handler) {
local->mad_priv = mad_priv; local->mad_priv = mad_priv;
local->recv_mad_agent = mad_agent_priv; local->recv_mad_agent = mad_agent_priv;
...@@ -717,15 +719,13 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, ...@@ -717,15 +719,13 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
break; break;
case IB_MAD_RESULT_SUCCESS: case IB_MAD_RESULT_SUCCESS:
/* Treat like an incoming receive MAD */ /* Treat like an incoming receive MAD */
solicited = solicited_mad(&mad_priv->mad.mad);
port_priv = ib_get_mad_port(mad_agent_priv->agent.device, port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
mad_agent_priv->agent.port_num); mad_agent_priv->agent.port_num);
if (port_priv) { if (port_priv) {
mad_priv->mad.mad.mad_hdr.tid = mad_priv->mad.mad.mad_hdr.tid =
((struct ib_mad *)smp)->mad_hdr.tid; ((struct ib_mad *)smp)->mad_hdr.tid;
recv_mad_agent = find_mad_agent(port_priv, recv_mad_agent = find_mad_agent(port_priv,
&mad_priv->mad.mad, &mad_priv->mad.mad);
solicited);
} }
if (!port_priv || !recv_mad_agent) { if (!port_priv || !recv_mad_agent) {
kmem_cache_free(ib_mad_cache, mad_priv); kmem_cache_free(ib_mad_cache, mad_priv);
...@@ -1421,42 +1421,15 @@ static void remove_mad_reg_req(struct ib_mad_agent_private *agent_priv) ...@@ -1421,42 +1421,15 @@ static void remove_mad_reg_req(struct ib_mad_agent_private *agent_priv)
return; return;
} }
static int response_mad(struct ib_mad *mad)
{
/* Trap represses are responses although response bit is reset */
return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
(mad->mad_hdr.method & IB_MGMT_METHOD_RESP));
}
static int solicited_mad(struct ib_mad *mad)
{
/* CM MADs are never solicited */
if (mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CM) {
return 0;
}
/* XXX: Determine whether MAD is using RMPP */
/* Not using RMPP */
/* Is this MAD a response to a previous MAD ? */
return response_mad(mad);
}
static struct ib_mad_agent_private * static struct ib_mad_agent_private *
find_mad_agent(struct ib_mad_port_private *port_priv, find_mad_agent(struct ib_mad_port_private *port_priv,
struct ib_mad *mad, struct ib_mad *mad)
int solicited)
{ {
struct ib_mad_agent_private *mad_agent = NULL; struct ib_mad_agent_private *mad_agent = NULL;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&port_priv->reg_lock, flags); spin_lock_irqsave(&port_priv->reg_lock, flags);
if (response_mad(mad)) {
/*
* Whether MAD was solicited determines type of routing to
* MAD client.
*/
if (solicited) {
u32 hi_tid; u32 hi_tid;
struct ib_mad_agent_private *entry; struct ib_mad_agent_private *entry;
...@@ -1560,18 +1533,6 @@ static int validate_mad(struct ib_mad *mad, u32 qp_num) ...@@ -1560,18 +1533,6 @@ static int validate_mad(struct ib_mad *mad, u32 qp_num)
return valid; return valid;
} }
/*
* Return start of fully reassembled MAD, or NULL, if MAD isn't assembled yet
*/
static struct ib_mad_private *
reassemble_recv(struct ib_mad_agent_private *mad_agent_priv,
struct ib_mad_private *recv)
{
/* Until we have RMPP, all receives are reassembled!... */
INIT_LIST_HEAD(&recv->header.recv_wc.recv_buf.list);
return recv;
}
static struct ib_mad_send_wr_private* static struct ib_mad_send_wr_private*
find_send_req(struct ib_mad_agent_private *mad_agent_priv, find_send_req(struct ib_mad_agent_private *mad_agent_priv,
u64 tid) u64 tid)
...@@ -1600,29 +1561,22 @@ find_send_req(struct ib_mad_agent_private *mad_agent_priv, ...@@ -1600,29 +1561,22 @@ find_send_req(struct ib_mad_agent_private *mad_agent_priv,
} }
static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
struct ib_mad_private *recv, struct ib_mad_recv_wc *mad_recv_wc)
int solicited)
{ {
struct ib_mad_send_wr_private *mad_send_wr; struct ib_mad_send_wr_private *mad_send_wr;
struct ib_mad_send_wc mad_send_wc; struct ib_mad_send_wc mad_send_wc;
unsigned long flags; unsigned long flags;
u64 tid;
/* Fully reassemble receive before processing */ INIT_LIST_HEAD(&mad_recv_wc->recv_buf.list);
recv = reassemble_recv(mad_agent_priv, recv);
if (!recv) {
if (atomic_dec_and_test(&mad_agent_priv->refcount))
wake_up(&mad_agent_priv->wait);
return;
}
/* Complete corresponding request */ /* Complete corresponding request */
if (solicited) { if (response_mad(mad_recv_wc->recv_buf.mad)) {
tid = mad_recv_wc->recv_buf.mad->mad_hdr.tid;
spin_lock_irqsave(&mad_agent_priv->lock, flags); spin_lock_irqsave(&mad_agent_priv->lock, flags);
mad_send_wr = find_send_req(mad_agent_priv, mad_send_wr = find_send_req(mad_agent_priv, tid);
recv->mad.mad.mad_hdr.tid);
if (!mad_send_wr) { if (!mad_send_wr) {
spin_unlock_irqrestore(&mad_agent_priv->lock, flags); spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
ib_free_recv_mad(&recv->header.recv_wc); ib_free_recv_mad(mad_recv_wc);
if (atomic_dec_and_test(&mad_agent_priv->refcount)) if (atomic_dec_and_test(&mad_agent_priv->refcount))
wake_up(&mad_agent_priv->wait); wake_up(&mad_agent_priv->wait);
return; return;
...@@ -1632,10 +1586,9 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, ...@@ -1632,10 +1586,9 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
spin_unlock_irqrestore(&mad_agent_priv->lock, flags); spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
/* Defined behavior is to complete response before request */ /* Defined behavior is to complete response before request */
recv->header.recv_wc.wc->wr_id = mad_send_wr->wr_id; mad_recv_wc->wc->wr_id = mad_send_wr->wr_id;
mad_agent_priv->agent.recv_handler( mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
&mad_agent_priv->agent, mad_recv_wc);
&recv->header.recv_wc);
atomic_dec(&mad_agent_priv->refcount); atomic_dec(&mad_agent_priv->refcount);
mad_send_wc.status = IB_WC_SUCCESS; mad_send_wc.status = IB_WC_SUCCESS;
...@@ -1643,9 +1596,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, ...@@ -1643,9 +1596,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
mad_send_wc.wr_id = mad_send_wr->wr_id; mad_send_wc.wr_id = mad_send_wr->wr_id;
ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc); ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
} else { } else {
mad_agent_priv->agent.recv_handler( mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
&mad_agent_priv->agent, mad_recv_wc);
&recv->header.recv_wc);
if (atomic_dec_and_test(&mad_agent_priv->refcount)) if (atomic_dec_and_test(&mad_agent_priv->refcount))
wake_up(&mad_agent_priv->wait); wake_up(&mad_agent_priv->wait);
} }
...@@ -1659,7 +1611,6 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, ...@@ -1659,7 +1611,6 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
struct ib_mad_private *recv, *response; struct ib_mad_private *recv, *response;
struct ib_mad_list_head *mad_list; struct ib_mad_list_head *mad_list;
struct ib_mad_agent_private *mad_agent; struct ib_mad_agent_private *mad_agent;
int solicited;
response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
if (!response) if (!response)
...@@ -1745,11 +1696,9 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, ...@@ -1745,11 +1696,9 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv,
} }
} }
/* Determine corresponding MAD agent for incoming receive MAD */ mad_agent = find_mad_agent(port_priv, &recv->mad.mad);
solicited = solicited_mad(&recv->mad.mad);
mad_agent = find_mad_agent(port_priv, &recv->mad.mad, solicited);
if (mad_agent) { if (mad_agent) {
ib_mad_complete_recv(mad_agent, recv, solicited); ib_mad_complete_recv(mad_agent, &recv->header.recv_wc);
/* /*
* recv is freed up in error cases in ib_mad_complete_recv * recv is freed up in error cases in ib_mad_complete_recv
* or via recv_handler in ib_mad_complete_recv() * or via recv_handler in ib_mad_complete_recv()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment