Email: <tj AT kernel DOT org>
Task: Convert create_workqueue() usages in drivers/staging/rtl8192[eu]
There are four usages of create_workqueue() in rtl8192[eu] drivers. Convert them to use system_wq or alloc_workqueue(). create_workqueue() maps to per-cpu workqueue (this is the default flavor) with WQ_MEM_RECLAIM set and maximum concurrency of 1, so a workqueue created with create_workqueue() has the following properties.
- Work items are guaranteed to be executed regardless of memory pressure and thus can be depended upon from memory reclaim.
- Work items queued to a specific CPU using queue_work_on() will execute on that cpu. Work items queued via queue_work() will prefer the queueing CPU but the locality is not guaranteed.
- Work items queued on the same CPU will be executed in order; however, there's no ordering defined between work items executing on different CPUs.
The conversion should pick the option which minimally fits the use case. The order of preferences is
- Other system_*wq which fits the usage minimally.
- alloc_workqueue() with the minimal attributes specified.
The questions to ask during conversion are roughly
- If the work items hosted by a workqueue are depeneded upon during memory reclaim, it needs to stay a separate workqueue and retain WQ_MEM_RECLAIM. Note that a workqueue with WQ_MEM_RECLAIM only guarantees forward progress of a single work item at a given time meaning that if a work item which is depended upon during memory reclaim depends on another work item, the two need to put into separate workqueues, each with WQ_MEM_RECLAIM. Hint: Wireless drivers aren't depended upon during memory reclaim.
- Do the work items need other specific attributes - WQ_HIGHPRI, WQ_CPU_INTENSIVE and so on? Please consult Documentation/workqueue.txt on details on each attribute.
- Do the work items need to be flushed as a whole? e.g. if work items are created dynamically and freed on execution but need to be flushed, they need a dedicated workqueue to serve as a flush domain.
- Do the work items need to be limited in concurrency? If the work items are created dynamically and can be numerous, they need to be queued on a separate workqueue with a reasonable concurrency limit. Note that the concurrency limit is per cpu or numa node and exist primarily to prevent run-away work items from overwhelming the system.
Occasionally, work items on a per-cpu workqueue may require execution ordering requiring the concurrency to be set at 1.
Task: Convert create_singlethread_workqueue() usages in drivers/staging/octeon/ethernet.c
Similar to "Convert create_workqueue() usages in drivers/staging/rtl8192[eu]". The followings are the extras to consider for singlethread workqueues.
- create_singlethread_workqueue() maps to alloc_ordered_workqueue() with WQ_MEM_RECLAIM set, so it creates a workqueue which executes work items one at a time in the queueing order and is guaranteed to make forward progress under memory pressure.
- It used to be that create_workqueue() was a lot more expensive than create_singlethread_workqueue(), so it isn't clear whether the usages are because they needed any of the above attributes or to avoid the overhead of per-cpu workqueues.