android - ¿Cómo definir y activar mi propio nuevo softirq en Linux kernel?
linux-kernel arm (2)
Me gustaría crear mi propio softirq en Linux kernel. ¿Es la forma correcta de hacerlo?
En el init
del módulo me gustaría disparar el softirq
desde Voy a agregar una llamada a:
394 void open_softirq(int nr, void (*action)(struct softirq_action *))
395 {
396 softirq_vec[nr].action = action;
397 }
Y en el fragmento me gustaría subir el softirq. Agregaré una llamada a la función raise_softirq
:
379 void raise_softirq(unsigned int nr)
380 {
381 unsigned long flags;
382
383 local_irq_save(flags);
384 raise_softirq_irqoff(nr);
385 local_irq_restore(flags);
386 }
Y agrega mi nuevo softirq
en:
411 /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
412 frequency threaded job scheduling. For almost all the purposes
413 tasklets are more than enough. F.e. all serial device BHs et
414 al. should be converted to tasklets, not to softirqs.
415 */
416
417 enum
418 {
419 HI_SOFTIRQ=0,
420 TIMER_SOFTIRQ,
421 NET_TX_SOFTIRQ,
422 NET_RX_SOFTIRQ,
423 BLOCK_SOFTIRQ,
424 BLOCK_IOPOLL_SOFTIRQ,
425 TASKLET_SOFTIRQ,
426 SCHED_SOFTIRQ,
427 HRTIMER_SOFTIRQ,
428 RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
429 MY_NEW_SOFTIRQ
430 NR_SOFTIRQS
431 };
Y aquí:
60 char *softirq_to_name[NR_SOFTIRQS] = {
61 "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
62 "TASKLET", "SCHED", "HRTIMER", "RCU", "MY_NEW_SOFTIRQ"
63 };
Las preguntas:
- ¿Estoy en lo cierto o me perdí algo?
- ¿Es la manera correcta de hacer eso? otras opciones?
Si desea parchar el núcleo y volver a compilarlo, probablemente lo haga bien (excepto que debe moverlo antes de RCU_SOFTIRQ).
De lo contrario, IOW si desea hacerlo en un módulo kernel, debe usar tasklet, que se basa en SoftIRQ, para hacer algo en el contexto de SoftIRQ:
tasklet_init()
se usa para iniciar su gancho.
tasklet_schedule()
para programar el tasklet que registra.
Declarar Softirq estáticamente
Estáticamente declare su softirq ( MY_NEW_SOFTIRQ
) agregándolo a la enum
y
char *softirq_to_name[NR_SOFTIRQS]
. Recompila el kernel.
Registre Softirq sobre la marcha
Una vez declarado estáticamente, nuestro propio softirq debe registrarse durante el tiempo de ejecución en el módulo kernel usando open_softirq()
. Suba en la ruta de salida del manejador de interrupción a través de raise_softirq()
.