]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Infrastructure for atomic user accesses
authorAndrew Morton <akpm@zip.com.au>
Sat, 10 Aug 2002 11:40:05 +0000 (04:40 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sat, 10 Aug 2002 11:40:05 +0000 (04:40 -0700)
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.

arch/i386/mm/fault.c
include/linux/preempt.h

index cd4083d09658edf14151ff290276da3d190bd6b7..dcfb3912e674dca9724f06603a6253ba40b8f416 100644 (file)
@@ -181,10 +181,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
        info.si_code = SEGV_MAPERR;
 
        /*
-        * If we're in an interrupt or have no user
-        * context, we must not take the fault..
+        * 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_interrupt() || !mm)
+       if (preempt_count() || !mm)
                goto no_context;
 
        down_read(&mm->mmap_sem);
index 172471f0dbde212e0ed7a714f2b00b92d1fea001..3864d46eadbaab331e29c3d7f325d61e01fe3d05 100644 (file)
@@ -5,19 +5,29 @@
 
 #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
 
 extern void preempt_schedule(void);
 
 #define preempt_disable() \
 do { \
-       preempt_count()++; \
+       inc_preempt_count(); \
        barrier(); \
 } while (0)
 
 #define preempt_enable_no_resched() \
 do { \
-       preempt_count()--; \
+       dec_preempt_count(); \
        barrier(); \
 } while (0)
 
@@ -34,6 +44,9 @@ do { \
                preempt_schedule(); \
 } while (0)
 
+#define inc_preempt_count_non_preempt()        do { } while (0)
+#define dec_preempt_count_non_preempt()        do { } while (0)
+
 #else
 
 #define preempt_disable()              do { } while (0)
@@ -41,6 +54,13 @@ do { \
 #define preempt_enable()               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 /* __LINUX_PREEMPT_H */