forked from Minki/linux
IB/mad: initialize mad_agent_priv before putting on lists
There is a potential race in ib_register_mad_agent() where the struct ib_mad_agent_private is not fully initialized before it is added to the list of agents per IB port. This means the ib_mad_agent_private could be seen before the refcount, spin locks, and linked lists are initialized. The fix is to initialize the structure earlier. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
1d9bc6d648
commit
d9620a4c82
@ -301,6 +301,16 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
mad_agent_priv->agent.context = context;
|
||||
mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
|
||||
mad_agent_priv->agent.port_num = port_num;
|
||||
spin_lock_init(&mad_agent_priv->lock);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->send_list);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->wait_list);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->done_list);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
|
||||
INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->local_list);
|
||||
INIT_WORK(&mad_agent_priv->local_work, local_completions);
|
||||
atomic_set(&mad_agent_priv->refcount, 1);
|
||||
init_completion(&mad_agent_priv->comp);
|
||||
|
||||
spin_lock_irqsave(&port_priv->reg_lock, flags);
|
||||
mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
|
||||
@ -350,17 +360,6 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
|
||||
list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
|
||||
spin_unlock_irqrestore(&port_priv->reg_lock, flags);
|
||||
|
||||
spin_lock_init(&mad_agent_priv->lock);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->send_list);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->wait_list);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->done_list);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
|
||||
INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
|
||||
INIT_LIST_HEAD(&mad_agent_priv->local_list);
|
||||
INIT_WORK(&mad_agent_priv->local_work, local_completions);
|
||||
atomic_set(&mad_agent_priv->refcount, 1);
|
||||
init_completion(&mad_agent_priv->comp);
|
||||
|
||||
return &mad_agent_priv->agent;
|
||||
|
||||
error4:
|
||||
|
Loading…
Reference in New Issue
Block a user