From: Bill Huey (hui) <billh@gnuppy.monkey.org>
To: Ingo Molnar <mingo@elte.hu>
Cc: linux-kernel@vger.kernel.org,
Thomas Gleixner <tglx@linutronix.de>,
John Stultz <johnstul@us.ibm.com>,
"Paul E. McKenney" <paulmck@us.ibm.com>,
Dipankar Sarma <dipankar@in.ibm.com>,
Arjan van de Ven <arjan@infradead.org>,
"Bill Huey (hui)" <billh@gnuppy.monkey.org>
Subject: [PATCH] move put_task_struct() reaping into a thread [Re: 2.6.18-rt1]
Date: Wed, 20 Sep 2006 23:56:24 -0700 [thread overview]
Message-ID: <20060921065624.GA9841@gnuppy.monkey.org> (raw)
In-Reply-To: <20060920141907.GA30765@elte.hu>
[-- Attachment #1: Type: text/plain, Size: 399 bytes --]
On Wed, Sep 20, 2006 at 04:19:07PM +0200, Ingo Molnar wrote:
> I'm pleased to announce the 2.6.18-rt1 tree, which can be downloaded
> from the usual place:
...
> as usual, bugreports, fixes and suggestions are welcome,
Speaking of which...
This patch moves put_task_struct() reaping into a thread instead of an
RCU callback function as discussed with Esben publically and Ingo privately:
bill
[-- Attachment #2: mingo.patch.diff --]
[-- Type: text/plain, Size: 7711 bytes --]
============================================================
--- include/linux/init_task.h 7998a1b8676588d10f9ca05c681b99fc3ee869d1
+++ include/linux/init_task.h ca1562e79859bb022e6e9b140cc1edad1116fca9
@@ -77,6 +77,12 @@
extern struct group_info init_groups;
+#ifdef CONFIG_PREEMPT_RT
+#define INIT_DELAYED_DROP(a) .delayed_drop = LIST_HEAD_INIT(a.delayed_drop),
+#else
+#define INIT_DELAYED_DROP()
+#endif
+
/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -128,6 +134,7 @@
.fs_excl = ATOMIC_INIT(0), \
.posix_timer_list = NULL, \
.pi_lock = RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \
+ INIT_DELAYED_DROP(tsk) \
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
}
============================================================
--- include/linux/sched.h afe9eb8f7f85de2d61a92d35807386aa9d79a52e
+++ include/linux/sched.h e8907a986e9567267f290b504177faf6a96d4dbd
@@ -1176,6 +1176,9 @@
#ifdef CONFIG_TASK_DELAY_ACCT
struct task_delay_info *delays;
#endif
+#ifdef CONFIG_PREEMPT_RT
+ struct list_head delayed_drop;
+#endif
};
static inline pid_t process_group(struct task_struct *tsk)
@@ -1199,15 +1202,6 @@
extern void free_task(struct task_struct *tsk);
#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
-#ifdef CONFIG_PREEMPT_RT
-extern void __put_task_struct_cb(struct rcu_head *rhp);
-
-static inline void put_task_struct(struct task_struct *t)
-{
- if (atomic_dec_and_test(&t->usage))
- call_rcu(&t->rcu, __put_task_struct_cb);
-}
-#else
extern void __put_task_struct(struct task_struct *t);
static inline void put_task_struct(struct task_struct *t)
@@ -1215,7 +1209,6 @@
if (atomic_dec_and_test(&t->usage))
__put_task_struct(t);
}
-#endif
/*
* Per process flags
============================================================
--- kernel/exit.c 98f9cbf2db74c4cf03c792c75b63991856793263
+++ kernel/exit.c 5a6655dad5c3e72723c9b42adcecab12daf6b933
@@ -131,11 +131,6 @@
}
}
-static void delayed_put_task_struct(struct rcu_head *rhp)
-{
- put_task_struct(container_of(rhp, struct task_struct, rcu));
-}
-
void release_task(struct task_struct * p)
{
struct task_struct *leader;
@@ -172,7 +167,7 @@
write_unlock_irq(&tasklist_lock);
proc_flush_task(p);
release_thread(p);
- call_rcu(&p->rcu, delayed_put_task_struct);
+ put_task_struct(p);
p = leader;
if (unlikely(zap_leader))
============================================================
--- kernel/fork.c a26a13e186fd7a595fb24745cd6060c155cb4e10
+++ kernel/fork.c 5ea1f9118ab66e1668ab7f5e6549e184d1b05d74
@@ -75,7 +75,10 @@
*/
static DEFINE_PER_CPU(struct task_struct *, desched_task);
-static DEFINE_PER_CPU(struct list_head, delayed_drop_list);
+static DEFINE_PER_CPU(struct list_head, delayed_mmdrop_list);
+#ifdef CONFIG_PREEMPT_RT
+static DEFINE_PER_CPU(struct list_head, delayed_put_task_struct_list);
+#endif
int nr_processes(void)
{
@@ -120,28 +123,33 @@
}
EXPORT_SYMBOL(free_task);
+
#ifdef CONFIG_PREEMPT_RT
-void __put_task_struct_cb(struct rcu_head *rhp)
+/*
+ * We dont want to do complex work from the scheduler with preemption
+ * disabled, therefore we delay the work to a per-CPU worker thread.
+ */
+static void _wake_cpu_desched_task(void);
+
+void fastcall __put_task_struct(struct task_struct *task)
{
- struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
+ struct list_head *head;
- BUG_ON(atomic_read(&tsk->usage));
- WARN_ON(!(tsk->flags & PF_DEAD));
- WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
- WARN_ON(tsk == current);
+ head = &get_cpu_var(delayed_put_task_struct_list);
+ list_add_tail(&task->delayed_drop, head);
- security_task_free(tsk);
- free_uid(tsk->user);
- put_group_info(tsk->group_info);
- delayacct_tsk_free(tsk);
+ _wake_cpu_desched_task();
- if (!profile_handoff_task(tsk))
- free_task(tsk);
+ put_cpu_var(delayed_put_task_struct_list);
}
+/*
+ * Delay if this is in an atomic critical section otherwise inline the deallocation
+ */
+void __put_task_struct_inline(struct task_struct *tsk)
#else
-
void __put_task_struct(struct task_struct *tsk)
+#endif
{
WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
BUG_ON(atomic_read(&tsk->usage));
@@ -155,7 +163,6 @@
if (!profile_handoff_task(tsk))
free_task(tsk);
}
-#endif
void __init fork_init(unsigned long mempages)
{
@@ -189,8 +196,12 @@
init_task.signal->rlim[RLIMIT_SIGPENDING] =
init_task.signal->rlim[RLIMIT_NPROC];
- for (i = 0; i < NR_CPUS; i++)
- INIT_LIST_HEAD(&per_cpu(delayed_drop_list, i));
+ for (i = 0; i < NR_CPUS; i++) {
+ INIT_LIST_HEAD(&per_cpu(delayed_mmdrop_list, i));
+#ifdef CONFIG_PREEMPT_RT
+ INIT_LIST_HEAD(&per_cpu(delayed_put_task_struct_list, i));
+#endif
+ }
}
static struct task_struct *dup_task_struct(struct task_struct *orig)
@@ -1123,6 +1134,9 @@
#endif
rt_mutex_init_task(p);
+#ifdef CONFIG_PREEMPT_RT
+ INIT_LIST_HEAD(&p->delayed_drop);
+#endif
#ifdef CONFIG_DEBUG_MUTEXES
p->blocked_on = NULL; /* not blocked yet */
@@ -1740,24 +1754,58 @@
return err;
}
+static void _wake_cpu_desched_task(void)
+{
+ struct task_struct *desched_task;
+
+ desched_task = __get_cpu_var(desched_task);
+ if (desched_task)
+ wake_up_process(desched_task);
+}
+
+#ifdef CONFIG_PREEMPT_RT
+static int put_task_struct_complete(void)
+{
+ struct list_head *head;
+ int ret = 0;
+
+ head = &get_cpu_var(delayed_put_task_struct_list);
+ while (!list_empty(head)) {
+ struct task_struct *task = list_entry(head->next,
+ struct task_struct, delayed_drop);
+ list_del(&task->delayed_drop);
+ put_cpu_var(delayed_put_task_struct_list);
+
+ __put_task_struct_inline(task); /* call the original function to perform the operation */
+ ret = 1;
+
+ head = &get_cpu_var(delayed_put_task_struct_list);
+ }
+ put_cpu_var(delayed_put_task_struct_list);
+
+ return ret;
+}
+
+#endif
+
static int mmdrop_complete(void)
{
struct list_head *head;
int ret = 0;
- head = &get_cpu_var(delayed_drop_list);
+ head = &get_cpu_var(delayed_mmdrop_list);
while (!list_empty(head)) {
struct mm_struct *mm = list_entry(head->next,
struct mm_struct, delayed_drop);
list_del(&mm->delayed_drop);
- put_cpu_var(delayed_drop_list);
+ put_cpu_var(delayed_mmdrop_list);
__mmdrop(mm);
ret = 1;
- head = &get_cpu_var(delayed_drop_list);
+ head = &get_cpu_var(delayed_mmdrop_list);
}
- put_cpu_var(delayed_drop_list);
+ put_cpu_var(delayed_mmdrop_list);
return ret;
}
@@ -1768,15 +1816,14 @@
*/
void fastcall __mmdrop_delayed(struct mm_struct *mm)
{
- struct task_struct *desched_task;
struct list_head *head;
- head = &get_cpu_var(delayed_drop_list);
+ head = &get_cpu_var(delayed_mmdrop_list);
list_add_tail(&mm->delayed_drop, head);
- desched_task = __get_cpu_var(desched_task);
- if (desched_task)
- wake_up_process(desched_task);
- put_cpu_var(delayed_drop_list);
+
+ _wake_cpu_desched_task();
+
+ put_cpu_var(delayed_mmdrop_list);
}
static int desched_thread(void * __bind_cpu)
@@ -1790,6 +1837,9 @@
if (mmdrop_complete())
continue;
+ if (put_task_struct_complete())
+ continue;
+
schedule();
/* This must be called from time to time on ia64, and is a no-op on other archs.
@@ -1814,7 +1864,10 @@
case CPU_UP_PREPARE:
BUG_ON(per_cpu(desched_task, hotcpu));
- INIT_LIST_HEAD(&per_cpu(delayed_drop_list, hotcpu));
+ INIT_LIST_HEAD(&per_cpu(delayed_mmdrop_list, hotcpu));
+#ifdef CONFIG_PREEMPT_RT
+ INIT_LIST_HEAD(&per_cpu(delayed_put_task_struct_list, hotcpu));
+#endif
p = kthread_create(desched_thread, hcpu, "desched/%d", hotcpu);
if (IS_ERR(p)) {
printk("desched_thread for %i failed\n", hotcpu);
next prev parent reply other threads:[~2006-09-21 6:56 UTC|newest]
Thread overview: 101+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-20 14:19 2.6.18-rt1 Ingo Molnar
2006-09-20 16:50 ` 2.6.18-rt1 Gene Heskett
2006-09-20 16:58 ` 2.6.18-rt1 Ingo Molnar
2006-09-20 17:33 ` 2.6.18-rt1 Gene Heskett
2006-09-20 18:34 ` 2.6.18-rt1 Gene Heskett
2006-09-20 17:00 ` 2.6.18-rt1 Daniel Walker
2006-09-20 17:38 ` 2.6.18-rt1 Paul E. McKenney
2006-09-20 17:41 ` 2.6.18-rt1 Daniel Walker
2006-09-20 18:23 ` 2.6.18-rt1 Gene Heskett
2006-09-20 18:25 ` 2.6.18-rt1 Paul E. McKenney
2006-09-20 18:34 ` 2.6.18-rt1 Daniel Walker
2006-09-20 20:06 ` 2.6.18-rt1 Paul E. McKenney
2006-09-20 21:38 ` 2.6.18-rt1 Gene Heskett
2006-09-20 20:17 ` 2.6.18-rt1 Gene Heskett
2006-09-20 18:36 ` 2.6.18-rt1 Gene Heskett
2006-09-20 18:47 ` 2.6.18-rt1 Thomas Gleixner
2006-09-20 19:20 ` 2.6.18-rt1 Thomas Gleixner
2006-09-20 19:46 ` 2.6.18-rt1 Ingo Molnar
2006-09-20 20:19 ` 2.6.18-rt1 Daniel Walker
2006-09-20 20:14 ` 2.6.18-rt1 Ingo Molnar
2006-09-20 20:31 ` 2.6.18-rt1 Daniel Walker
2006-09-21 19:02 ` 2.6.18-rt1 Ingo Molnar
2006-09-21 19:18 ` 2.6.18-rt1 Daniel Walker
2006-09-22 14:42 ` 2.6.18-rt1 Daniel Walker
2006-09-27 8:36 ` 2.6.18-rt1 Ingo Molnar
2006-09-21 8:04 ` 2.6.18-rt1 Deepak Saxena
2006-09-21 8:04 ` 2.6.18-rt1 Ingo Molnar
2006-09-21 8:24 ` 2.6.18-rt1 Deepak Saxena
2006-09-22 2:19 ` 2.6.18-rt1 john cooper
2006-09-22 6:36 ` 2.6.18-rt1 Lennert Buytenhek
2006-09-22 11:56 ` 2.6.18-rt1 Ingo Molnar
2006-09-27 13:10 ` 2.6.18-rt4 john cooper
2006-09-27 13:09 ` 2.6.18-rt4 Ingo Molnar
2006-09-20 18:56 ` 2.6.18-rt1 K.R. Foley
2006-09-20 19:49 ` 2.6.18-rt1 Ingo Molnar
2006-09-20 20:33 ` 2.6.18-rt1 K.R. Foley
2006-09-20 20:41 ` 2.6.18-rt1 Thomas Gleixner
2006-09-20 20:50 ` 2.6.18-rt1 K.R. Foley
2006-09-21 19:16 ` 2.6.18-rt1 john stultz
2006-09-22 2:18 ` 2.6.18-rt1 K.R. Foley
2006-09-22 11:58 ` 2.6.18-rt1 Ingo Molnar
2006-09-28 0:42 ` 2.6.18-rt1 john stultz
2006-09-28 22:48 ` 2.6.18-rt1 john stultz
2006-09-29 2:09 ` 2.6.18-rt1 K.R. Foley
2006-09-29 12:24 ` 2.6.18-rt1 Ingo Molnar
2006-09-29 12:40 ` 2.6.18-rt1 Ingo Molnar
2006-09-20 19:58 ` 2.6.18-rt1 Thomas Gleixner
2006-09-20 20:34 ` 2.6.18-rt1 K.R. Foley
2006-09-20 19:38 ` 2.6.18-rt1 Mark Knecht
2006-09-20 20:27 ` 2.6.18-rt1 Mark Knecht
2006-09-22 14:14 ` 2.6.18-rt1 Lee Revell
2006-09-20 20:54 ` 2.6.18-rt1 Michal Piotrowski
2006-09-20 22:07 ` 2.6.18-rt1 Michal Piotrowski
2006-09-20 22:26 ` 2.6.18-rt1 Michal Piotrowski
2006-09-21 6:56 ` Bill Huey [this message]
2006-09-21 6:54 ` [PATCH] move put_task_struct() reaping into a thread [Re: 2.6.18-rt1] Ingo Molnar
2006-09-21 7:18 ` Bill Huey
2006-09-21 7:16 ` Ingo Molnar
2006-09-21 7:32 ` Bill Huey
2006-09-21 7:29 ` Ingo Molnar
2006-09-21 7:48 ` Bill Huey
2006-09-21 7:56 ` Ingo Molnar
2006-09-21 8:13 ` Bill Huey
2006-09-21 12:23 ` Esben Nielsen
2006-09-21 12:56 ` Ingo Molnar
2006-09-21 7:27 ` Bill Huey
2006-09-21 7:22 ` Ingo Molnar
2006-09-21 7:35 ` Bill Huey
2006-09-21 7:31 ` Ingo Molnar
2006-09-21 7:52 ` Bill Huey
2006-09-27 2:55 ` Eric W. Biederman
2006-09-27 5:08 ` Bill Huey
2006-09-27 6:02 ` Eric W. Biederman
2006-09-27 6:34 ` Bill Huey
2006-09-27 7:29 ` Eric W. Biederman
2006-09-27 9:01 ` Ingo Molnar
2006-09-27 13:59 ` Eric W. Biederman
2006-09-27 14:06 ` Ingo Molnar
2006-09-27 16:18 ` Paul E. McKenney
2006-09-27 9:08 ` Ingo Molnar
2006-09-27 9:09 ` Bill Huey
2006-09-27 9:05 ` Ingo Molnar
2006-09-27 20:28 ` Esben Nielsen
2006-09-27 8:57 ` Ingo Molnar
2006-09-27 9:14 ` Bill Huey
2006-09-27 9:15 ` Ingo Molnar
2006-09-25 9:53 ` 2.6.18-rt1 Florian Schmidt
2006-09-26 7:57 ` 2.6.18-rt1 Florian Schmidt
2006-09-25 16:12 ` 2.6.18-rt1 Mike Kravetz
2006-09-27 8:34 ` 2.6.18-rt1 Ingo Molnar
2006-09-30 18:06 ` 2.6.18-rt1 Lee Revell
2006-09-30 18:18 ` 2.6.18-rt1 Dipankar Sarma
2006-09-30 18:25 ` 2.6.18-rt1 Lee Revell
2006-10-13 21:18 ` 2.6.18-rt1 Karsten Wiese
2006-10-13 21:20 ` 2.6.18-rt1 Lee Revell
2006-10-13 21:24 ` 2.6.18-rt1 Dipankar Sarma
2006-10-13 22:12 ` 2.6.18-rt1 Lee Revell
2006-10-13 22:16 ` 2.6.18-rt1 Dipankar Sarma
2006-10-17 14:46 ` 2.6.18-rt1 Lee Revell
2006-10-18 8:34 ` 2.6.18-rt1 Ingo Molnar
2006-10-18 7:12 ` 2.6.18-rt1 Ingo Molnar
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=20060921065624.GA9841@gnuppy.monkey.org \
--to=billh@gnuppy.monkey.org \
--cc=arjan@infradead.org \
--cc=dipankar@in.ibm.com \
--cc=johnstul@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=paulmck@us.ibm.com \
--cc=tglx@linutronix.de \
/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