Re: [patch 6/12] hold atomic kmaps across generic_file_read

From: Andrew Morton (akpm@zip.com.au)
Date: Sat Aug 10 2002 - 20:27:31 EST


Linus Torvalds wrote:
>
> On Sat, 10 Aug 2002, Andrew Morton wrote:
> >
> > If not, I don't think it's worth making this change just for
> > the highmem read/write thing (calculating `current' at each
> > spin_lock site...) I just open coded it.
>
> Well, this way it will now do the preempt count twice (once in
> kmap_atomic, once in th eopen-coded one) if preempt is enabled.
>
> I'd suggest just making k[un]map_atomic() always do the
> inc/dec_preempt_count. Other ideas?
>

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.

Please let my post-virginal brain know if you're not otherwise OK
with the approach ;)

 arch/i386/mm/fault.c | 6 +++---
 include/linux/preempt.h | 24 ++++++++++++++++++++++--
 2 files changed, 25 insertions(+), 5 deletions(-)

--- 2.5.30/arch/i386/mm/fault.c~atomic-copy_user Sat Aug 10 14:44:03 2002
+++ 2.5.30-akpm/arch/i386/mm/fault.c Sat Aug 10 14:44:52 2002
@@ -189,10 +189,10 @@ asmlinkage void do_page_fault(struct pt_
         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;
 
 #ifdef CONFIG_X86_REMOTE_DEBUG
--- 2.5.30/include/linux/preempt.h~atomic-copy_user Sat Aug 10 16:18:50 2002
+++ 2.5.30-akpm/include/linux/preempt.h Sat Aug 10 18:23:40 2002
@@ -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 */

.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Aug 15 2002 - 22:00:23 EST