Which core will execute my ISR in a multi-core env?

Hi all

is there a way to bind execution of a ISR (attached with
InterruptAttachEvent) to a particular core in a SMP system?

Or maybe a way to bind the handling of a particular IRQ to a core or a
core subset?

Or again, is there a chance to foreseen (if forcing is not allowed) the
exact core where ISR will run on?

I’m trying to port some x86 device drivers from single to multi-core
platform, and I’m wondering if I have to protect process/ISR conflicts
against all combinations of execution cores.

Davide


/* Ancri Davide - */

“Davide Ancri” <falsemail@nospam.xx> wrote in message
news:f6i8ln$t3n$1@inn.qnx.com

Hi all

is there a way to bind execution of a ISR (attached with
InterruptAttachEvent) to a particular core in a SMP system?

Or maybe a way to bind the handling of a particular IRQ to a core or a
core subset?

Or again, is there a chance to foreseen (if forcing is not allowed) the
exact core where ISR will run on?

I’m trying to port some x86 device drivers from single to multi-core
platform, and I’m wondering if I have to protect process/ISR conflicts
against all combinations of execution cores.

Not really. You just have to protect against the usual stuff.

Davide


/* Ancri Davide - */

Mario Charest wrote:

I’m trying to port some x86 device drivers from single to
multi-core platform, and I’m wondering if I have to protect
process/ISR conflicts against all combinations of execution cores.

Not really. You just have to protect against the usual stuff.

I was meaning that if I can guarantee that the ISR will run only on the
same core where the thread will (using affinity mask or similars), I
think there’s nothing special to be changed on my sources.

Otherwhise, critical accesses to shared variables into the ISR should be
optimized and protected through InterruptLock() or something like that,
isn’t it?

Thanks!
Davide


/* Ancri Davide - */

In article <f6i8ln$t3n$1@inn.qnx.com>,
Davide Ancri <falsemail@nospam.xx> wrote:

is there a way to bind execution of a ISR (attached with
InterruptAttachEvent) to a particular core in a SMP system?

This is done by the person who wrote the startup program for the
board - startup is responsible for determining what core a particular
interrupt is delivered to by how it programs the interrupt controller
hardware. There’s no mechanism to change those bindings after the
system has come up (aside from reprogramming the hardware behind its
back, but that’s something you better know what you’re doing before
you go there).

For startups developed by QSS, typically all interrupts are directed
at CPU 0 (aside the ones that are used internally by procnto for
inter-process interrupts).


