2016-08-08 32 views
1

Sorry, wenn das sehr einfach ist. Dies ist eine vereinfachte Version von dem, was ich mache. Ich schreibe ein Kernel-Modul. Wenn es läuft, gibt es zwei Threads, eine zwei verschiedene physische CPU. Ich verwende eine globale Variable, um bestimmte Kommunikation zwischen diesen Threads zu tun. Das Merkwürdige ist, dass manchmal das Schreiben eines Threads vom anderen nicht gesehen wird. Was könnte der Grund sein?Warum wird von einer CPU geschriebener Wert von der anderen nicht gesehen?

Ich vermute, dass es mit Speicherbarriere und vielleicht Cache-Synchronisation zu tun hat, also habe ich versucht, smp_wmb() nach dem Schreiben, aber es scheint nicht zu helfen. Und soweit ich weiß, kann ich die Cache-Synchronisation nicht explizit steuern. Also bin ich irgendwie festgefahren.

Irgendwelche Ideen?

EDIT: machen Sie es klar, dass die Beschreibung eine vereinfachte Version ist.

+0

Könnte eine Menge Dinge sein. Da das Kernel-Modul C annimmt, haben Sie die Variable volatile deklariert? –

+0

@GabeSechan Ja, ich habe das versucht. – TFC

+0

Befolgen Sie die Muster, die der andere Kernel-Code verwendet. Außer wenn Sie etwas unglaublich Ungewöhnliches tun, sollte die Schreibspeicherbarriere vor dem Schreiben sein. Welche Bedeutung vermittelt dieser Wert? –

Antwort

-1

Ich denke, dass Sie wegen der Compileroptimierung mit dem Problem konfrontiert sind.

Haben Sie versucht, volatile zu verwenden? Ich denke, volatile wird in Ihrem Fall funktionieren.

Das Schlüsselwort volatile sollte verwendet werden, wenn gleichzeitige unsynchronisierte Operationen für eine Variable aus mehr als einer Quelle (Prozess) ausgeführt werden. Wenn die Variable als flüchtig deklariert wird, greifen alle Prozesse immer direkt von ihrem Speicherort auf die Variable zu, anstatt die Variable in den Cache des Mikroprozessors zu kopieren und von dort auf sie zuzugreifen.

+0

Das flüchtige Qualifikationsmerkmal wirkt sich im Allgemeinen nicht darauf aus, ob sich der Wert einer Variablen im Cache oder im Arbeitsspeicher befindet. Es wirkt sich im Allgemeinen nur darauf aus, ob der Wert der Variablen vorübergehend in einem Register gehalten wird. –

0

Zuerst machen Sie es falsch. Die richtige Synchronisation zwischen CPUs ist ziemlich kompliziert und sehr architekturspezifisch. Sie sollten einige der vorhandenen Kernel-Mechanismen für die Thread-Synchronisierung verwenden. Sofern Sie keine speziellen Leistungsanforderungen haben, verwenden Sie nur Spinlocks. Dann können Sie bei Bedarf ein wenig mehr über verschiedene Synchronisationsmechanismen lesen und einen finden, der am besten zu Ihrer Arbeitslast passt.

Um Ihre Frage direkter zu beantworten - es gibt mindestens zwei Probleme, die Sie hier begegnen können: 1. Befehl Reorder von Compiler, der in der Regel von Compiler Barrieren (d. H.) gesorgt wird. 2. Out-of-Order-Ausführung durch CPU- und Cache-Kohärenz, die normalerweise durch Speicherbarrieren bewältigt wird.

Details sind Architektur und Usecase-spezifisch, aber Sie haben keine Code- oder Architekturdetails bereitgestellt, die wir analysieren könnten. Daher müssen Sie möglicherweise mindestens eines der folgenden Geräte verwenden: barrier(), smp_wmb(), smp_rmb() und smp_read_barrier_depends().