* [PATCH -rt] update kmap_atomic on !HIGHMEM
@ 2006-12-27 19:35 Daniel Walker
2006-12-27 20:54 ` Ingo Molnar
2006-12-27 21:25 ` Ingo Molnar
0 siblings, 2 replies; 10+ messages in thread
From: Daniel Walker @ 2006-12-27 19:35 UTC (permalink / raw)
To: mingo; +Cc: linux-kernel
I got some scheduling while atomic on x86-64 , and since x86-64 doesn't seem
to have HIGHMEM there's no workaround for kmap_atomic() .
This patch adds the same as i386 HIGHMEM for !HIGHMEM.
Signed-Off-By: Daniel Walker <dwalker@mvista.com>
---
include/linux/highmem.h | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletion(-)
Index: linux-2.6.19/include/linux/highmem.h
===================================================================
--- linux-2.6.19.orig/include/linux/highmem.h
+++ linux-2.6.19/include/linux/highmem.h
@@ -42,13 +42,25 @@ static inline void *kmap(struct page *pa
#define kunmap(page) do { (void) (page); } while (0)
+#ifdef CONFIG_PREEMPT_RT
+/*
+ * kmap and kmunmap are above, and they don't really do anything
+ * interesting.
+ */
+# define kmap_atomic(page, idx) kmap(page)
+# define kmap_atomic_pfn(pfn, idx) kmap(pfn_to_page(pfn))
+# define kunmap_atomic(kvaddr, idx) kunmap(kvaddr)
+#else
#define kmap_atomic(page, idx) \
({ pagefault_disable(); page_address(page); })
#define kunmap_atomic(addr, idx) do { pagefault_enable(); } while (0)
#define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx))
-#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
#endif
+#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
+
+#endif /* ARCH_HAS_KMAP */
+
#endif /* CONFIG_HIGHMEM */
/* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
--
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 19:35 [PATCH -rt] update kmap_atomic on !HIGHMEM Daniel Walker @ 2006-12-27 20:54 ` Ingo Molnar 2006-12-27 21:04 ` Daniel Walker 2006-12-27 21:25 ` Ingo Molnar 1 sibling, 1 reply; 10+ messages in thread From: Ingo Molnar @ 2006-12-27 20:54 UTC (permalink / raw) To: Daniel Walker; +Cc: linux-kernel * Daniel Walker <dwalker@mvista.com> wrote: > I got some scheduling while atomic on x86-64 , [...] please post those messages too. Ingo ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 20:54 ` Ingo Molnar @ 2006-12-27 21:04 ` Daniel Walker 0 siblings, 0 replies; 10+ messages in thread From: Daniel Walker @ 2006-12-27 21:04 UTC (permalink / raw) To: Ingo Molnar; +Cc: linux-kernel On Wed, 2006-12-27 at 21:54 +0100, Ingo Molnar wrote: > * Daniel Walker <dwalker@mvista.com> wrote: > > > I got some scheduling while atomic on x86-64 , [...] > > please post those messages too. > > Ingo Ok .. This is from 2.6.20-rc2-rt0 tho . BUG: scheduling while atomic: kswapd0/0x00000001/244, CPU#1 Call Trace: [<ffffffff80268f80>] __sched_text_start+0xb0/0xb9f [<ffffffff8028fa8c>] task_rq_lock+0x4c/0x90 [<ffffffff8028fdd3>] rt_mutex_setprio+0xb3/0xd0 [<ffffffff802bb2c4>] add_preempt_count+0x14/0xf0 [<ffffffff802b1353>] task_blocks_on_rt_mutex+0x163/0x1d0 [<ffffffff80269da5>] schedule+0xe5/0x110 [<ffffffff8026afa2>] rt_spin_lock_slowlock+0x102/0x1b0 [<ffffffff802c9b71>] swap_duplicate+0x51/0x100 [<ffffffff802c94b2>] move_to_swap_cache+0x32/0x70 [<ffffffff802cf4ba>] shmem_writepage+0xaa/0x1a0 [<ffffffff802c35e0>] shrink_inactive_list+0x430/0x950 [<ffffffff802134f4>] shrink_zone+0xe4/0x110 [<ffffffff8025e629>] kswapd+0x379/0x510 [<ffffffff802a8270>] autoremove_wake_function+0x0/0x30 [<ffffffff8025e2b0>] kswapd+0x0/0x510 [<ffffffff80234c89>] kthread+0xd9/0x120 [<ffffffff8022981c>] schedule_tail+0xdc/0x130 [<ffffffff802a80a0>] keventd_create_kthread+0x0/0x90 [<ffffffff80265ef8>] child_rip+0xa/0x12 [<ffffffff802a80a0>] keventd_create_kthread+0x0/0x90 [<ffffffff80234bb0>] kthread+0x0/0x120 [<ffffffff80265eee>] child_rip+0x0/0x12 --------------------------- | preempt count: 00000001 ] | 1-level deep critical section nesting: ---------------------------------------- .. [<ffffffff802cc111>] .... shmem_swp_entry+0x31/0x1a0 .....[<00000000>] .. ( <= 0x0) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 19:35 [PATCH -rt] update kmap_atomic on !HIGHMEM Daniel Walker 2006-12-27 20:54 ` Ingo Molnar @ 2006-12-27 21:25 ` Ingo Molnar 2006-12-27 21:31 ` Ingo Molnar ` (3 more replies) 1 sibling, 4 replies; 10+ messages in thread From: Ingo Molnar @ 2006-12-27 21:25 UTC (permalink / raw) To: Daniel Walker; +Cc: linux-kernel * Daniel Walker <dwalker@mvista.com> wrote: > I got some scheduling while atomic on x86-64 , and since x86-64 > doesn't seem to have HIGHMEM there's no workaround for kmap_atomic() . > > This patch adds the same as i386 HIGHMEM for !HIGHMEM. the problem is that this does not disable pagefaulting while kmap-atomic. Could you try the patch below, does it solve the assert? Ingo -------------------------> Subject: [patch] clean up the page fault disabling logic From: Ingo Molnar <mingo@elte.hu> decouple the pagefault-disabled logic from the preempt count. Signed-off-by: Ingo Molnar <mingo@elte.hu> --- arch/arm/mm/fault.c | 2 +- arch/i386/mm/fault.c | 2 +- arch/mips/mm/fault.c | 2 +- arch/powerpc/mm/fault.c | 2 +- arch/x86_64/mm/fault.c | 2 +- include/linux/sched.h | 1 + include/linux/uaccess.h | 33 +++------------------------------ kernel/fork.c | 1 + mm/memory.c | 20 ++++++++++++++++++++ 9 files changed, 30 insertions(+), 35 deletions(-) Index: linux/arch/arm/mm/fault.c =================================================================== --- linux.orig/arch/arm/mm/fault.c +++ linux/arch/arm/mm/fault.c @@ -230,7 +230,7 @@ do_page_fault(unsigned long addr, unsign * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_atomic() || !mm || current->pagefault_disabled) goto no_context; /* Index: linux/arch/i386/mm/fault.c =================================================================== --- linux.orig/arch/i386/mm/fault.c +++ linux/arch/i386/mm/fault.c @@ -382,7 +382,7 @@ fastcall notrace void __kprobes do_page_ * If we're in an interrupt, have no user context or are running in an * atomic region then we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_atomic() || !mm || current->pagefault_disabled) goto bad_area_nosemaphore; /* When running in the kernel we expect faults to occur only to Index: linux/arch/mips/mm/fault.c =================================================================== --- linux.orig/arch/mips/mm/fault.c +++ linux/arch/mips/mm/fault.c @@ -69,7 +69,7 @@ asmlinkage void do_page_fault(struct pt_ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (in_atomic() || !mm || current->pagefault_disabled) goto bad_area_nosemaphore; down_read(&mm->mmap_sem); Index: linux/arch/powerpc/mm/fault.c =================================================================== --- linux.orig/arch/powerpc/mm/fault.c +++ linux/arch/powerpc/mm/fault.c @@ -196,7 +196,7 @@ int __kprobes notrace do_page_fault(stru } #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ - if (in_atomic() || mm == NULL) { + if (in_atomic() || mm == NULL || current->pagefault_disabled) { if (!user_mode(regs)) return SIGSEGV; /* in_atomic() in user mode is really bad, Index: linux/arch/x86_64/mm/fault.c =================================================================== --- linux.orig/arch/x86_64/mm/fault.c +++ linux/arch/x86_64/mm/fault.c @@ -405,7 +405,7 @@ asmlinkage void __kprobes do_page_fault( * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (unlikely(in_atomic() || !mm)) + if (unlikely(in_atomic() || !mm || current->pagefault_disabled)) goto bad_area_nosemaphore; again: Index: linux/include/linux/sched.h =================================================================== --- linux.orig/include/linux/sched.h +++ linux/include/linux/sched.h @@ -1147,6 +1147,7 @@ struct task_struct { /* mutex deadlock detection */ struct mutex_waiter *blocked_on; #endif + int pagefault_disabled; #ifdef CONFIG_TRACE_IRQFLAGS unsigned int irq_events; int hardirqs_enabled; Index: linux/include/linux/uaccess.h =================================================================== --- linux.orig/include/linux/uaccess.h +++ linux/include/linux/uaccess.h @@ -6,37 +6,10 @@ /* * These routines enable/disable the pagefault handler in that - * it will not take any locks and go straight to the fixup table. - * - * They have great resemblance to the preempt_disable/enable calls - * and in fact they are identical; this is because currently there is - * no other way to make the pagefault handlers do this. So we do - * disable preemption but we don't necessarily care about that. + * it will not take any MM locks and go straight to the fixup table. */ -static inline void pagefault_disable(void) -{ - inc_preempt_count(); - /* - * make sure to have issued the store before a pagefault - * can hit. - */ - barrier(); -} - -static inline void pagefault_enable(void) -{ - /* - * make sure to issue those last loads/stores before enabling - * the pagefault handler again. - */ - barrier(); - dec_preempt_count(); - /* - * make sure we do.. - */ - barrier(); - preempt_check_resched(); -} +extern void pagefault_disable(void); +extern void pagefault_enable(void); #ifndef ARCH_HAS_NOCACHE_UACCESS Index: linux/kernel/fork.c =================================================================== --- linux.orig/kernel/fork.c +++ linux/kernel/fork.c @@ -1128,6 +1128,7 @@ static struct task_struct *copy_process( p->hardirq_context = 0; p->softirq_context = 0; #endif + p->pagefault_disabled = 0; #ifdef CONFIG_LOCKDEP p->lockdep_depth = 0; /* no locks held yet */ p->curr_chain_key = 0; Index: linux/mm/memory.c =================================================================== --- linux.orig/mm/memory.c +++ linux/mm/memory.c @@ -2481,6 +2481,26 @@ unlock: return VM_FAULT_MINOR; } +void pagefault_disable(void) +{ + current->pagefault_disabled++; + /* + * make sure to have issued the store before a pagefault + * can hit. + */ + barrier(); +} + +void pagefault_enable(void) +{ + /* + * make sure to issue those last loads/stores before enabling + * the pagefault handler again. + */ + barrier(); + current->pagefault_disabled--; +} + /* * By the time we get here, we already hold the mm semaphore */ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 21:25 ` Ingo Molnar @ 2006-12-27 21:31 ` Ingo Molnar 2006-12-27 21:37 ` Daniel Walker 2006-12-27 21:36 ` Daniel Walker ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: Ingo Molnar @ 2006-12-27 21:31 UTC (permalink / raw) To: Daniel Walker; +Cc: linux-kernel plus on i386 the fix below is needed as well. Ingo --- include/asm-i386/highmem.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) Index: linux/include/asm-i386/highmem.h =================================================================== --- linux.orig/include/asm-i386/highmem.h +++ linux/include/asm-i386/highmem.h @@ -81,9 +81,9 @@ struct page *__kmap_atomic_to_page(void * on PREEMPT_RT kmap_atomic() is a wrapper that uses kmap(): */ #ifdef CONFIG_PREEMPT_RT -# define kmap_atomic(page, type) kmap(page) -# define kmap_atomic_pfn(pfn, type) kmap(pfn_to_page(pfn)) -# define kunmap_atomic(kvaddr, type) kunmap_virt(kvaddr) +# define kmap_atomic(page, type) ({ pagefault_disable(); kmap(page); }) +# define kmap_atomic_pfn(pfn, type) kmap_atomic(pfn_to_page(pfn), type) +# define kunmap_atomic(kvaddr, type) do { pagefault_enable(); kunmap_virt(kvaddr); } while (0) # define kmap_atomic_to_page(kvaddr) kmap_to_page(kvaddr) #else # define kmap_atomic(page, type) __kmap_atomic(page, type) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 21:31 ` Ingo Molnar @ 2006-12-27 21:37 ` Daniel Walker 2006-12-27 21:41 ` Ingo Molnar 0 siblings, 1 reply; 10+ messages in thread From: Daniel Walker @ 2006-12-27 21:37 UTC (permalink / raw) To: Ingo Molnar; +Cc: linux-kernel On Wed, 2006-12-27 at 22:31 +0100, Ingo Molnar wrote: > plus on i386 the fix below is needed as well. > We do it on most other arches .. PowerPC , and I think ARM too. Daniel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 21:37 ` Daniel Walker @ 2006-12-27 21:41 ` Ingo Molnar 0 siblings, 0 replies; 10+ messages in thread From: Ingo Molnar @ 2006-12-27 21:41 UTC (permalink / raw) To: Daniel Walker; +Cc: linux-kernel * Daniel Walker <dwalker@mvista.com> wrote: > On Wed, 2006-12-27 at 22:31 +0100, Ingo Molnar wrote: > > plus on i386 the fix below is needed as well. > > > > We do it on most other arches .. PowerPC , and I think ARM too. I dont think they currently work with PREEMPT_RT and HIGHMEM enabled, but if/once they do they'll need a similar fix. Ingo ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 21:25 ` Ingo Molnar 2006-12-27 21:31 ` Ingo Molnar @ 2006-12-27 21:36 ` Daniel Walker 2006-12-27 21:54 ` Daniel Walker 2006-12-28 0:05 ` Daniel Walker 3 siblings, 0 replies; 10+ messages in thread From: Daniel Walker @ 2006-12-27 21:36 UTC (permalink / raw) To: Ingo Molnar; +Cc: linux-kernel On Wed, 2006-12-27 at 22:25 +0100, Ingo Molnar wrote: > * Daniel Walker <dwalker@mvista.com> wrote: > > > I got some scheduling while atomic on x86-64 , and since x86-64 > > doesn't seem to have HIGHMEM there's no workaround for kmap_atomic() . > > > > This patch adds the same as i386 HIGHMEM for !HIGHMEM. > > the problem is that this does not disable pagefaulting while > kmap-atomic. Could you try the patch below, does it solve the assert? > That goes for the other CONFIG_HIGHMEM changes also? I mean if we can't do it here we shouldn't do it else where.. (note, I just used testscripts/ltpstress.sh from LTP to reproduce this.) Daniel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 21:25 ` Ingo Molnar 2006-12-27 21:31 ` Ingo Molnar 2006-12-27 21:36 ` Daniel Walker @ 2006-12-27 21:54 ` Daniel Walker 2006-12-28 0:05 ` Daniel Walker 3 siblings, 0 replies; 10+ messages in thread From: Daniel Walker @ 2006-12-27 21:54 UTC (permalink / raw) To: Ingo Molnar; +Cc: linux-kernel On Wed, 2006-12-27 at 22:25 +0100, Ingo Molnar wrote: > > +void pagefault_disable(void) > +{ > + current->pagefault_disabled++; > + /* > + * make sure to have issued the store before a pagefault > + * can hit. > + */ > + barrier(); > +} > + > +void pagefault_enable(void) > +{ > + /* > + * make sure to issue those last loads/stores before enabling > + * the pagefault handler again. > + */ > + barrier(); > + current->pagefault_disabled--; > +} > + I'll test it, but clearly I'm not going to get the same scheduling while atomic using this change.. So may as well just put it in -rt and see if something crashes .. Daniel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] update kmap_atomic on !HIGHMEM 2006-12-27 21:25 ` Ingo Molnar ` (2 preceding siblings ...) 2006-12-27 21:54 ` Daniel Walker @ 2006-12-28 0:05 ` Daniel Walker 3 siblings, 0 replies; 10+ messages in thread From: Daniel Walker @ 2006-12-28 0:05 UTC (permalink / raw) To: Ingo Molnar; +Cc: linux-kernel On Wed, 2006-12-27 at 22:25 +0100, Ingo Molnar wrote: > * Daniel Walker <dwalker@mvista.com> wrote: > > > I got some scheduling while atomic on x86-64 , and since x86-64 > > doesn't seem to have HIGHMEM there's no workaround for kmap_atomic() . > > > > This patch adds the same as i386 HIGHMEM for !HIGHMEM. > > the problem is that this does not disable pagefaulting while > kmap-atomic. Could you try the patch below, does it solve the assert? > It hasn't crashed after about an hour of stress.. One comment on the patch tho , the pagefault_enable/pagefault_disable need module exports, I saw the build complaining about them. Daniel ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-12-28 0:06 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-12-27 19:35 [PATCH -rt] update kmap_atomic on !HIGHMEM Daniel Walker 2006-12-27 20:54 ` Ingo Molnar 2006-12-27 21:04 ` Daniel Walker 2006-12-27 21:25 ` Ingo Molnar 2006-12-27 21:31 ` Ingo Molnar 2006-12-27 21:37 ` Daniel Walker 2006-12-27 21:41 ` Ingo Molnar 2006-12-27 21:36 ` Daniel Walker 2006-12-27 21:54 ` Daniel Walker 2006-12-28 0:05 ` Daniel Walker
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®