Commit 199143a8 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Infrastructure for atomic user accesses

Well the optimum solution there would be to create and use
`inc_preempt_count_non_preempt()'.  I don't see any
way of embedding this in kmap_atomic() or copy_to_user_atomic()
without loss of flexibility or incurring a double-inc somewhere.
parent 1dd4dd0c
...@@ -181,10 +181,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -181,10 +181,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
info.si_code = SEGV_MAPERR; info.si_code = SEGV_MAPERR;
/* /*
* If we're in an interrupt or have no user * If we're in an interrupt, have no user context or are running in an
* context, we must not take the fault.. * atomic region then we must not take the fault..
*/ */
if (in_interrupt() || !mm) if (preempt_count() || !mm)
goto no_context; goto no_context;
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
......
...@@ -5,19 +5,29 @@ ...@@ -5,19 +5,29 @@
#define preempt_count() (current_thread_info()->preempt_count) #define preempt_count() (current_thread_info()->preempt_count)
#define inc_preempt_count() \
do { \
preempt_count()++; \
} while (0)
#define dec_preempt_count() \
do { \
preempt_count()--; \
} while (0)
#ifdef CONFIG_PREEMPT #ifdef CONFIG_PREEMPT
extern void preempt_schedule(void); extern void preempt_schedule(void);
#define preempt_disable() \ #define preempt_disable() \
do { \ do { \
preempt_count()++; \ inc_preempt_count(); \
barrier(); \ barrier(); \
} while (0) } while (0)
#define preempt_enable_no_resched() \ #define preempt_enable_no_resched() \
do { \ do { \
preempt_count()--; \ dec_preempt_count(); \
barrier(); \ barrier(); \
} while (0) } while (0)
...@@ -34,6 +44,9 @@ do { \ ...@@ -34,6 +44,9 @@ do { \
preempt_schedule(); \ preempt_schedule(); \
} while (0) } while (0)
#define inc_preempt_count_non_preempt() do { } while (0)
#define dec_preempt_count_non_preempt() do { } while (0)
#else #else
#define preempt_disable() do { } while (0) #define preempt_disable() do { } while (0)
...@@ -41,6 +54,13 @@ do { \ ...@@ -41,6 +54,13 @@ do { \
#define preempt_enable() do { } while (0) #define preempt_enable() do { } while (0)
#define preempt_check_resched() do { } while (0) #define preempt_check_resched() do { } while (0)
/*
* Sometimes we want to increment the preempt count, but we know that it's
* already incremented if the kernel is compiled for preemptibility.
*/
#define inc_preempt_count_non_preempt() inc_preempt_count()
#define dec_preempt_count_non_preempt() dec_preempt_count()
#endif #endif
#endif /* __LINUX_PREEMPT_H */ #endif /* __LINUX_PREEMPT_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment