J'ai écrit ce crochet: section init: p> J'ai défini une variable statique: p> < Pré> xxx pré> car il n'y a aucun code entre voici l'erreur SysLog complète: http://past.ubuntu.com/6617614/ p> p> verrouillage code> et
déverrouiller code> Je n'attends aucune erreur, mais lorsque j'exécute ce module, le noyau produit ces erreurs : P>
Erreur mise à jour: h1>
4 Réponses :
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! P>
Si vous souhaitez un objet de synchronisation, vous pouvez essayer d'utiliser des serrures de spin. P>
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). P>
Vérifiez ce fil Comprendre le contexte d'exécution de NetFilter Hooks pour similaire cas. p>
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.
Même si Spécifiquement, celui-ci est causé par Si vous avez besoin de synchroniser, utilisez les appels appropriés, par exemple. Spinlocks et RCU. P> mutex_lock () code> ne dormira probablement pas dans ce cas, il reste pourrait em> dormir.
Puisque cela s'appelle dans un contexte atomique, l'erreur est levée. P>
mutex_lock () code> appelant
mai_sleep () code>, qui peut appeler
__ calendrier () p> p> p>
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(); }
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 ( selon http://www.gossamer-threads.com/lists/ IPTABLE / Devel / 56853 P>
discussion, votre fonction 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. p>
Pour test rapide Vous pouvez utiliser Maintenant, mot sur le crash: p>
Hard_irq Code> |
Bottom_half code> |
Process_context code>) Le code est appelé. p>
mutex_lock code> |
mutex_unlock code> est uniquement pour la protection du code de protection_context. P>
hook_func code> peut être appelée
sot_irq code> ou
process_context code>.
Donc, vous devez utiliser un mécanisme de verrouillage adapté à la protection entre ces deux contextes. P>
spin_lock_irqsave code> verrouillage dans votre
Hook_func code>.
spin_lock_irqsave code> 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. P>
mutex_lock code> |
mutex_unlock code> ne peut être utilisé que dans le code process_context. Lorsque votre
Hook_func code> est appelé à partir de
soft_irq code>,
mutex_lock code> 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 code>). P>
Oui, j'ai défini et l'initialise.
Ce message d'erreur est incomplet.
@Cl. J'ai mis à jour le message d'erreur.