lkml.org 
[lkml]   [2008]   [Aug]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC] export irq_set/get_affinity() for multiqueue network drivers
    Hello,

    Is there any way to setup IRQ masks from within a driver? myri10ge
    currently relies on an external script (writing in
    /proc/irq/*/smp_affinity) to bind each queue/MSI-X to a different
    processor. By default, Linux will either:
    * round-robin the interrupts (killing the benefit of DCA for instance)
    * put all IRQs on the same CPU (killing much of the benefit of multislices)

    With more and more drivers using multiqueues, I think we need a nice way
    to bind MSI-X from within the drivers. I am not sure what's best, the
    attached (untested) patch would just export the existing
    irq_set_affinity() and add irq_get_affinity(). Comments?

    thanks,
    Brice

    [PATCH] export irq_set/get_affinity() to modules

    Export irq_set_affinity() and add/export irq_get_affinity() so that
    network drivers may access MSI-X interrupt masks to bind multiqueues
    to different CPUs. Otherwise Linux will either:
    * round-robin the interrupts (killing the benefit of DCA, for instance)
    * put all IRQs on the same CPU (killing much of the benefit of multislices)

    Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
    ---
    include/linux/interrupt.h | 3 +++
    kernel/irq/manage.c | 15 +++++++++++++++
    2 files changed, 18 insertions(+)

    --- a/include/linux/interrupt.h
    +++ b/include/linux/interrupt.h
    @@ -107,6 +107,7 @@ extern void enable_irq(unsigned int irq);
    extern cpumask_t irq_default_affinity;

    extern int irq_set_affinity(unsigned int irq, cpumask_t cpumask);
    +extern int irq_get_affinity(unsigned int irq, cpumask_t *cpumask);
    extern int irq_can_set_affinity(unsigned int irq);
    extern int irq_select_affinity(unsigned int irq);

    @@ -117,6 +118,8 @@ static inline int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
    return -EINVAL;
    }

    +static inline int irq_get_affinity(unsigned int irq) { return 0; }
    +
    static inline int irq_can_set_affinity(unsigned int irq)
    {
    return 0;
    --- a/kernel/irq/manage.c
    +++ b/kernel/irq/manage.c
    @@ -96,6 +96,21 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
    #endif
    return 0;
    }
    +EXPORT_SYMBOL(irq_set_affinity);
    +
    +int irq_get_affinity(unsigned int irq, cpumask_t *cpumask)
    +{
    + struct irq_desc *desc = irq_desc + irq;
    + cpumask_t *mask = &desc->affinity;
    +
    +#ifdef CONFIG_GENERIC_PENDING_IRQ
    + if (desc->status & IRQ_MOVE_PENDING)
    + mask = &desc->pending_mask;
    +#endif
    + memcpy(cpumask, mask, sizeof(*mask);
    + return 0;
    +}
    +EXPORT_SYMBOL(irq_get_affinity);

    #ifndef CONFIG_AUTO_IRQ_AFFINITY
    /*
    \
     
     \ /
      Last update: 2008-08-28 22:53    [W:0.035 / U:0.040 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site