Verständnis Von Linux-Kernel-Ringpuffer

Gibt es einen Artikel unter: http://lwn.net/Articles/378262/, beschreibt die Linux-Kernel Ringpuffer-implementation. Ich habe einige Fragen:

Hier ist der "Produzent":

spin_lock(&producer_lock);

unsigned long head = buffer->head;
unsigned long tail = ACCESS_ONCE(buffer->tail);

if (CIRC_SPACE(head, tail, buffer->size) >= 1) {
    /* insert one item into the buffer */
    struct item *item = buffer[head];

    produce_item(item);

    smp_wmb(); /* commit the item before incrementing the head */

    buffer->head = (head + 1) & (buffer->size - 1);

    /* wake_up() will make sure that the head is committed before
     * waking anyone up */
    wake_up(consumer);
}

spin_unlock(&producer_lock);

Fragen:

  1. Da dieser code befasst sich explizit mit memory-Bestellung und Unteilbarkeit was ist der Punkt, der spin_lock()?
  2. So weit, mein Verständnis ist, dass ACCESS_ONCE Stoppt compiler umsortieren wahr?
  3. Hat produce_item(item) einfach alle schreibt im Zusammenhang mit dem Artikel?
  4. Ich glaube smp_wmb() garantiert, dass alle Schreibvorgänge in produce_item(item) abgeschlossen ist, BEVOR der "veröffentlichen" schreiben, die darauf folgt. wahr?
  5. Der Kommentar auf der Seite, wo ich diese code scheint zu implizieren, dass eine smp_wmb() würde
    normalerweise benötigt Sie nach der Aktualisierung der Kopf-index, aber wake_up(Verbraucher) dies tut, so ist es nicht notwendig. Ist das wahr? Wenn ja, warum?

Hier ist der "Verbraucher":

spin_lock(&consumer_lock);

unsigned long head = ACCESS_ONCE(buffer->head);
unsigned long tail = buffer->tail;

if (CIRC_CNT(head, tail, buffer->size) >= 1) {
    /* read index before reading contents at that index */
    smp_read_barrier_depends();

    /* extract one item from the buffer */
    struct item *item = buffer[tail];

    consume_item(item);

    smp_mb(); /* finish reading descriptor before incrementing tail */

    buffer->tail = (tail + 1) & (buffer->size - 1);
}

spin_unlock(&consumer_lock);

Spezifische Fragen zum "Verbraucher":

  1. Was bedeutet smp_read_barrier_depends() zu tun? Aus einigen Kommentaren in einem forum, es scheint, wie Sie haben könnte, hat ein smp_rmb() hier, aber auf manchen Architekturen ist dies unnötig (x86) und zu teuer, so smp_read_barrier_depends() wurde erstellt, um zu tun, diese Optional... Das heißt, ich weiß wirklich nicht verstehen, warum smp_rmb() ist immer notwendig!
  2. Ist die smp_mb() gibt es die Garantie, dass alle liest, bevor es abgeschlossen ist, bevor das schreiben nach es?
InformationsquelleAutor dicroce | 2013-01-17
Schreibe einen Kommentar