Peter,
> On Mon, Apr 12, 2010 at 10:34 AM, Peter Teoh <[email protected]> wrote:
>> I've been working with 2 drivers, an i2c based touchcreen and a spi
>> based ethernet. My problem comes when I try to change the affinity for
>> their irqs to be handled by processor 2, change is not reflected, for
>> the ethernet I have...
>>
>> # cat /proc/interrupts | grep eth0
>> 194: 4883 0 GPIO eth0
>> # cat /proc/irq/194/smp_affinity
>> 3
>> # echo 1 > /proc/irq/194/smp_affinity
>> # cat /proc/irq/194/smp_affinity
>> 3
>
> Notice the creation read/write attributes:
>
> ./irq/proc.c:
> proc_create_data("smp_affinity", 0600, desc->dir,
> proc_create("irq/default_smp_affinity", 0600, NULL,
>
> 0600 means read-only by root. 0666 means read-only by everyone.
Ok...
>> Is there any flag needed in the irq handler to allow the affinity? I
>> have tested the irq affinity for a keypad driver and it is working as
>> expected...
>>
>
> logically, i don't think you aim is achieveable. reason being that
> the keypad driver is a kernel thread by itself, and so can be assigned
> to a specific CPU. (similarly for another non-performance critical
> driver: kpsmoused - which is created as a workqueue:
>
> kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
>
> since "ps -ef" gave only on kernel thread listed, I supposed it is
> possible to assign CPU affinity to this thread.
>
> But ethernet IRQ processing is performance critical, and it is done
> inside the ksoftirqd thread, and so ksoftirqd is per-CPU.
>
> inside run_softirqd() there is a CPU turning-on-off throttling mechanism:
>
> while (local_softirq_pending()) {
> /* Preempt disable stops cpu going offline.
> If already offline, we'll be on wrong CPU:
> don't process */
> if (cpu_is_offline((long)__bind_cpu))
> goto wait_to_die;
> do_softirq();
> preempt_enable_no_resched();
> cond_resched();
> preempt_disable();
> rcu_sched_qs((long)__bind_cpu);
> }
>
> But when u turned off the CPU all jobs are not run as well. i
> guessed it is just too much work and not worth the effort to do such
> fine tuning....
Thanks for the great explanation... it helped a lot. This is the final
resolution...
The irq for the driver is a GPIO type so it is considered a virtual
interrupt. If we want to assign the handling to a different CPU we
need to set the affinity for the irq of the gpio bank not the gpio irq
itself.
In my setup, we have a total of 6 banks with 32 gpio each
#define OMAP_MAX_GPIO_LINES 192
and the interrupt assigned to the specific bank
#define INT_44XX_GPIO_BANK1 (29 + IRQ_GIC_START)
#define INT_44XX_GPIO_BANK2 (30 + IRQ_GIC_START)
#define INT_44XX_GPIO_BANK3 (31 + IRQ_GIC_START)
#define INT_44XX_GPIO_BANK4 (32 + IRQ_GIC_START)
#define INT_44XX_GPIO_BANK5 (33 + IRQ_GIC_START)
#define INT_44XX_GPIO_BANK6 (34 + IRQ_GIC_START)
so now changing irq bank instead of irq driver, affinity can be changed
r...@omap-4430sdp:~# echo 2 > /proc/irq/62/smp_affinity
r...@omap-4430sdp:~# cat /proc/interrupts
CPU0 CPU1
194: 20084 156 GPIO eth0
Appreciated your feedback...
Best Regards
Abraham
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