Re: [PATCH 0/4] WorkStruct: Shrink work_struct by two thirds

From: Andrew Morton
Date: Mon Nov 20 2006 - 14:17:57 EST


On Mon, 20 Nov 2006 14:27:13 +0000
David Howells <dhowells@xxxxxxxxxx> wrote:

> The workqueue struct is huge, and this limits it's usefulness. On a 64-bit
> architecture it's nearly 100 bytes in size, of which the timer_list is half.
> These patches shrink work_struct by 8 of the 12 words it ordinarily consumes.
> This is done by:
>
> (1) Splitting the timer out so that delayable work items are defined by a
> separate structure which incorporates a basic work_struct and a timer.
>
> (2) Folding the pending bit and wq_data data together
>
> (3) Removing the private data. This can almost always be derived from the
> address of the work_struct using container_of() and the selection of the
> work function. For the cases where the container of the work_struct may
> go away the moment the pending bit is cleared, it is made possible to
> defer the release of the structure by deferring the clearing of the
> pending bit.
>
>
> These patches reduce the size of the work_struct thusly:
>
> #WORDS 32-bit arch 64-bit arch
> =============== =============== ===============
> As is 12 48 bytes 96 bytes
> Non-delayable 4 16 bytes 32 bytes
> Delayable 10 40 bytes 80 bytes
>
> I've looked through most of the usages of work_structs, and I think that
> probably fewer than half the work_structs used actually require delayability,
> and I'm not sure that it's absolutely necessary in all cases.

via this:

> --- a/include/linux/workqueue.h
> +++ b/include/linux/workqueue.h
> @@ -17,6 +17,10 @@ struct work_struct {
> void (*func)(void *);
> void *data;
> void *wq_data;
> +};
> +
> +struct dwork_struct {
> + struct work_struct work;
> struct timer_list timer;
> };
>

Could we reduce the migration pain by leaving the work_struct as-is and
defining a new, leaner one and then incrementally migrating stuff over to
it?

struct work_struct_lite {
unsigned long pending;
struct list_head entry;
void (*func)(void *);
void *data;
void *wq_data;
};

struct work_struct {
struct work_struct_lite w;
struct timer_list timer;
}


or even

struct work_struct {
union {
struct work_struct_lite w;
struct {
unsigned long pending;
struct list_head entry;
void (*func)(void *);
void *data;
void *wq_data;
};
}
struct timer_list timer;
};


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/