Documentation/translations/sp_SP/memory-barriers.txt

Source file repositories/reference/linux-study-clean/Documentation/translations/sp_SP/memory-barriers.txt

File Facts

System
Linux kernel
Corpus path
Documentation/translations/sp_SP/memory-barriers.txt
Extension
.txt
Size
126779 bytes
Lines
3135
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rw_semaphore {
		...
		spinlock_t lock;
		struct list_head waiters;
	};

	struct rwsem_waiter {
		struct list_head list;
		struct task_struct *task;
	};

Para despertar a un proceso que espera ("waiter") en particular, las
funciones up_read() o up_write() tienen que:

 (1) leer el siguiente puntero del registro de este proceso que espera,
     para saber dónde está el registro del siguiente waiter;

 (2) leer el puntero a la estructura de tareas del waiter;

 (3) borrar el puntero de la tarea para decirle al waiter que se le ha dado
     el semáforo;

 (4) llamar a wake_up_process() en la tarea; y

 (5) liberar la referencia retenida en la estructura de tareas del waiter.

En otras palabras, tiene que realizar esta secuencia de eventos:

	LOAD waiter->list.next;
	LOAD waiter->task;
	STORE waiter->task;
	CALL wakeup
	RELEASE task

y si alguno de estos pasos ocurre fuera de orden, entonces todo puede que
funcione defectuosamente.

Una vez que se ha puesto en cola y soltado el bloqueo de semáforo, el
proceso que espera no consigue el candado de nuevo; en cambio, solo espera
a que se borre su puntero de tarea antes de continuar. Dado que el registro
está en la pila del proceso que espera, esto significa que si el puntero de
la tarea se borra _antes_ de que se lea el siguiente puntero de la lista,
otra CPU podría comenzar a procesar el proceso que espera y podría romper
el stack del proceso que espera antes de que la función up*() tenga la
oportunidad de leer el puntero que sigue.

Considere entonces lo que podría suceder con la secuencia de eventos
anterior:

	CPU 1				CPU 2
	===============================	===============================
					down_xxx()
					Poner waiter en la "queue" (cola)
					Dormir
	up_yyy()
	LOAD waiter->task;
	STORE waiter->task;
					Despertado por otro evento
	<preempt>
					Reanudar el procesamiento
					down_xxx() regresa
					llamada a foo()
					foo() estropea *waiter
	</preempt>
	LOAD waiter->list.next;
	--- OOPS ---

Esto podría solucionarse usando el bloqueo de semáforo, pero luego la
función down_xxx() tiene que obtener innecesariamente el spinlock
nuevamente, después de ser despertado el hilo.

Annotation

Implementation Notes