All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: torvalds@linux-foundation.org, mingo@elte.hu,
	peterz@infradead.org, awalls@radix.net,
	linux-kernel@vger.kernel.org, jeff@garzik.org,
	akpm@linux-foundation.org, jens.axboe@oracle.com,
	rusty@rustcorp.com.au, cl@linux-foundation.org,
	dhowells@redhat.com, arjan@linux.intel.com, avi@redhat.com,
	johannes@sipsolutions.net, andi@firstfloor.org
Cc: Tejun Heo <tj@kernel.org>, Arjan van de Ven <arjan@infradead.org>
Subject: [PATCH 34/40] async: kill original implementation
Date: Mon, 18 Jan 2010 09:57:46 +0900	[thread overview]
Message-ID: <1263776272-382-35-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1263776272-382-1-git-send-email-tj@kernel.org>

The original implementation doesn't have any user now.  Kill it.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Arjan van de Ven <arjan@infradead.org>
---
 drivers/base/core.c    |    1 -
 drivers/base/dd.c      |    1 -
 include/linux/async.h  |   13 --
 init/do_mounts.c       |    1 -
 init/main.c            |    1 -
 kernel/async.c         |  366 +-----------------------------------------------
 kernel/irq/autoprobe.c |    1 -
 kernel/module.c        |    2 -
 8 files changed, 3 insertions(+), 383 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 14774c9..20dbf59 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1743,6 +1743,5 @@ void device_shutdown(void)
 			dev->driver->shutdown(dev);
 		}
 	}
-	async_synchronize_full();
 	async_barrier();
 }
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 5c9c923..8c187db 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -178,7 +178,6 @@ void wait_for_device_probe(void)
 {
 	/* wait for the known devices to complete their probing */
 	wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
-	async_synchronize_full();
 	async_barrier();
 }
 EXPORT_SYMBOL_GPL(wait_for_device_probe);
diff --git a/include/linux/async.h b/include/linux/async.h
index 49658dc..da9eee7 100644
--- a/include/linux/async.h
+++ b/include/linux/async.h
@@ -11,21 +11,8 @@
  */
 
 #include <linux/types.h>
-#include <linux/list.h>
 #include <linux/workqueue.h>
 
