it-swarm-pt.com

Por que os bloqueios de rotação são boas opções no Linux Kernel Design, em vez de algo mais comum no código do ambiente do usuário, como semáforo ou mutex?

Eu entendo que Spinlocks são verdadeiros desperdícios no Linux Kernel Design.

Gostaria de saber por que é como se os bloqueios de rotação fossem boas escolhas no Linux Kernel Design em vez de algo mais comum no código do usuário, como semáforo ou mutex?

6
Sen

A escolha entre um spinlock e outra construção que faz com que o chamador bloqueie e abandone o controle de uma CPU é, em grande parte, governada pelo tempo que leva para realizar uma troca de contexto (salvar registros/estado no encadeamento de bloqueio e restaurar registros/estado em outro tópico). O tempo que leva e também o custo de cache para fazer isso podem ser significativos.

Se um spinlock estiver sendo usado para proteger o acesso a registradores de hardware ou similar, onde qualquer outro thread que está acessando vai levar apenas alguns milissegundos ou menos antes de liberar o bloqueio, então é um uso muito melhor do tempo de CPU para espera de rotação ao invés de mudar de contexto e continuar.

8
Richm

Como a questão implica dizer que spinlocks são um "desperdício", spinlocks devem ser mantidos apenas brevemente.

Spinlocks não são a única maneira de sincronizar vários threads. Mutexes/semáforos também são usados ​​no kernel do Linux, assim como outras primitivas de sincronização (por exemplo, waitqueues, eventos).

No entanto, o kernel tem que lidar com casos que o espaço do usuário nunca vê, um comum sendo os manipuladores de interrupção. Os manipuladores de interrupção não podem ser reprogramados no Linux, mas geralmente precisam usar alguma primitiva de sincronização (por exemplo, para adicionar um item de trabalho a uma lista vinculada que algum outro thread processará posteriormente). Visto que os manipuladores de interrupção não podem dormir, eles não podem usar mutexes, waitqueues, etc. Isso praticamente deixa os spinlocks. Se um thread precisa sincronizar o acesso com um manipulador de interrupção, ele também deve usar o mesmo spinlock.

Spinlocks não são necessariamente um desperdício. Eles são otimizados para o caso de não contenção/não espera e podem ser pegos e liberados muito rapidamente. Nesse caso, eles são mais rápidos e envolvem menos sobrecarga do que outros primitivos de sincronização.

11
James W

Outros responderam. Vou resumir os casos em que você usaria spinlock e regras para usar spinlock.

1. Quando o spinlock é usado?

Resp: Nas seguintes situações.

  1. O segmento que contém o bloqueio não pode entrar em suspensão.
  2. O thread que está esperando por um bloqueio não dorme, mas gira em um loop apertado.

Quando usado corretamente, o spinlock pode fornecer um desempenho superior ao do semáforo. Ex: manipulador de intrusão.

2. Quais são as regras para usar spinlocks?

Resp:

Regra - 1: Qualquer código que contenha o spinlock, não pode abandonar o processador por nenhum motivo, exceto para interrupções de serviço (às vezes nem mesmo). Portanto, o código que contém o spinlock não pode dormir.

Motivo: suponha que o driver que está segurando o spinlock vá dormir. Ex: chama a função copy_from_user() ou copy_to_user(), ou a preempção do kernel entra em ação, então o processo de prioridade mais alta empurrou o seu código de lado. Efetivamente, o processo libera o spinlock de retenção da CPU.

Agora não sabemos quando o código irá liberar o bloqueio. Se algum outro encadeamento tentar obter o mesmo bloqueio, ele girará por muito tempo. Na pior das hipóteses, isso resultaria em desbloqueio.

O caso de preempção do kernel é tratado pelo próprio código spinlock. Sempre que o código do kernel contém um spinlock, a preempção é desabilitada no processador relevante. Mesmo o sistema de um processador deve desabilitar a preempção dessa forma.

Regra - 2: Desabilite interrupções na CPU local, enquanto o spinlock é mantido.

Motivo: Ajude o seu driver a fazer um spinlock que controla o acesso ao dispositivo e depois emite uma interrupção. Isso faz com que o manipulador de interrupção seja executado. Agora, o manipulador de interrupção também precisa do bloqueio para acessar o dispositivo. Se o manipulador de interrupção for executado no mesmo processador, ele começará a girar. O código do driver também não pode ser executado para liberar o bloqueio. SO o processador girará para sempre.

Regra - 3: Spinlocks devem ser mantidos pelo menor tempo possível.

Motivo: Longos tempos de bloqueio também evitam que o processador atual seja escalonado, o que significa que um processo de maior prioridade pode ter que esperar para obter a CPU.

Portanto, isso impacta a latência do kernel (tempo que um processo pode ter que esperar para ser agendado). Normalmente os spinlocks devem ser mantidos durante o tempo, menos do que a CPU leva para fazer uma troca de contexto entre os threads.

Regra -4: se você tiver semáforos e spinlocks ambos a serem tomados. Em seguida, pegue o semáforo primeiro e depois o spinlock.

2
santosh