From: Robert Love <rml@tech9.net>
To: torvalds@transmeta.com
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] misc. kernel preemption bits
Date: 29 Aug 2002 11:33:01 -0400 [thread overview]
Message-ID: <1030635181.978.2559.camel@phantasy> (raw)
Linus,
Misc. kernel preemption-related bits. Specifically,
- update to Documentation/preempt-locking.txt (me)
- preempt-safe arch/i386/kernel/ioport.c :: sys_ioperm()
(George Anzinger)
- remove "kernel_lock()" cruft in include/linux/smp.h
(Andrew Morton)
- we have a debug check in preempt_schedule that, even
on detecting a schedule with irqs disabled, still goes
ahead and reschedules. We should return. (me)
- preempt-safe net/core/dev.c :: netif_rx() (George Anzinger)
All fairly trivial and/or simple. Patch is against 2.5.32-bk. Please,
apply.
Robert Love
diff -urN linux-2.5.32/Documentation/preempt-locking.txt linux/Documentation/preempt-locking.txt
--- linux-2.5.32/Documentation/preempt-locking.txt Tue Aug 27 15:26:32 2002
+++ linux/Documentation/preempt-locking.txt Wed Aug 28 23:23:30 2002
@@ -1,7 +1,7 @@
Proper Locking Under a Preemptible Kernel:
Keeping Kernel Code Preempt-Safe
- Robert Love <rml@tech9.net>
- Last Updated: 22 Jan 2002
+ Robert Love <rml@tech9.net>
+ Last Updated: 28 Aug 2002
INTRODUCTION
@@ -112,3 +112,24 @@
This code is not preempt-safe, but see how easily we can fix it by simply
moving the spin_lock up two lines.
+
+
+PREVENTING PREEMPTION USING INTERRUPT DISABLING
+
+
+It is possible to prevent a preemption event using local_irq_disable and
+local_irq_save. Note, when doing so, you must be very careful to not cause
+an event that would set need_resched and result in a preemption check. When
+in doubt, rely on locking or explicit preemption disabling.
+
+Note in 2.5 interrupt disabling is now only per-CPU (e.g. local).
+
+An additional concern is proper usage of local_irq_disable and local_irq_save.
+These may be used to protect from preemption, however, on exit, if preemption
+may be enabled, a test to see if preemption is required should be done. If
+these are called from the spin_lock and read/write lock macros, the right thing
+is done. They may also be called within a spin-lock protected region, however,
+if they are ever called outside of this context, a test for preemption should
+be made. Do note that calls from interrupt context or bottom half/ tasklets
+are also protected by preemption locks and so may use the versions which do
+not check preemption.
diff -urN linux-2.5.32/arch/i386/kernel/ioport.c linux/arch/i386/kernel/ioport.c
--- linux-2.5.32/arch/i386/kernel/ioport.c Tue Aug 27 15:26:42 2002
+++ linux/arch/i386/kernel/ioport.c Wed Aug 28 23:23:30 2002
@@ -55,12 +55,16 @@
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
struct thread_struct * t = ¤t->thread;
- struct tss_struct * tss = init_tss + smp_processor_id();
+ struct tss_struct * tss;
+ int ret = 0;
if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
return -EINVAL;
if (turn_on && !capable(CAP_SYS_RAWIO))
return -EPERM;
+
+ tss = init_tss + get_cpu();
+
/*
* If it's the first ioperm() call in this thread's lifetime, set the
* IO bitmap up. ioperm() is much less timing critical than clone(),
@@ -69,8 +73,11 @@
if (!t->ts_io_bitmap) {
unsigned long *bitmap;
bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
- if (!bitmap)
- return -ENOMEM;
+ if (!bitmap) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
/*
* just in case ...
*/
@@ -88,7 +95,9 @@
set_bitmap(t->ts_io_bitmap, from, num, !turn_on);
set_bitmap(tss->io_bitmap, from, num, !turn_on);
- return 0;
+out:
+ put_cpu();
+ return ret;
}
/*
diff -urN linux-2.5.32/include/linux/smp.h linux/include/linux/smp.h
--- linux-2.5.32/include/linux/smp.h Tue Aug 27 15:26:43 2002
+++ linux/include/linux/smp.h Wed Aug 28 23:23:30 2002
@@ -87,9 +87,6 @@
#define smp_processor_id() 0
#define hard_smp_processor_id() 0
#define smp_threads_ready 1
-#ifndef CONFIG_PREEMPT
-#define kernel_lock()
-#endif
#define smp_call_function(func,info,retry,wait) ({ 0; })
static inline void smp_send_reschedule(int cpu) { }
static inline void smp_send_reschedule_all(void) { }
diff -urN linux-2.5.32/kernel/sched.c linux/kernel/sched.c
--- linux-2.5.32/kernel/sched.c Tue Aug 27 15:26:37 2002
+++ linux/kernel/sched.c Wed Aug 28 23:23:24 2002
@@ -1039,6 +1039,7 @@
printk("bad: schedule() with irqs disabled!\n");
show_stack(NULL);
preempt_enable_no_resched();
+ return;
}
need_resched:
diff -urN linux-2.5.32/net/core/dev.c linux/net/core/dev.c
--- linux-2.5.32/net/core/dev.c Tue Aug 27 15:26:43 2002
+++ linux/net/core/dev.c Wed Aug 28 23:23:30 2002
@@ -1229,19 +1229,20 @@
int netif_rx(struct sk_buff *skb)
{
- int this_cpu = smp_processor_id();
+ int this_cpu;
struct softnet_data *queue;
unsigned long flags;
if (!skb->stamp.tv_sec)
do_gettimeofday(&skb->stamp);
- /* The code is rearranged so that the path is the most
- short when CPU is congested, but is still operating.
+ /*
+ * The code is rearranged so that the path is the most
+ * short when CPU is congested, but is still operating.
*/
- queue = &softnet_data[this_cpu];
-
local_irq_save(flags);
+ this_cpu = smp_processor_id();
+ queue = &softnet_data[this_cpu];
netdev_rx_stat[this_cpu].total++;
if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
@@ -1252,10 +1253,10 @@
enqueue:
dev_hold(skb->dev);
__skb_queue_tail(&queue->input_pkt_queue, skb);
- local_irq_restore(flags);
#ifndef OFFLINE_SAMPLE
get_sample_stats(this_cpu);
#endif
+ local_irq_restore(flags);
return queue->cng_level;
}
next reply other threads:[~2002-08-29 15:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-29 15:33 Robert Love [this message]
2002-08-29 18:24 ` [PATCH] misc. kernel preemption bits Andrew Morton
2002-08-29 19:11 ` Robert Love
2002-08-29 21:07 ` george anzinger
2002-08-29 18:38 ` Linus Torvalds
2002-08-29 18:39 ` Robert Love
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=1030635181.978.2559.camel@phantasy \
--to=rml@tech9.net \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.