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

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

 



On Tue, Jul 16, 2013 at 12:35 PM, Hauke Mehrtens <hauke@xxxxxxxxxx> wrote:
> On 07/16/2013 02:57 PM, Johannes Berg wrote:
>> 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)
>
> Why not do a check for #ifndef WQ_UNBOUND that way we do not get that
> many problems when someone tries a kernel that already backported this.

Not sure I understood this. I tried though.

>> +#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);          \
>> +})

BTW I believe using (perens)(like)(this) seems to help avoid
re-dup'ing the define effect see my last patch. Not sure if that helps
here.

>> +#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
>
> The #undef destroy_workqueue in compat-3.3.c does not look nice to me.
>
> What about this and then call orig_destroy_workqueue(wq)?
>
> static inline void orig_destroy_workqueue(struct workqueue_struct *wq)
> {
>         destroy_workqueue(wq);
> }
> #define destroy_workqueue(wq) backport_destroy_workqueue(wq)

I didn't get this either :(

>> +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];
>> +};
>> +

Do we really need this on the backport?

>> +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);

For now I'm using a slightly modified version of this to get passed
through some linux-next tags, sorry I've been caught up. I'll post
what I have just now.

  Luis
--
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