1

Linux Kernel Entwicklung von Robert Love heißt es:Warum ist Mutex_trylock nicht sicher für Interrupts?

Ein Mutex kann nicht durch einen Interrupt-Handler oder untere Hälfte, sogar mit mutex_trylock()

Bei http://landley.net/kdocs/htmldocs/kernel-locking.html erworben werden, seine erwähnt, dass

mutex_tryclock() unterbricht Ihre Aufgabe nicht, gibt aber nicht Null zurück, wenn der Mutex beim ersten Versuch gesperrt werden konnte oder 0, falls nicht. Diese Funktion kann nicht sicher in Hardware- oder Softwareinterrupt-Kontexten trotz nicht schlafen verwendet werden.

Ich verstehe nicht, warum es nicht in solchen Fällen verwendet werden kann, wenn es nicht schlafen geht?

+0

Bei https://lwn.net/Articles/167034 fand ich die folgende Aussage "Diese Einschränkung scheint mehr damit zu tun zu haben, Mutexe davon abzuhalten, jemals als Vervollständigung verwendet zu werden, als eine grundlegende Einschränkung", aber ich kann nicht wirklich zu verstehen, was es bedeutet (was ist Fertigstellungen)? – user3740387

+0

Wie ich verstehe, bedeutet "Vervollständigungen" die Verwendung von Mutex als Vervollständigungssignal. Zum Beispiel versucht A, einen Mutex zu halten, der bereits durch B gesperrt ist. Er lässt A warten. Dann kann A durch Loslassen der Sperre mit B fortfahren. In dem Artikel, den du erwähnt hast, heißt es: "Ein Mutex kann nur vom Besitzer freigeschaltet werden - was eine Aufgabe sein muss." Mutex kann jedoch durch eine einzelne Aufgabe gesperrt/entsperrt werden, wobei der Usecase ein kritischer Abschnitt sein sollte. – jaeyong

Antwort

3

Stellen Sie sich vor, Sie hätten eine Plattform, deren native primitive Mutexe auf niedriger Ebene keine "try lock" -Operation haben. Um in diesem Fall einen High-Level-Mutex zu implementieren, müssten Sie eine Zustandsvariable und einen booleschen "is locked" verwenden, der durch den Low-Level-Mutex geschützt wird, um anzuzeigen, dass der High-Level-Mutex gesperrt wurde.

So könnte ein Waitable-Mutex mit einem Low-Level-Primitiv-Mutex (der keine "Trylock" -Operation unterstützt) implementiert werden, um einen High-Level-Mutex zu implementieren (das ist). Der "High-Level-Mutex" kann einfach ein Boolescher Wert sein, der durch den Low-Level-Mutex geschützt wird.

Mutex
  1. Acquire Low-Level (das ist eine echte Sperroperation auf der primitiven, Implementierung Mutex):

    Mit diesem Design, mutex_lock würde wie folgt umgesetzt werden.

  2. Wenn High-Level-Mutex gehalten wird, warten Sie auf den High-Level-Mutex.
  3. Erwerben High-Level-Mutex (nur locked = true;).
  4. L-Pegel-Mutex freigeben.

    1. Acquire Low-Level-Mutex:

    Und mutex_unlock würde wie folgt umgesetzt werden.

  5. High-Level-Mutex freigeben (nur locked = false;)
  6. Signal der Zustandsvariablen.
  7. Lassen Sie den Low-Level-Mutex los.

    Mutex
    1. Acquire Low-Level:

    In diesem Fall mutex_trylock würde wie folgt umgesetzt werden.

  8. Überprüfen, ob High-Level-Mutex gehalten wird.
  9. Wenn ja, geben Sie Low-Level-Mutex und Fehler zurück.
  10. Nehmen Sie High-Level-Mutex.
  11. L-Pegel-Mutex freigeben.
  12. Zurück Erfolg.

Stellen Sie sich vor, wenn wir nach dem Schritt 2, aber vor dem Schritt unterbrochen sind 3.

+0

Machen Sie das nicht zu einer "grundsätzlichen" Einschränkung im Widerspruch zu der Stmt. gemacht in http://lwn.net/Articles/167034 Ich postete in einem Kommentar zu meiner Frage? – user3740387

+0

Ich betrachte deinen Fall folgendermaßen: High-Level-Mutex ist verfügbar, Interrupt passiert, jemand anderes nimmt den High-Level-Mutex, wir kehren nach einiger Zeit zum mutex_trylock-Code zurück und nehmen dann High-Level-Mutex in Schritt 4 wieder, obwohl es bereits vergeben ist. – user3740387

+0

@ user3740387 Die Einschränkung ist sinnvoll, da sie es zulässt, dass es sich um einen High-Level-Mutex handelt, anstatt zu erzwingen, dass es als primitiv implementiert wird. Und ja, Sie verstehen das Problem richtig - Interrupt-sichere Synchronisation Primitive sind verschiedene Tiere von generischen. –

0

sein kann, ist es, weil in mutex_trylock Interrupts werden nicht deaktiviert. Wenn wir ein Szenario haben, in dem ein Mutex im Interrupt-Kontext mit mutex_trylock gesperrt ist und ein anderer Interrupt kommt, der versucht, den gleichen Mutex zu erhalten. Dies kann zu einer Deadlock-Situation führen.