DragonFly BSD
DragonFly kernel List (threaded) for 2006-02
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: MSI prototype

From: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 21 Feb 2006 01:53:31 -0800 (PST)

:method used for SYS_RES_IRQ. You might wonder why we don't use the
:same technique as for IRQs and pre-assign vectors. Lazy allocation is
:a better strategy for MSI and MSI-X ("MSI extended") as the capability
:structure can only indicate the max supported number of vectors (up to
:1K vectors in some cases) which may be much larger than the actual
:number used. Therefore, it is best left to the drivers to decide how
:many vectors to allocate AND what to do if they can't get as many as
:they want/need.
:The problems
:I basically like the bus_alloc_resource and bus_setup_intr philosophy,
:but they currently pose separate problems for MSI and MSI-X.
:1) MSI allows multiple vectors per function but requires that the
:vectors are contiguous (e.g. vectors 1,2,3 or 2,3,4 are OK but 2,4,5
:are not). So while the current implementation finds the first unused
:vector, there isn't a way to specify that this must be the first of 3
:free vectors (for example). Additionally, when allocating the
:subsequent vectors, there isn't a way to correlate the current
:allocation with a previous one.
:2) MSI-X avoids the above problem because it has separate address/data
:registers for each supported interrupt (i.e. MSI only has a single
:address/data register for ALL interrupts). The problem here is with
:setting up the interrupt. Once an interrupt is allocated, there isn't
:a way too say "use this address/data for the 3rd interrupt" (which
:translates into "write this to the 3rd addr/data registers").
:3) Another minor problem is in the resource implementation which
:currently panics (IIRC ...) if the system tries to add more than one
:resource of the same type to the resource list (i.e. can't have
:multiple SYS_RES_MSI). This one I'm less worried about than the
:previous 2.
:So, what to do? If it were up to me, I'd be tempted to modify the
:current interfaces to support the additional information needed
:because I like the alloc/setup metaphors. The downside to this is
:modifying "a couple" ;) of drivers to support the new API. Thoughts?

    I think (3) isn't a big deal if the MSI irq abstraction is given
    the 'number of vectors' required and returns just the base vector,
    letting the driver do base+0, base+1, base+2 for the individual
    vectors.  One resource would thus represent all N requested contiguous

    Reservation and allocation can be solved by removing the software
    limits on the number of supported IRQs.  In 1.4 I separated out the
    software interrupt bits from the hardware interrupt bits, increasing
    the number of supported IRQs from 24 to 32.  See the gd_fpending and
    gd_ipending fields in src/sys/i386/include/globaldata.h.
    (those fields are used to 'remember' interrupts which occured during
    a critical section and then process them when the critical section is
    released at crit_exit/doreti/splz time).

    Fortunately most of the other code dependancies, namely SPL masks, no
    longer exist in DragonFly.  And we also now have a fairly nicely
    abstracted interrupt vector management layer, aka src/sys/i386/{apic,icu}.

    If we do further work to increase the number of supported irqs in
    software to some reasonable number, like 256, then the device driver
    model would be greatly simplified.  We basically would never run out
    of IRQs and wouldn't have to worry about running out of IRQs.

    Device driver code tends to assume level-triggered so that would
    probably be the hardest bit once the infrastructure is in place.

    My understanding of MSI(X) is that it basically treats the interrupt
    as edge-triggered.  On trigger it writes the specified data to the
    specified address which, I assume, would be an IOAPIC or LAPIC address?
    I can't imagine how it would work with an IOAPIC with its stupid 
    register window crap, so I assume the MSI(X) address and data would
    inject an ICR command into the LAPIC.  I don't quite understand how
    the device is able to do that without polling the 'S'end Pending
    bit in the ICR, though.


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]