Brian Stecher (bstecher@qnx.com) QNX Software Systems
phone: +1 (613) 591-0931 (voice) 175 Terence Matthews Cr.
+1 (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

Brian, now you have me a little curious. Let me see if I
understand?
The default seems for all hardware interrupts to go to cpu 0, at
least
until you muck with a BSP or write your own.

If the user attaches an interrupt handler to that interrupt, it will
also
run on cpu 0? regardless of any affinity the process has? Or will
the interrupt handler be scheduled (immediately one would hope)
for the affined (my made up word) processor?

“Davide Ancri” <falsemail@nospam.xx> wrote in message
news:f6imto$6ml$1@inn.qnx.com

Mario Charest wrote:
I’m trying to port some x86 device drivers from single to
multi-core platform, and I’m wondering if I have to protect
process/ISR conflicts against all combinations of execution cores.

Not really. You just have to protect against the usual stuff.

I was meaning that if I can guarantee that the ISR will run only on the
same core where the thread will (using affinity mask or similars), I
think there’s nothing special to be changed on my sources.

Event if it isn’t why would you have to do something special?

Otherwhise, critical accesses to shared variables into the ISR should be
optimized and protected through InterruptLock() or something like that,
isn’t it?

Yes. However personaly I’ve always manage to arrange shared variable so
that spinlocks aren’t necessary.
If you use InterruptAttachEvent instead of InterruptAttach you can use
mutexes instead.

Thanks!
Davide


/* Ancri Davide - */

maschoen <maschoen@pobox-dot-com.no-spam.invalid> wrote:

Brian, now you have me a little curious. Let me see if I
understand?
The default seems for all hardware interrupts to go to cpu 0, at
least
until you muck with a BSP or write your own.

Yes.

If the user attaches an interrupt handler to that interrupt, it will
also
run on cpu 0?

Yes.

regardless of any affinity the process has?

Processes don’t have affinities – threads do. Interrupt handlers are
independent of threads, so in no way are affected by threads’ processor
affinities.

Or will
the interrupt handler be scheduled (immediately one would hope)
for the affined (my made up word) processor?

Nope.

-David Gibbs

David Gibbs
QNX Training Services
dagibbs@qnx.com

You’re confusing ISR with Interrupt Thread, Mitch. The interrupt service routine (which runs in the
context of the Neutrino kernel) will run on CPU0 - if you used InterruptAttachEvent() or return a sigevent
from your handler, then your Interrupt Thread will be scheduled to run based on the usual scheduling
decisions. I do believe that if the thread is valid to run on the current cpu, then it will stay there,
but there’s nothing (short of setting the affinity) that would prevent it from running on CPU1

Colin

maschoen wrote:

Brian, now you have me a little curious. Let me see if I
understand?
The default seems for all hardware interrupts to go to cpu 0, at
least
until you muck with a BSP or write your own.

If the user attaches an interrupt handler to that interrupt, it will
also
run on cpu 0? regardless of any affinity the process has? Or will
the interrupt handler be scheduled (immediately one would hope)
for the affined (my made up word) processor?


cburgess@qnx.com

Brian Stecher wrote:

For startups developed by QSS, typically all interrupts are directed
at CPU 0 (aside the ones that are used internally by procnto for
inter-process interrupts).

I think I’ll print a summary of this thread on paper, these seem to be
very interesting info!

Thaks to all.
Davide


/* Ancri Davide - */

Mario Charest wrote:

Otherwhise, critical accesses to shared variables into the ISR should be
optimized and protected through InterruptLock() or something like that,
isn’t it?

Yes. However personaly I’ve always manage to arrange shared variable so
that spinlocks aren’t necessary.

I’m thinking about this solution, it seems the most clean and efficient.

Is there some good howto (maybe in the qnx site) about general
guidelines for this particular issue?


If you use InterruptAttachEvent instead of InterruptAttach you can use
mutexes instead.

With InterruptAttachEvent() and a single thread dealing with the
hardware I would say that no protection is needed at all.

But you know how much I hate InterruptAttachEvent() in a shared-IRQs
architecture: how long to be waited for InterruptAttachEvent()-free QSSL
x86 device drivers? :wink:

Davide


/* Ancri Davide - */

Another doubt, this time about InterruptLock/Unlock().

Moving to multicore, I need to protect concurrent calling to the
hardware-handling routine from procces space and kernel space (ISR).

In single core I simply wrap the process-space call with
InterruptDisable() and InterruptEnable(), while the atomic execution in
the ISR was guaranteed being atomically on the only existent cpu.

Now the solution seems to be InterruptLock() and InterruptUnlock(), that
implement spinlocking while cpu interrupts are turned off, but I’m
wondering why inside the kernel-executed ISR the interrupts shall be
disabled/enabled, taking into account that:

  1. locking a spinlock in process-space without disabling interrupts is
    really dangerous, because spin owner can be preempted for an unknown
    period, but under ISR preemption can happen only from other ISRs (few
    microseconds if programmers know what they’re doing), so cli/sti is not
    mandatory from my point of view

  2. typically my ISR (executed thousand times per second) will always
    find the spinlock available, because calling the same function in
    process space is a very rare event

  3. cli and sti x86 instructions are not so light in modern processors:
    they impact on pipelining may take lot of cpu cycles

I wuold try to modify the __inline_InterruptLock &
__inline_InterruptUnlock macros defined in <x86/neutrino.h>, to create a
version intended for ISR use only: should I pay attention to something I
haven’t taken into account or am I right?

Davide


/* Ancri Davide - */

David,

Yes, thread affinity, not process affinity, an old QNX 4 habit.

Colin,

No, I don’t think I’m confused, but let me ask a question that
will illuminate one way or another.
Let’s say in a multiprocessor system I attach an ISR to some
interrupt.
Let’s also say that the ISR wakes up a thread which has affinity 0
(can only run on processor 0).

I conclude that I am now in the old QNX 4 situation, where the ISR
might startup while the thread is running,
but there is no chance that two different processors will be
simultaneously accessing the same shared buffer.
Is this so?

maschoen wrote:

David,

Yes, thread affinity, not process affinity, an old QNX 4 habit.

Colin,

No, I don’t think I’m confused, but let me ask a question that
will illuminate one way or another.
Let’s say in a multiprocessor system I attach an ISR to some
interrupt.
Let’s also say that the ISR wakes up a thread which has affinity 0
(can only run on processor 0).

I conclude that I am now in the old QNX 4 situation, where the ISR
might startup while the thread is running,
but there is no chance that two different processors will be
simultaneously accessing the same shared buffer.
Is this so?

As long as your startup has setup interrupt routing to only go to CPU0, and all threads
that might wakeup are bound by affinity to CPU0, then yes, that assumption can be made.


cburgess@qnx.com

Colin Burgess wrote:

As long as your startup has setup interrupt routing to only go to
CPU0, and all threads that might wakeup are bound by affinity to
CPU0, then yes, that assumption can be made.

Two more questions :wink:

  1. Brian wrote:

For startups developed by QSS, typically all interrupts are directed
at CPU 0 (aside the ones that are used internally by procnto for
inter-process interrupts).
Can we assume that for x86 systems (yes I love putting realtime kernels

on those windoze-oriented boxes!) QSS startups will always route
device interrups to CPU 0 ?

  1. Is there a system call (or maybe some info in the system page) to
    know on which CPU has a specified IRQ been routed?

Binding the driver thread to the CPU where the ISR will be executed
seems to be an interesting solution, that let non-SMP drivers run on SMP
boxes without binary differences, avoiding cache issues on ISR/thread
shared memory and the InterruptLock() overhead I was mentioning in my
last post of this thread.

Davide


/* Ancri Davide - */

In article <f775np$rs1$1@inn.qnx.com>,
Davide Ancri <falsemail@nospam.xx> wrote:

Can we assume that for x86 systems (yes I love putting realtime kernels
on those windoze-oriented boxes!) QSS startups will always route
device interrups to CPU 0 ?

No, you can not assume that we will always route interrupts to CPU 0.
I can’t see it changing in the forseeable future, but we do not guarantee
that we won’t change it. If you need that guarantee, you’ll have to
maintain your own startup executable.

  1. Is there a system call (or maybe some info in the system page) to
    know on which CPU has a specified IRQ been routed?

Nope. Typically you can query the hardware to determine where it’s
routing things, but there’s no board independent manner to find out.

\

Brian Stecher (bstecher@qnx.com) QNX Software Systems
phone: +1 (613) 591-0931 (voice) 175 Terence Matthews Cr.
+1 (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

Davide Ancri wrote:

Another doubt, this time about InterruptLock/Unlock().

Any hints about my doubt?

Davide


/* Ancri Davide - */