11
votes

Pourquoi la section critique vide au sein de NetFilter Hooks, se produit `Bug: Planification tandis que Erreur atomique`?

J'ai écrit ce crochet: xxx

section init: xxx

J'ai défini une variable statique: < Pré> xxx

car il n'y a aucun code entre verrouillage et déverrouiller Je n'attends aucune erreur, mais lorsque j'exécute ce module, le noyau produit ces erreurs :

Erreur mise à jour: xxx

voici l'erreur SysLog complète: http://past.ubuntu.com/6617614/


3 commentaires

Oui, j'ai défini et l'initialise.


Ce message d'erreur est incomplet.


@Cl. J'ai mis à jour le message d'erreur.


4 Réponses :


8
votes

Ceci est un crochet de l'intérieur du noyau. Dormir, verrouiller un sémaphore (pend) ou toute opération de blocage ne sont pas autorisés; Vous bloquez le noyau!

Si vous souhaitez un objet de synchronisation, vous pouvez essayer d'utiliser des serrures de spin.

comme Cette réponse à une question similaire a déclaré, mutex_lock déclenchera le planificateur; Mais le noyau sera perplexe car vous essayez de planifier une autre tâche, alors que vous êtes dans la section critique (le rappel lui-même est une grande section critique).

Vérifiez ce fil Comprendre le contexte d'exécution de NetFilter Hooks pour similaire cas.


2 commentaires

Si le verrouillage avec mutex dans le noyau n'est pas autorisé, alors pourquoi les développeurs de noyau ont créé une API mutex à l'intérieur du noyau?


Les mutiles @Khajavi sont autorisés dans certains contextes, mais pas dans NetFilter Hooks.



6
votes

Même si mutex_lock () ne dormira probablement pas dans ce cas, il reste pourrait dormir. Puisque cela s'appelle dans un contexte atomique, l'erreur est levée.

Spécifiquement, celui-ci est causé par mutex_lock () appelant mai_sleep () , qui peut appeler __ calendrier ()

Si vous avez besoin de synchroniser, utilisez les appels appropriés, par exemple. Spinlocks et RCU.


0 commentaires

5
votes

Vous voyez ce message si votre tâche planifiée lorsqu'elle contient un synchro, probablement un spinlock. Lorsque vous verrouillez un spinlock, il augmente Preempt_Count; Lorsque le planificateur déteste la situation de la planification avec une augmentation croissante de préempte, il imprime exactement ce message:

/ * * Imprimez la planification pendant que Bug Atomic: P>

 */
static noinline void __schedule_bug(struct task_struct *prev)
{
        if (oops_in_progress)
                return;

        printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n",
                prev->comm, prev->pid, preempt_count());

        debug_show_held_locks(prev);
        print_modules();
        if (irqs_disabled())
                print_irqtrace_events(prev);
        dump_stack();
}


0 commentaires

4
votes

Ceci est un problème de contexte d'exécution clairement. Pour utiliser le verrouillage approprié dans le code du noyau, il faut être conscient dans quel contexte d'exécution ( Hard_irq | Bottom_half | Process_context ) Le code est appelé.

mutex_lock | mutex_unlock est uniquement pour la protection du code de protection_context.

selon http://www.gossamer-threads.com/lists/ IPTABLE / Devel / 56853

discussion, votre fonction hook_func peut être appelée sot_irq ou process_context . Donc, vous devez utiliser un mécanisme de verrouillage adapté à la protection entre ces deux contextes.

Je vous suggère de passer par le guide de verrouillage du noyau ( https : //www.kernel.org/pub/linux/kernel/people/rusty/kernel-ocking/ ). Le guide explique également les particularités impliquées lorsque le système est SMP (très courant) et la préemption est sur.

Pour test rapide Vous pouvez utiliser spin_lock_irqsave verrouillage dans votre Hook_func . spin_lock_irqsave est toujours en sécurité, il désactive les interruptions sur la CPU actuelle et Spinlock garantira une opération atomique sur le système SMP.

Maintenant, mot sur le crash:

mutex_lock | mutex_unlock ne peut être utilisé que dans le code process_context. Lorsque votre Hook_func est appelé à partir de soft_irq , mutex_lock cause le processus de courant de courant et à son tour invoque le planificateur. Dormir dans le code du noyau n'est pas autorisé dans le contexte atomique (voici soft_irq ).


0 commentaires