Para o programa de coleta de dados do espaço do usuário, o que há de errado com um loop infinito? Contanto que você esteja usando a chamada de sistema poll
, ela deve ser eficiente: link ?
Armazenamento permanente de dados
Não sei qual é a melhor maneira de fazer isso, por que você não escreve apenas em um arquivo da userland na enquete? Eu suponho que sua preocupação é que, se muitos dados chegarem, os dados serão perdidos, é isso?
Mas duvido que o fator limitante seja o kernel da comunicação do usuário no caso, mas a lentidão do dispositivo de armazenamento permanente, portanto, fazê-lo na userland não fará nenhuma diferença, eu acho. Em qualquer caso, a única solução do kernel tem uma questão de alto nível em: link e não acho que você terá uma solução melhor aqui.
Desativar interrupções
Você tem certeza de que isso faria alguma diferença, especialmente considerando que o gargalo provavelmente será? Eu esperaria que se o seu dispositivo estivesse realmente produzindo um grande número de interrupções, então elas dominariam qualquer outra interrupção em qualquer caso. Vale a pena arriscar bagunçar o estado de outro hardware? As especificações do seu dispositivo de hardware sugerem que ele poderia fornecer fisicamente uma largura de banda de dados muito maior do que a que você tem atualmente?
Eu não sei como fazer isso sozinho, mas se você quiser uma resposta, sua melhor aposta é fazer uma pergunta separada com o título "Como desabilitar todas as interrupções de um módulo do kernel do Linux?". O LDD2 menciona a função cli()
link , mas parece que foi preterido: link Esse texto sugere local_irq_disable
e local_irq_save
.
Eu também tentaria hack-lo com qualquer método que você encontrasse para desabilitar as interrupções, e ver se fica mais eficiente antes de procurar mais se um método legal existir.
Em um emulador, um rápido:
static int myinit(void)
{
pr_info("hello init\n");
unsigned long flags;
local_irq_save(flags);
return 0;
}
falha com:
returned with disabled interrupts
aparentemente vindo de v4.16 do_one_initcall
, então há um erro especializado para lidar com isso!
Eu então tentei ingenuamente fazer isso a partir de um thread de trabalho:
static int work_func(void *data)
{
unsigned long flags;
local_irq_save(flags);
return 0;
}
static int myinit(void)
{
kthread = kthread_create(work_func, NULL, "mykthread");
wake_up_process(kthread);
return 0;
}
mas ainda assim não consigo observar nenhum efeito, então as interrupções devem estar sendo ativadas por alguma outra coisa, como pode ser inferido de:
watch -n 1 grep i8042 /proc/interrupts
que continua atualizando tty ou muse / interrupções de teclado.
O mesmo de outros pontos de entrada, como fops, ou se eu tentar um asm("cli")
bruto. Vamos precisar de uma abordagem mais educada.