[ofa-general] [PATCHv2] IB/mad: fix duplicated kernel thread name
Michael S. Tsirkin
mst at dev.mellanox.co.il
Sun Jul 15 02:41:45 PDT 2007
Make mad module use a single workqueue rather than a per-port
workqueue. This way, we'll have less clutter on systems with
a lot of ports.
Signed-off-by: Michael S. Tsirkin <mst at dev.mellanox.co.il>
---
> Quoting Or Gerlitz <ogerlitz at voltaire.com>:
> Subject: [PATCH] IB/mad: fix duplicated kernel thread name
>
> Roland,
>
> This is the best I could come with, its still a problem
> if you have multiple devices of different providers or
> more than ten devices of the same provider... any other idea?
>
> --------------------------------------------------------------
>
> The mad module creates thread per active port where the thread name is
> derived from the port name. This cause different threads to have same
> names when there are multiple devices. Fix that by using both the device
> and the port numbers to derive the name.
>
> Signed-off-by: Or Gerlitz <ogerlitz at voltaire.com>
Thinking about it, why would we *want* a per-port thread?
What do you guys think about the following?
As a bonus, this makes it easier to renice the mad thread
for people that want to do this.
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 85ccf13..626d3e4 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -45,6 +45,8 @@ MODULE_DESCRIPTION("kernel IB MAD API");
MODULE_AUTHOR("Hal Rosenstock");
MODULE_AUTHOR("Sean Hefty");
+struct workqueue_struct *ib_mad_wq;
+
static struct kmem_cache *ib_mad_cache;
static struct list_head ib_mad_port_list;
@@ -525,7 +527,7 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
list_del(&mad_agent_priv->agent_list);
spin_unlock_irqrestore(&port_priv->reg_lock, flags);
- flush_workqueue(port_priv->wq);
+ flush_workqueue(ib_mad_wq);
ib_cancel_rmpp_recvs(mad_agent_priv);
deref_mad_agent(mad_agent_priv);
@@ -774,8 +776,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
spin_lock_irqsave(&mad_agent_priv->lock, flags);
list_add_tail(&local->completion_list, &mad_agent_priv->local_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
- queue_work(mad_agent_priv->qp_info->port_priv->wq,
- &mad_agent_priv->local_work);
+ queue_work(ib_mad_wq, &mad_agent_priv->local_work);
ret = 1;
out:
return ret;
@@ -1965,9 +1966,7 @@ static void adjust_timeout(struct ib_mad_agent_private *mad_agent_priv)
delay = mad_send_wr->timeout - jiffies;
if ((long)delay <= 0)
delay = 1;
- queue_delayed_work(mad_agent_priv->qp_info->
- port_priv->wq,
- &mad_agent_priv->timed_work, delay);
+ queue_delayed_work(ib_mad_wq, &mad_agent_priv->timed_work, delay);
}
}
}
@@ -2002,8 +2001,7 @@ static void wait_for_response(struct ib_mad_send_wr_private *mad_send_wr)
/* Reschedule a work item if we have a shorter timeout */
if (mad_agent_priv->wait_list.next == &mad_send_wr->agent_list) {
cancel_delayed_work(&mad_agent_priv->timed_work);
- queue_delayed_work(mad_agent_priv->qp_info->port_priv->wq,
- &mad_agent_priv->timed_work, delay);
+ queue_delayed_work(ib_mad_wq, &mad_agent_priv->timed_work, delay);
}
}
@@ -2462,9 +2460,7 @@ static void timeout_sends(struct work_struct *work)
delay = mad_send_wr->timeout - jiffies;
if ((long)delay <= 0)
delay = 1;
- queue_delayed_work(mad_agent_priv->qp_info->
- port_priv->wq,
- &mad_agent_priv->timed_work, delay);
+ queue_delayed_work(ib_mad_wq, &mad_agent_priv->timed_work, delay);
break;
}
@@ -2496,7 +2492,7 @@ static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg)
spin_lock_irqsave(&ib_mad_port_list_lock, flags);
if (!list_empty(&port_priv->port_list))
- queue_work(port_priv->wq, &port_priv->work);
+ queue_work(ib_mad_wq, &port_priv->work);
spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
}
@@ -2800,11 +2796,6 @@ static int ib_mad_port_open(struct ib_device *device,
goto error7;
snprintf(name, sizeof name, "ib_mad%d", port_num);
- port_priv->wq = create_singlethread_workqueue(name);
- if (!port_priv->wq) {
- ret = -ENOMEM;
- goto error8;
- }
INIT_WORK(&port_priv->work, ib_mad_completion_handler);
spin_lock_irqsave(&ib_mad_port_list_lock, flags);
@@ -2814,18 +2805,15 @@ static int ib_mad_port_open(struct ib_device *device,
ret = ib_mad_port_start(port_priv);
if (ret) {
printk(KERN_ERR PFX "Couldn't start port\n");
- goto error9;
+ goto error8;
}
return 0;
-error9:
+error8:
spin_lock_irqsave(&ib_mad_port_list_lock, flags);
list_del_init(&port_priv->port_list);
spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
-
- destroy_workqueue(port_priv->wq);
-error8:
destroy_mad_qp(&port_priv->qp_info[1]);
error7:
destroy_mad_qp(&port_priv->qp_info[0]);
@@ -2863,7 +2851,7 @@ static int ib_mad_port_close(struct ib_device *device, int port_num)
list_del_init(&port_priv->port_list);
spin_unlock_irqrestore(&ib_mad_port_list_lock, flags);
- destroy_workqueue(port_priv->wq);
+ flush_workqueue(ib_mad_wq);
destroy_mad_qp(&port_priv->qp_info[1]);
destroy_mad_qp(&port_priv->qp_info[0]);
ib_dereg_mr(port_priv->mr);
@@ -2960,6 +2948,12 @@ static int __init ib_mad_init_module(void)
{
int ret;
+ ib_mad_wq = create_singlethread_workqueue("ib_mad");
+ if (!ib_mad_wq) {
+ ret = -ENOMEM;
+ goto error0;
+ }
+
spin_lock_init(&ib_mad_port_list_lock);
ib_mad_cache = kmem_cache_create("ib_mad",
@@ -2987,6 +2981,8 @@ static int __init ib_mad_init_module(void)
error2:
kmem_cache_destroy(ib_mad_cache);
error1:
+ destroy_workqueue(ib_mad_wq);
+error0:
return ret;
}
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
index 9be5cc0..5cd2eb9 100644
--- a/drivers/infiniband/core/mad_priv.h
+++ b/drivers/infiniband/core/mad_priv.h
@@ -206,7 +206,6 @@ struct ib_mad_port_private {
spinlock_t reg_lock;
struct ib_mad_mgmt_version_table version[MAX_MGMT_VERSION];
struct list_head agent_list;
- struct workqueue_struct *wq;
struct work_struct work;
struct ib_mad_qp_info qp_info[IB_MAD_QPS_CORE];
};
@@ -225,4 +224,6 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr);
void ib_reset_mad_timeout(struct ib_mad_send_wr_private *mad_send_wr,
int timeout_ms);
+extern struct workqueue_struct *ib_mad_wq;
+
#endif /* __IB_MAD_PRIV_H__ */
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 3663fd7..b8ee2b7 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -94,7 +94,7 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
}
spin_unlock_irqrestore(&agent->lock, flags);
- flush_workqueue(agent->qp_info->port_priv->wq);
+ flush_workqueue(ib_mad_wq);
list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv,
&agent->rmpp_list, list) {
@@ -445,8 +445,7 @@ static struct ib_mad_recv_wc * complete_rmpp(struct mad_rmpp_recv *rmpp_recv)
rmpp_wc = rmpp_recv->rmpp_wc;
rmpp_wc->mad_len = get_mad_len(rmpp_recv);
/* 10 seconds until we can find the packet lifetime */
- queue_delayed_work(rmpp_recv->agent->qp_info->port_priv->wq,
- &rmpp_recv->cleanup_work, msecs_to_jiffies(10000));
+ queue_delayed_work(ib_mad_wq, &rmpp_recv->cleanup_work, msecs_to_jiffies(10000));
return rmpp_wc;
}
@@ -538,8 +537,7 @@ start_rmpp(struct ib_mad_agent_private *agent,
} else {
spin_unlock_irqrestore(&agent->lock, flags);
/* 40 seconds until we can find the packet lifetimes */
- queue_delayed_work(agent->qp_info->port_priv->wq,
- &rmpp_recv->timeout_work,
+ queue_delayed_work(ib_mad_wq, &rmpp_recv->timeout_work,
msecs_to_jiffies(40000));
rmpp_recv->newwin += window_size(agent);
ack_recv(rmpp_recv, mad_recv_wc);
--
MST
More information about the general
mailing list