• Ming Lei's avatar
    genirq/affinity: Store interrupt sets size in struct irq_affinity · 9cfef55b
    Ming Lei authored
    The interrupt affinity spreading mechanism supports to spread out
    affinities for one or more interrupt sets. A interrupt set contains one
    or more interrupts. Each set is mapped to a specific functionality of a
    device, e.g. general I/O queues and read I/O queus of multiqueue block
    devices.
    
    The number of interrupts per set is defined by the driver. It depends on
    the total number of available interrupts for the device, which is
    determined by the PCI capabilites and the availability of underlying CPU
    resources, and the number of queues which the device provides and the
    driver wants to instantiate.
    
    The driver passes initial configuration for the interrupt allocation via
    a pointer to struct irq_affinity.
    
    Right now the allocation mechanism is complex as it requires to have a
    loop in the driver to determine the maximum number of interrupts which
    are provided by the PCI capabilities and the underlying CPU resources.
    This loop would have to be replicated in every driver which wants to
    utilize this mechanism. That's unwanted code duplication and error
    prone.
    
    In order to move this into generic facilities it is required to have a
    mechanism, which allows the recalculation of the interrupt sets and
    their size, in the core code. As the core code does not have any
    knowledge about the underlying device, a driver specific callback will
    be added to struct affinity_desc, which will be invoked by the core
    code. The callback will get the number of available interupts as an
    argument, so the driver can calculate the corresponding number and size
    of interrupt sets.
    
    To support this, two modifications for the handling of struct irq_affinity
    are required:
    
    1) The (optional) interrupt sets size information is contained in a
       separate array of integers and struct irq_affinity contains a
       pointer to it.
    
       This is cumbersome and as the maximum number of interrupt sets is small,
       there is no reason to have separate storage. Moving the size array into
       struct affinity_desc avoids indirections and makes the code simpler.
    
    2) At the moment the struct irq_affinity pointer which is handed in from
       the driver and passed through to several core functions is marked
       'const'.
    
       With the upcoming callback to recalculate the number and size of
       interrupt sets, it's necessary to remove the 'const'
       qualifier. Otherwise the callback would not be able to update the data.
    
    Implement #1 and store the interrupt sets size in 'struct irq_affinity'.
    
    No functional change.
    
    [ tglx: Fixed the memcpy() size so it won't copy beyond the size of the
      	source. Fixed the kernel doc comments for struct irq_affinity and
      	de-'This patch'-ed the changelog ]
    Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Bjorn Helgaas <helgaas@kernel.org>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: linux-block@vger.kernel.org
    Cc: Sagi Grimberg <sagi@grimberg.me>
    Cc: linux-nvme@lists.infradead.org
    Cc: linux-pci@vger.kernel.org
    Cc: Keith Busch <keith.busch@intel.com>
    Cc: Sumit Saxena <sumit.saxena@broadcom.com>
    Cc: Kashyap Desai <kashyap.desai@broadcom.com>
    Cc: Shivasharan Srikanteshwara <shivasharan.srikanteshwara@broadcom.com>
    Link: https://lkml.kernel.org/r/20190216172228.423723127@linutronix.de
    
    9cfef55b
pci.c 77 KB