[RFC/RFT] backport: backport sprintf-style workqueue naming

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Johannes Berg <johannes.berg@xxxxxxxxx>

Since kernel version 3.3, workqueue names could be
sprintf'ed instead of just pointing to a name. This
wasn't used a lot so never needed to be backported,
but now it's used everywhere. Backport this API.

Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx>
---
 backport/backport-include/linux/workqueue.h | 47 ++++++++++++++++----
 backport/compat/compat-3.3.c                | 69 +++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 8 deletions(-)

diff --git a/backport/backport-include/linux/workqueue.h b/backport/backport-include/linux/workqueue.h
index 9958715..54c9090 100644
--- a/backport/backport-include/linux/workqueue.h
+++ b/backport/backport-include/linux/workqueue.h
@@ -14,16 +14,47 @@ bool mod_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork,
 #define create_freezable_workqueue create_freezeable_workqueue
 #endif
 
-#ifndef alloc_ordered_workqueue
-#define alloc_ordered_workqueue(name, flags) create_singlethread_workqueue(name)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+#define WQ_UNBOUND	0
 #endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
-#define alloc_workqueue(name, flags, max_active) __create_workqueue(name, flags, max_active)
+#define __WQ_ORDERED	0
+/*
+ * commit b196be89cdc14a88cc637cdad845a75c5886c82d
+ * Author: Tejun Heo <tj@xxxxxxxxxx>
+ * Date:   Tue Jan 10 15:11:35 2012 -0800
+ *
+ *     workqueue: make alloc_workqueue() take printf fmt and args for name
+ */
+struct workqueue_struct *
+backport_alloc_workqueue(const char *fmt, unsigned int flags,
+			 int max_active, struct lock_class_key *key,
+			 const char *lock_name, ...);
+#undef alloc_workqueue
+#ifdef CONFIG_LOCKDEP
+#define alloc_workqueue(fmt, flags, max_active, args...)		\
+({									\
+	static struct lock_class_key __key;				\
+	const char *__lock_name;					\
+									\
+	if (__builtin_constant_p(fmt))					\
+		__lock_name = (fmt);					\
+	else								\
+		__lock_name = #fmt;					\
+									\
+	backport_alloc_workqueue((fmt), (flags), (max_active),		\
+				 &__key, __lock_name, ##args);		\
+})
+#else
+#define alloc_workqueue(fmt, flags, max_active, args...)		\
+	backport_alloc_workqueue((fmt), (flags), (max_active),		\
+				 NULL, NULL, ##args)
 #endif
-
-#ifndef alloc_workqueue
-#define alloc_workqueue(name, flags, max_active) __create_workqueue(name, flags, max_active, 0)
+#undef alloc_ordered_workqueue
+#define alloc_ordered_workqueue(fmt, flags, args...) \
+	alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args)
+#define destroy_workqueue backport_destroy_workqueue
+void backport_destroy_workqueue(struct workqueue_struct *wq);
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
diff --git a/backport/compat/compat-3.3.c b/backport/compat/compat-3.3.c
index a44f59d..d86b40e 100644
--- a/backport/compat/compat-3.3.c
+++ b/backport/compat/compat-3.3.c
@@ -12,6 +12,7 @@
 #include <linux/version.h>
 #include <linux/skbuff.h>
 #include <linux/module.h>
+#include <linux/workqueue.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
 
@@ -171,3 +172,71 @@ out:
 	return n;
 }
 EXPORT_SYMBOL_GPL(__pskb_copy);
+
+static DEFINE_SPINLOCK(wq_name_lock);
+static struct list_head wq_name_list;
+
+struct wq_name {
+	struct list_head list;
+	struct workqueue_struct *wq;
+	char name[24];
+};
+
+struct workqueue_struct *
+backport_alloc_workqueue(const char *fmt, unsigned int flags,
+			 int max_active, struct lock_class_key *key,
+			 const char *lock_name, ...)
+{
+	struct workqueue_struct *wq;
+	struct wq_name *n = kzalloc(sizeof(*n), GFP_KERNEL);
+	va_list args;
+
+	if (!n)
+		return NULL;
+
+	va_start(args, lock_name);
+	vsnprintf(n->name, sizeof(n->name), fmt, args);
+	va_end(args);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+	wq = __create_workqueue_key(n->name, max_active == 1, 0,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+				    0,
+#endif
+				    key, lock_name);
+#else	                        
+	wq = __alloc_workqueue_key(n->name, flags, max_active, key, lock_name);
+#endif
+	if (!wq) {
+		kfree(n);
+		return NULL;
+	}
+
+	n->wq = wq;
+	spin_lock(&wq_name_lock);
+	list_add(&n->list, &wq_name_list);
+	spin_unlock(&wq_name_lock);
+
+	return wq;
+}
+EXPORT_SYMBOL_GPL(backport_alloc_workqueue);
+
+void backport_destroy_workqueue(struct workqueue_struct *wq)
+{
+	struct wq_name *n, *tmp;
+
+	/* call original */
+#undef destroy_workqueue
+	destroy_workqueue(wq);
+
+	spin_lock(&wq_name_lock);
+	list_for_each_entry_safe(n, tmp, &wq_name_list, list) {
+		if (n->wq == wq) {
+			list_del(&n->list);
+			kfree(n);
+			break;
+		}
+	}
+	spin_unlock(&wq_name_lock);
+}
+EXPORT_SYMBOL_GPL(backport_destroy_workqueue);
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe backports" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux