/* @lock must be held when calling disconnect */ staticvoid __disconnect(struct irq_bypass_producer *prod, struct irq_bypass_consumer *cons)
{ if (prod->stop)
prod->stop(prod); if (cons->stop)
cons->stop(cons);
cons->del_producer(cons, prod);
if (prod->del_consumer)
prod->del_consumer(prod, cons);
if (cons->start)
cons->start(cons); if (prod->start)
prod->start(prod);
prod->consumer = NULL;
cons->producer = NULL;
}
/** *irq_bypass_register_producer-registerIRQbypassproducer *@producer:pointertoproducerstructure *@eventfd:pointertotheeventfdcontextassociatedwiththeproducer *@irq:LinuxIRQnumberoftheunderlyingproducerdevice * *AddtheprovidedIRQproducertothesetofproducersandconnectwiththe *consumerwithamatchingeventfd,ifoneexists.
*/ int irq_bypass_register_producer(struct irq_bypass_producer *producer, struct eventfd_ctx *eventfd, int irq)
{ unsignedlong index = (unsignedlong)eventfd; struct irq_bypass_consumer *consumer; int ret;
if (WARN_ON_ONCE(producer->eventfd)) return -EINVAL;
producer->irq = irq;
guard(mutex)(&lock);
ret = xa_insert(&producers, index, producer, GFP_KERNEL); if (ret) return ret;
consumer = xa_load(&consumers, index); if (consumer) {
ret = __connect(producer, consumer); if (ret) {
WARN_ON_ONCE(xa_erase(&producers, index) != producer); return ret;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.