mirror of https://lore.kernel.org/lkml/
 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-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
2010-02-12 18:03 ` [PATCH 35/40] fscache: convert object to use workqueue instead of slow-work 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

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome