I'm a little confused, when I disable interrupts (using
spin_lock_irqsave() for example), on uniprocessor machine the kernel
preemption is disabled. Does the same happens with multiprocessor?
Thanks in advance,
Guy.
On the CPU that does the spin_lock_irqsave(), it will. However, the
other CPUs might not even notice that this CPU is doing this.
So, for the system as a whole, this won't happen.
--
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html
This is a somewhat empty statement. Since a task can only run on one
CPU at any given time, it can only preempted on this CPU and if some
other task running on another CPU is or isn't preempted while the
first task will not be is of no technical concern.
Please read the OP's question again:
He was asking whether "preemption is disabled". I interpret that as a
question about preemption in general, not just restricted to the CPU
that has disabled interrupts. Any other interpretation does not make
sense. IMHO.
Josef
I got it, the preemption will be disabled on the local cpu only.
That's was my intention in the first place, sorry for the vagueness.
Guy.
'Disabling preemption in general' would not make the least bit of
sense, because only the task that disabled preemption is the one
supposedly doing something in the middle of which it must not be
preempted. As it turned out to be, the preempt counter is a per-task
variable (part of the struct thread_info struct, defined in
.../include/asm/thread_info.h), meaning, disabling 'general
preemption' isn't even technically possible (and there is no reason
why it should be).
You're right, the preemption disabling is relevant in task context
only (as you mentioned thread_info's preemet_count is incremented when
a lock is held).
As I said I was a bit confused.
a. The preemption counter, is a way of identifying the depth of
recursion in preemption. So you always see the source codes checking
for preemption==0, meaning that it is not in interrupt context.
b. Preemption, one way is triggered by the hardware clock. Or
possibly IPI, or possibly any other interrupts, not sure, all are
possible(??). And then the IDT (interrupt descriptor table) setup to
respond to that incoming clock signal. But IDT is also handling many
other interrupt at the same time. So when you disable interrupt, you
disable preemption.
c. In Intel/AMD CPU architecture, there is an IDT for each CPU. So
in multi-core architecture, there is one IDT per CPU. Disabling
interrupt on one CPU does not disable it on another CPU. And
spin_lock_irqsave() is local per CPU. One CPU executing
spin_lock_irqsave() will not affect another CPU's interrupt, and so
preemption is still possible, but it is happening on other CPU.
100: void __lockfunc _spin_lock_irq(spinlock_t *lock)
101: {
102: local_irq_disable();===>only the local IDT is
disabled. After this call, preemption is hardware-wise disabled.
103: preempt_disable();===>just updating the variables, but
hardware-wise, nothing is done.
104: spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
105: LOCK_CONTENDED(lock, _raw_spin_trylock,
_raw_spin_lock);
106: }
d. Recommended documentation to read: located in Documentation
directory in source: spinlocks.txt, preempt-locking.txt, RCU/UP.txt,
kernel-locking.doc, atomic_ops.txt, memory-barriers.txt etc. All of
them have something on spinlocks and IRQ.
Correct me if i am wrong.
[...]
> b. Preemption, one way is triggered by the hardware clock. Or
> possibly IPI, or possibly any other interrupts, not sure, all are
> possible(??).
It is the job of the scheduler to preempt the currently running process
if a higher priority process becomes runnable. And the scheduler is
usually (for the 'preempt' case) called as part of the timer
processing.
> And then the IDT (interrupt descriptor table) setup to
> respond to that incoming clock signal. But IDT is also handling many
> other interrupt at the same time. So when you disable interrupt, you
> disable preemption.
When you disable interrupts on a certain CPU, you disable the only
possible source of asynchronous, involuntary (from the perspective of
the currently running task) control transfers to 'different code'
(like the scheduler).