-typedef u64 async_cookie_t;
-typedef void (async_func_ptr) (void *data, async_cookie_t cookie);
-
-extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data);
-extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data,
-					    struct list_head *list);
-extern void async_synchronize_full(void);
-extern void async_synchronize_full_domain(struct list_head *list);
-extern void async_synchronize_cookie(async_cookie_t cookie);
-extern void async_synchronize_cookie_domain(async_cookie_t cookie,
-					    struct list_head *list);
-
 typedef void (*async_func_t)(void *data);
 
 extern bool async_call(async_func_t func, void *data);
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 608ac17..f84f552 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -405,7 +405,6 @@ void __init prepare_namespace(void)
 		while (driver_probe_done() != 0 ||
 			(ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
 			msleep(100);
-		async_synchronize_full();
 		async_barrier();
 	}
 
diff --git a/init/main.c b/init/main.c
index e35dfdd..04c67fe 100644
--- a/init/main.c
+++ b/init/main.c
@@ -801,7 +801,6 @@ static noinline int init_post(void)
 	__releases(kernel_lock)
 {
 	/* need to finish all async __init code before freeing the memory */
-	async_synchronize_full();
 	async_barrier();
 	free_initmem();
 	unlock_kernel();
diff --git a/kernel/async.c b/kernel/async.c
index 4cd52bc..ddc2499 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -13,8 +13,6 @@
 
 /*
 
-Goals and Theory of Operation
-
 The primary goal of this feature is to reduce the kernel boot time,
 by doing various independent hardware delays and discovery operations
 decoupled and not strictly serialized.
@@ -25,377 +23,19 @@ asynchronously, out of order, while these operations still
 have their externally visible parts happen sequentially and in-order.
 (not unlike how out-of-order CPUs retire their instructions in order)
 
-Key to the asynchronous function call implementation is the concept of
-a "sequence cookie" (which, although it has an abstracted type, can be
-thought of as a monotonically incrementing number).
-
-The async core will assign each scheduled event such a sequence cookie and
-pass this to the called functions.
-
-The asynchronously called function should before doing a globally visible
-operation, such as registering device numbers, call the
-async_synchronize_cookie() function and pass in its own cookie. The
-async_synchronize_cookie() function will make sure that all asynchronous
-operations that were scheduled prior to the operation corresponding with the
-cookie have completed.
-
-Subsystem/driver initialization code that scheduled asynchronous probe
-functions, but which shares global resources with other drivers/subsystems
-that do not use the asynchronous call feature, need to do a full
-synchronization with the async_synchronize_full() function, before returning
-from their init function. This is to maintain strict ordering between the
-asynchronous and synchronous parts of the kernel.
+Parts can be executed in parallel should be scheduled via async_call()
+while parts which need to be executed sequentially to implement
+in-order appearance via async_call_ordered().
 
 */
 
 #include <linux/async.h>
-#include <linux/bug.h>
 #include <linux/module.h>
-#include <linux/wait.h>
 #include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/kthread.h>
 #include <linux/delay.h>
-#include <asm/atomic.h>
-
-static async_cookie_t next_cookie = 1;
-
-#define MAX_THREADS	256
-#define MAX_WORK	32768
-
-static LIST_HEAD(async_pending);
-static LIST_HEAD(async_running);
-static DEFINE_SPINLOCK(async_lock);
-
-static int async_enabled = 0;
-
-struct async_entry {
-	struct list_head list;
-	async_cookie_t   cookie;
-	async_func_ptr	 *func;
-	void             *data;
-	struct list_head *running;
-};
-
-static DECLARE_WAIT_QUEUE_HEAD(async_done);
-static DECLARE_WAIT_QUEUE_HEAD(async_new);
-
-static atomic_t entry_count;
-static atomic_t thread_count;
 
 extern int initcall_debug;
 
-
-/*
- * MUST be called with the lock held!
- */
-static async_cookie_t  __lowest_in_progress(struct list_head *running)
-{
-	struct async_entry *entry;
-
-	if (!list_empty(running)) {
-		entry = list_first_entry(running,
-			struct async_entry, list);
-		return entry->cookie;
-	}
-
-	list_for_each_entry(entry, &async_pending, list)
-		if (entry->running == running)
-			return entry->cookie;
-
-	return next_cookie;	/* "infinity" value */
-}
-
-static async_cookie_t  lowest_in_progress(struct list_head *running)
-{
-	unsigned long flags;
-	async_cookie_t ret;
-
-	spin_lock_irqsave(&async_lock, flags);
-	ret = __lowest_in_progress(running);
-	spin_unlock_irqrestore(&async_lock, flags);
-	return ret;
-}
-/*
- * pick the first pending entry and run it
- */
-static void run_one_entry(void)
-{
-	unsigned long flags;
-	struct async_entry *entry;
-	ktime_t calltime, delta, rettime;
-
-	/* 1) pick one task from the pending queue */
-
-	spin_lock_irqsave(&async_lock, flags);
-	if (list_empty(&async_pending))
-		goto out;
-	entry = list_first_entry(&async_pending, struct async_entry, list);
-
-	/* 2) move it to the running queue */
-	list_move_tail(&entry->list, entry->running);
-	spin_unlock_irqrestore(&async_lock, flags);
-
-	/* 3) run it (and print duration)*/
-	if (initcall_debug && system_state == SYSTEM_BOOTING) {
-		printk("calling  %lli_%pF @ %i\n", (long long)entry->cookie,
-			entry->func, task_pid_nr(current));
-		calltime = ktime_get();
-	}
-	entry->func(entry->data, entry->cookie);
-	if (initcall_debug && system_state == SYSTEM_BOOTING) {
-		rettime = ktime_get();
-		delta = ktime_sub(rettime, calltime);
-		printk("initcall %lli_%pF returned 0 after %lld usecs\n",
-			(long long)entry->cookie,
-			entry->func,
-			(long long)ktime_to_ns(delta) >> 10);
-	}
-
-	/* 4) remove it from the running queue */
-	spin_lock_irqsave(&async_lock, flags);
-	list_del(&entry->list);
-
-	/* 5) free the entry  */
-	kfree(entry);
-	atomic_dec(&entry_count);
-
-	spin_unlock_irqrestore(&async_lock, flags);
-
-	/* 6) wake up any waiters. */
-	wake_up(&async_done);
-	return;
-
-out:
-	spin_unlock_irqrestore(&async_lock, flags);
-}
-
-
-static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct list_head *running)
-{
-	struct async_entry *entry;
-	unsigned long flags;
-	async_cookie_t newcookie;
-	
-
-	/* allow irq-off callers */
-	entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC);
-
-	/*
-	 * If we're out of memory or if there's too much work
-	 * pending already, we execute synchronously.
-	 */
-	if (!async_enabled || !entry || atomic_read(&entry_count) > MAX_WORK) {
-		kfree(entry);
-		spin_lock_irqsave(&async_lock, flags);
-		newcookie = next_cookie++;
-		spin_unlock_irqrestore(&async_lock, flags);
-
-		/* low on memory.. run synchronously */
-		ptr(data, newcookie);
-		return newcookie;
-	}
-	entry->func = ptr;
-	entry->data = data;
-	entry->running = running;
-
-	spin_lock_irqsave(&async_lock, flags);
-	newcookie = entry->cookie = next_cookie++;
-	list_add_tail(&entry->list, &async_pending);
-	atomic_inc(&entry_count);
-	spin_unlock_irqrestore(&async_lock, flags);
-	wake_up(&async_new);
-	return newcookie;
-}
-
-/**
- * async_schedule - schedule a function for asynchronous execution
- * @ptr: function to execute asynchronously
- * @data: data pointer to pass to the function
- *
- * Returns an async_cookie_t that may be used for checkpointing later.
- * Note: This function may be called from atomic or non-atomic contexts.
- */
-async_cookie_t async_schedule(async_func_ptr *ptr, void *data)
-{
-	return __async_schedule(ptr, data, &async_running);
-}
-EXPORT_SYMBOL_GPL(async_schedule);
-
-/**
- * async_schedule_domain - schedule a function for asynchronous execution within a certain domain
- * @ptr: function to execute asynchronously
- * @data: data pointer to pass to the function
- * @running: running list for the domain
- *
- * Returns an async_cookie_t that may be used for checkpointing later.
- * @running may be used in the async_synchronize_*_domain() functions
- * to wait within a certain synchronization domain rather than globally.
- * A synchronization domain is specified via the running queue @running to use.
- * Note: This function may be called from atomic or non-atomic contexts.
- */
-async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data,
-				     struct list_head *running)
-{
-	return __async_schedule(ptr, data, running);
-}
-EXPORT_SYMBOL_GPL(async_schedule_domain);
-
-/**
- * async_synchronize_full - synchronize all asynchronous function calls
- *
- * This function waits until all asynchronous function calls have been done.
- */
-void async_synchronize_full(void)
-{
-	do {
-		async_synchronize_cookie(next_cookie);
-	} while (!list_empty(&async_running) || !list_empty(&async_pending));
-}
-EXPORT_SYMBOL_GPL(async_synchronize_full);
-
-/**
- * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain
- * @list: running list to synchronize on
- *
- * This function waits until all asynchronous function calls for the
- * synchronization domain specified by the running list @list have been done.
- */
-void async_synchronize_full_domain(struct list_head *list)
-{
-	async_synchronize_cookie_domain(next_cookie, list);
-}
-EXPORT_SYMBOL_GPL(async_synchronize_full_domain);
-
-/**
- * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing
- * @cookie: async_cookie_t to use as checkpoint
- * @running: running list to synchronize on
- *
- * This function waits until all asynchronous function calls for the
- * synchronization domain specified by the running list @list submitted
- * prior to @cookie have been done.
- */
-void async_synchronize_cookie_domain(async_cookie_t cookie,
-				     struct list_head *running)
-{
-	ktime_t starttime, delta, endtime;
-
-	if (initcall_debug && system_state == SYSTEM_BOOTING) {
-		printk("async_waiting @ %i\n", task_pid_nr(current));
-		starttime = ktime_get();
-	}
-
-	wait_event(async_done, lowest_in_progress(running) >= cookie);
-
-	if (initcall_debug && system_state == SYSTEM_BOOTING) {
-		endtime = ktime_get();
-		delta = ktime_sub(endtime, starttime);
-
-		printk("async_continuing @ %i after %lli usec\n",
-			task_pid_nr(current),
-			(long long)ktime_to_ns(delta) >> 10);
-	}
-}
-EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain);
-
-/**
- * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing
- * @cookie: async_cookie_t to use as checkpoint
- *
- * This function waits until all asynchronous function calls prior to @cookie
- * have been done.
- */
-void async_synchronize_cookie(async_cookie_t cookie)
-{
-	async_synchronize_cookie_domain(cookie, &async_running);
-}
-EXPORT_SYMBOL_GPL(async_synchronize_cookie);
-
-
-static int async_thread(void *unused)
-{
-	DECLARE_WAITQUEUE(wq, current);
-	add_wait_queue(&async_new, &wq);
-
-	while (!kthread_should_stop()) {
-		int ret = HZ;
-		set_current_state(TASK_INTERRUPTIBLE);
-		/*
-		 * check the list head without lock.. false positives
-		 * are dealt with inside run_one_entry() while holding
-		 * the lock.
-		 */
-		rmb();
-		if (!list_empty(&async_pending))
-			run_one_entry();
-		else
-			ret = schedule_timeout(HZ);
-
-		if (ret == 0) {
-			/*
-			 * we timed out, this means we as thread are redundant.
-			 * we sign off and die, but we to avoid any races there
-			 * is a last-straw check to see if work snuck in.
-			 */
-			atomic_dec(&thread_count);
-			wmb(); /* manager must see our departure first */
-			if (list_empty(&async_pending))
-				break;
-			/*
-			 * woops work came in between us timing out and us
-			 * signing off; we need to stay alive and keep working.
-			 */
-			atomic_inc(&thread_count);
-		}
-	}
-	remove_wait_queue(&async_new, &wq);
-
-	return 0;
-}
-
-static int async_manager_thread(void *unused)
-{
-	DECLARE_WAITQUEUE(wq, current);
-	add_wait_queue(&async_new, &wq);
-
-	while (!kthread_should_stop()) {
-		int tc, ec;
-
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		tc = atomic_read(&thread_count);
-		rmb();
-		ec = atomic_read(&entry_count);
-
-		while (tc < ec && tc < MAX_THREADS) {
-			if (IS_ERR(kthread_run(async_thread, NULL, "async/%i",
-					       tc))) {
-				msleep(100);
-				continue;
-			}
-			atomic_inc(&thread_count);
-			tc++;
-		}
-
-		schedule();
-	}
-	remove_wait_queue(&async_new, &wq);
-
-	return 0;
-}
-
-static int __init async_init(void)
-{
-	async_enabled =
-		!IS_ERR(kthread_run(async_manager_thread, NULL, "async/mgr"));
-
-	WARN_ON(!async_enabled);
-	return 0;
-}
-
-core_initcall(async_init);
-
 struct async_ent {
 	struct work_struct	work;
 	async_func_t		func;
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 39188cd..9d7f375 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -38,7 +38,6 @@ unsigned long probe_irq_on(void)
 	/*
 	 * quiesce the kernel, or at least the asynchronous portion
 	 */
-	async_synchronize_full();
 	async_barrier();
 	mutex_lock(&probing_active);
 	/*
diff --git a/kernel/module.c b/kernel/module.c
index 623a9b6..21c4c17 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -716,7 +716,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
 		mod->exit();
 	blocking_notifier_call_chain(&module_notify_list,
 				     MODULE_STATE_GOING, mod);
-	async_synchronize_full();
 	async_barrier();
 	mutex_lock(&module_mutex);
 	/* Store the name of the last unloaded module for diagnostic purposes */
@@ -2494,7 +2493,6 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
 				     MODULE_STATE_LIVE, mod);
 
 	/* We need to finish all async code before the module init sequence is done */
