[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