Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

irqbypass: Explicitly track producer and consumer bindings

Explicitly track IRQ bypass producer:consumer bindings. This will allow
making removal an O(1) operation; searching through the list to find
information that is trivially tracked (and useful for debug) is wasteful.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
Link: https://lore.kernel.org/r/20250516230734.2564775-5-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>

+16
+7
include/linux/irqbypass.h
··· 29 29 * pairings are not supported. 30 30 */ 31 31 32 + struct irq_bypass_consumer; 33 + 32 34 /** 33 35 * struct irq_bypass_producer - IRQ bypass producer definition 34 36 * @node: IRQ bypass manager private list management 35 37 * @eventfd: eventfd context used to match producers and consumers 38 + * @consumer: The connected consumer (NULL if no connection) 36 39 * @irq: Linux IRQ number for the producer device 37 40 * @add_consumer: Connect the IRQ producer to an IRQ consumer (optional) 38 41 * @del_consumer: Disconnect the IRQ producer from an IRQ consumer (optional) ··· 49 46 struct irq_bypass_producer { 50 47 struct list_head node; 51 48 struct eventfd_ctx *eventfd; 49 + struct irq_bypass_consumer *consumer; 52 50 int irq; 53 51 int (*add_consumer)(struct irq_bypass_producer *, 54 52 struct irq_bypass_consumer *); ··· 63 59 * struct irq_bypass_consumer - IRQ bypass consumer definition 64 60 * @node: IRQ bypass manager private list management 65 61 * @eventfd: eventfd context used to match producers and consumers 62 + * @producer: The connected producer (NULL if no connection) 66 63 * @add_producer: Connect the IRQ consumer to an IRQ producer 67 64 * @del_producer: Disconnect the IRQ consumer from an IRQ producer 68 65 * @stop: Perform any quiesce operations necessary prior to add/del (optional) ··· 77 72 struct irq_bypass_consumer { 78 73 struct list_head node; 79 74 struct eventfd_ctx *eventfd; 75 + struct irq_bypass_producer *producer; 76 + 80 77 int (*add_producer)(struct irq_bypass_consumer *, 81 78 struct irq_bypass_producer *); 82 79 void (*del_producer)(struct irq_bypass_consumer *,
+9
virt/lib/irqbypass.c
··· 51 51 if (prod->start) 52 52 prod->start(prod); 53 53 54 + if (!ret) { 55 + prod->consumer = cons; 56 + cons->producer = prod; 57 + } 54 58 return ret; 55 59 } 56 60 ··· 76 72 cons->start(cons); 77 73 if (prod->start) 78 74 prod->start(prod); 75 + 76 + prod->consumer = NULL; 77 + cons->producer = NULL; 79 78 } 80 79 81 80 /** ··· 152 145 153 146 list_for_each_entry(consumer, &consumers, node) { 154 147 if (consumer->eventfd == producer->eventfd) { 148 + WARN_ON_ONCE(producer->consumer != consumer); 155 149 __disconnect(producer, consumer); 156 150 break; 157 151 } ··· 242 234 243 235 list_for_each_entry(producer, &producers, node) { 244 236 if (producer->eventfd == consumer->eventfd) { 237 + WARN_ON_ONCE(consumer->producer != producer); 245 238 __disconnect(producer, consumer); 246 239 break; 247 240 }