-	async_synchronize_full();
 	async_barrier();
 
 	mutex_lock(&module_mutex);
-- 
1.6.4.2


  parent reply	other threads:[~2010-01-18  0:54 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-18  0:57 [PATCHSET] concurrency managed workqueue, take#3 Tejun Heo
2010-01-18  0:57 ` [PATCH 01/40] sched: consult online mask instead of active in select_fallback_rq() Tejun Heo
2010-01-18 10:13   ` Peter Zijlstra
2010-01-18 11:26     ` Tejun Heo
2010-01-18  0:57 ` [PATCH 02/40] sched: rename preempt_notifiers to sched_notifiers and refactor implementation Tejun Heo
2010-01-18  0:57 ` [PATCH 03/40] sched: refactor try_to_wake_up() Tejun Heo
2010-01-18  0:57 ` [PATCH 04/40] sched: implement __set_cpus_allowed() Tejun Heo
2010-01-18  9:56   ` Peter Zijlstra
2010-01-18 11:22     ` Tejun Heo
2010-01-18 11:41       ` Peter Zijlstra
2010-01-19  1:07         ` Tejun Heo
2010-01-19  8:37           ` Peter Zijlstra
2010-01-20  8:35             ` Tejun Heo
2010-01-20  8:50               ` Peter Zijlstra
2010-01-20  9:00                 ` Tejun Heo
2010-01-20  8:59                   ` Peter Zijlstra
2010-01-24  8:18               ` Tejun Heo
2010-01-18  0:57 ` [PATCH 05/40] sched: make sched_notifiers unconditional Tejun Heo
2010-01-18  0:57 ` [PATCH 06/40] sched: add wakeup/sleep sched_notifiers and allow NULL notifier ops Tejun Heo
2010-01-18  9:57   ` Peter Zijlstra
2010-01-18 11:31     ` Tejun Heo
2010-01-18 12:49       ` Peter Zijlstra
2010-01-19  1:04         ` Tejun Heo
2010-01-19  8:28           ` Tejun Heo
2010-01-19  8:55             ` Peter Zijlstra
2010-01-20  8:47               ` Tejun Heo
2010-01-18  0:57 ` [PATCH 07/40] sched: implement try_to_wake_up_local() Tejun Heo
2010-01-18  0:57 ` [PATCH 08/40] acpi: use queue_work_on() instead of binding workqueue worker to cpu0 Tejun Heo
2010-01-18  0:57 ` [PATCH 09/40] stop_machine: reimplement without using workqueue Tejun Heo
2010-01-18  0:57 ` [PATCH 10/40] workqueue: misc/cosmetic updates Tejun Heo
2010-01-18  0:57 ` [PATCH 11/40] workqueue: merge feature parameters into flags Tejun Heo
2010-01-18  0:57 ` [PATCH 12/40] workqueue: define both bit position and mask for work flags Tejun Heo
2010-01-18  0:57 ` [PATCH 13/40] workqueue: separate out process_one_work() Tejun Heo
2010-01-18  0:57 ` [PATCH 14/40] workqueue: temporarily disable workqueue tracing Tejun Heo
2010-01-18  0:57 ` [PATCH 15/40] workqueue: kill cpu_populated_map Tejun Heo
2010-01-18  0:57 ` [PATCH 16/40] workqueue: update cwq alignement Tejun Heo
2010-01-18  0:57 ` [PATCH 17/40] workqueue: reimplement workqueue flushing using color coded works Tejun Heo
2010-01-18  0:57 ` [PATCH 18/40] workqueue: introduce worker Tejun Heo
2010-01-18  0:57 ` [PATCH 19/40] workqueue: reimplement work flushing using linked works Tejun Heo
2010-01-18  0:57 ` [PATCH 20/40] workqueue: implement per-cwq active work limit Tejun Heo
2010-01-18  0:57 ` [PATCH 21/40] workqueue: reimplement workqueue freeze using max_active Tejun Heo
2010-01-18  0:57 ` [PATCH 22/40] workqueue: introduce global cwq and unify cwq locks Tejun Heo
2010-01-18  0:57 ` [PATCH 23/40] workqueue: implement worker states Tejun Heo
2010-01-18  0:57 ` [PATCH 24/40] workqueue: reimplement CPU hotplugging support using trustee Tejun Heo
2010-01-18  0:57 ` [PATCH 25/40] workqueue: make single thread workqueue shared worker pool friendly Tejun Heo
2010-01-18  0:57 ` [PATCH 26/40] workqueue: use shared worklist and pool all workers per cpu Tejun Heo
2010-01-18  0:57 ` [PATCH 27/40] workqueue: implement concurrency managed dynamic worker pool Tejun Heo
2010-01-18  0:57 ` [PATCH 28/40] workqueue: increase max_active of keventd and kill current_is_keventd() Tejun Heo
2010-01-18  0:57 ` [PATCH 29/40] workqueue: add system_wq and system_single_wq Tejun Heo
2010-01-18  0:57 ` [PATCH 30/40] workqueue: implement work_busy() Tejun Heo
2010-01-18  2:52   ` Andy Walls
2010-01-18  5:41     ` Tejun Heo
2010-01-18  0:57 ` [PATCH 31/40] libata: take advantage of cmwq and remove concurrency limitations Tejun Heo
2010-01-18 15:48   ` Stefan Richter
2010-01-19  0:49     ` Tejun Heo
2010-01-18  0:57 ` [PATCH 32/40] async: introduce workqueue based alternative implementation Tejun Heo
2010-01-18  6:01   ` Arjan van de Ven
2010-01-18  8:49     ` Tejun Heo
2010-01-18 15:25       ` Arjan van de Ven
2010-01-19  0:57         ` Tejun Heo
2010-01-19  0:57           ` Arjan van de Ven
2010-01-19  7:56             ` Tejun Heo
2010-01-19 14:37               ` Arjan van de Ven
2010-01-20  0:19                 ` Tejun Heo
2010-01-20  0:31                   ` Arjan van de Ven
2010-01-20  2:08                     ` Tejun Heo
2010-01-20  6:03                       ` Arjan van de Ven
2010-01-20  8:24                         ` Tejun Heo
2010-01-22 10:59                           ` [PATCH] async: use workqueue for worker pool Tejun Heo
2010-01-18  0:57 ` [PATCH 33/40] async: convert async users to use the new implementation Tejun Heo
2010-01-18  0:57 ` Tejun Heo [this message]
2010-01-18  0:57 ` [PATCH 35/40] fscache: convert object to use workqueue instead of slow-work Tejun Heo
2010-02-12 18:03   ` David Howells
2010-02-13  5:43     ` Tejun Heo
2010-02-15 15:04       ` David Howells
2010-02-16  3:40         ` Tejun Heo
2010-02-16  3:59           ` Tejun Heo
2010-02-16 18:05           ` David Howells
2010-02-16 23:50             ` Tejun Heo
2010-02-18 11:50               ` David Howells
2010-02-18 12:33                 ` Tejun Heo
2010-01-18  0:57 ` [PATCH 36/40] fscache: convert operation " Tejun Heo
2010-01-18  0:57 ` [PATCH 37/40] fscache: drop references to slow-work Tejun Heo
2010-01-18  0:57 ` [PATCH 38/40] cifs: use workqueue instead of slow-work Tejun Heo
2010-01-19 12:20   ` Jeff Layton
2010-01-20  0:15     ` Tejun Heo
2010-01-20  0:56       ` Jeff Layton
2010-01-20  1:23         ` Tejun Heo
2010-01-22 11:14           ` [PATCH UPDATED " Tejun Heo
2010-01-22 11:45             ` Jeff Layton
2010-01-24  8:25               ` Tejun Heo
2010-01-24 12:13                 ` Jeff Layton
2010-01-25 15:25                   ` Tejun Heo
2010-01-18  0:57 ` [PATCH 39/40] gfs2: " Tejun Heo
2010-01-18  9:45   ` Steven Whitehouse
2010-01-18 11:24     ` Tejun Heo
2010-01-18 12:07       ` Steven Whitehouse
2010-01-19  1:00         ` Tejun Heo
2010-01-19  8:46           ` [PATCH UPDATED " Tejun Heo
2010-01-18  0:57 ` [PATCH 40/40] slow-work: kill it Tejun Heo
2010-01-18  1:03 ` perf-wq.c used to generate synthetic workload Tejun Heo
2010-01-18 16:13 ` [PATCHSET] concurrency managed workqueue, take#3 Stefan Richter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1263776272-382-35-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=arjan@infradead.org \
    --cc=arjan@linux.intel.com \
    --cc=avi@redhat.com \
    --cc=awalls@radix.net \
    --cc=cl@linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=jeff@garzik.org \
    --cc=jens.axboe@oracle.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.org \
    --cc=rusty@rustcorp.com.au \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.