Un artículo que analiza la historia de vida de block io.

Como parte importante del negocio del almacenamiento, el bloque IO es el único camino hacia el almacenamiento no volátil. Cada etapa de su ciclo de vida está directamente relacionada con el rendimiento, el consumo de energía e incluso la vida útil de nuestros teléfonos móviles. Este artículo intenta explicar el curso de vida de un bloque IO a través de las cuatro etapas de generación, programación, entrega y devolución de bloque IO.

1. ¿Qué es un dispositivo de bloque y una capa de dispositivo de bloque?

Desde el nacimiento de las computadoras, ha habido dispositivos IO. Los dispositivos IO se dividen aproximadamente en dos categorías, dispositivos de bloque y dispositivos de caracteres. Las dos características importantes de los dispositivos de bloque son: almacenamiento en bloque y direccionabilidad. La capa de dispositivo de bloqueo es una capa lógica de software que permite que las solicitudes para bloquear dispositivos se completen de manera eficiente y razonable a través de la gestión organizacional. Como se muestra en la figura anterior, en la estructura de disco tradicional, reducir el movimiento del brazo/cabezal (acción mecánica) hace que sea más fácil encontrar la dirección de destino, lo que puede mejorar el rendimiento de IO.

La posición de la capa del dispositivo de bloque en toda la pila de almacenamiento se muestra en la siguiente figura y está conectada al sistema de archivos y al controlador del dispositivo de bloque específico (UFS, controlador EMMC) a continuación:

La herramienta de código abierto blktrace se puede utilizar para analizar los rastros de E/S y el rendimiento. AQGP comienza a crear el complemento del subproceso y luego AQM completa la fusión del complemento dentro del subproceso. Finalmente, IUDC completa la emisión y devolución del complemento dentro del mismo. la amenaza.

2. La generación de bloque IO.

Desde la apertura de cada aplicación en el teléfono móvil hasta el programa en lenguaje C que muchas personas escribieron cuando eran estudiantes, se producirá el bloque IO. En esencia, blockIO puede ocurrir siempre que se llamen a las funciones de biblioteca abrir, leer, cerrar, escribir, fsync y sincronizar en la biblioteca libc.

1.  Operaciones de archivos comunes en modo usuario

2. Sistema de archivos IO ~ leer con anticipación

3. Sistema de archivos IO ~ reescritura de página sucia

4. Sistema de archivos IO ~ fsync y sincronización

5. Escritura del dispositivo IO ~ dm del sistema de archivos

Obtenga la pista del dispositivo dm (253:26) con el siguiente comando:

./blktrace -d /dev/block/dm-26 -o - |./blkparse -i -

Dado que existe una capa de mapeo desde el dispositivo dm al dispositivo físico real, para la misma dirección lógica 8898352, use el siguiente comando para obtener la pista del bloque IO para esta dirección lógica en su dispositivo físico mapeado (259:41) En el dispositivo físico, la dirección del bloque cambió de 8898352 a 33294128 después de la reasignación.

./blktrace -d /dev/block/sdc57 -o - | ./blkparse -i -

Aquí tomamos el dispositivo dm tipo verity como ejemplo y su ruta de generación de bloque io:

Seis.ruta de generación de E/S directa

Las operaciones anteriores de lectura anticipada, reescritura de páginas sucias y sincronización pasan por la caché de la página. Algunos software de evaluación comparativa como androbench no pasan por la caché de la página. Se centran más en el rendimiento del almacenamiento subyacente directo y utilizan E/S directa. La siguiente figura muestra la ruta de generación de IO del bloque de IO directa.

  Information Direct: ruta de aprendizaje de tecnología del código fuente del kernel de Linux + video tutorial sobre el código fuente del kernel

Learning Express: Código fuente del kernel de Linux Ajuste de memoria Sistema de archivos Gestión de procesos Controlador de dispositivo/Pila de protocolo de red

3. Programación del bloque IO

http://1.IO marco general de programación

La programación se encuentra a menudo en nuestra vida diaria, como ascensores o taxistas que envían viajes, horarios de comida escalonados, desplazamientos escalonados, etc., todo para mejorar el rendimiento general y el consumo de energía.

Algunos escenarios de generación de IO en bloque se enumeran anteriormente. Cuando se generan estas IO, también necesitan un mecanismo de programación adecuado para un mejor rendimiento general y consumo de energía. Una vez generada la IO, pasa por la cola suave, el programador, la cola dura y finalmente completa el envío.

2. La relación entre las estructuras de datos clave: biografía, solicitud, página y sector.

Finalmente se combinan una o más BIOS en una solicitud. Cada solicitud es una estructura de datos directa orientada al controlador del dispositivo de almacenamiento, que lleva la dirección virtual de la página de memoria y la dirección lógica del medio de almacenamiento. Es el intercambio de datos entre volátiles. medios y medios no volátiles puente.

Cada biografía contiene una matriz bio_vec y cada elemento de la matriz apunta a una página de memoria.

Cada biografía contiene un bvec_iter, que contiene el sector del medio de almacenamiento al que apunta este io.

No existe un requisito continuo para las páginas de memoria, pero los sectores del medio de almacenamiento deben estar conectados de extremo a extremo, porque en el código del controlador, sglist puede contener múltiples puntos discretos y las direcciones de los sectores en el medio de almacenamiento no son continuas, lo que causar que el cabezal magnético se ajuste repetidamente, lo que reduce en gran medida el rendimiento. Dado que sglist es un bus de memoria que direcciona el acceso, no hay ningún problema de rendimiento. En medios flash, aunque no interviene el ajuste del cabezal, si es discontinuo la velocidad de programación se reducirá considerablemente.

3.bio -> solicitud

Una biografía pasa por una división, una fusión de enchufe, una fusión de ascensor y finalmente se fusiona con una solicitud existente u obtiene una solicitud nueva.

4.remapeo del desarrollador donde se encuentra el bloque IO

Para comprender mejor las operaciones de reasignación y fusión de bloques IO, hablemos de los conceptos de dispositivos de bloques y tablas de particiones. Cada dispositivo (como LU0, LU1) tiene una estructura gendisk, pero una LU (Unidad lógica) a menudo se divide en varias particiones. gendisk contiene la tabla de particiones de este dispositivo. Para cada partición dividida, puede montar de forma independiente su propio sistema de archivos y comenzar a direccionar dentro del sistema de archivos desde 0. Cuando se forma IO y se envía al dispositivo, dado que la administración de direcciones internas del dispositivo se basa en LU, es necesario encontrar primero el desplazamiento de la partición en la tabla de particiones, más el desplazamiento dentro del sistema de archivos. Dirección lógica de direccionamiento orientada a LU.

5.biodivisión

Una biografía tiene una cantidad máxima de datos que puede soportar. Si la excede, se dividirá. La siguiente figura es un diagrama dividido con un límite de 512 KB.

6.  fusión biológica

bio intentará fusionarse una vez en el propio complemento de este hilo. Si la fusión no tiene éxito, continuará intentando fusionarse en la cola del ascensor correspondiente a esta cola. Para mq (multicola), también puede intentar fusionarse en el software -cola.

7. Enrosque el tapón y desenchufe

Fusionar y conectar ambas tiendas actuales, lo que reduce la frecuencia de las solicitudes que se envían al dispositivo de almacenamiento. La espera de conexión también aumentará las posibilidades de fusión. Sólo trabajando juntos se puede mejorar el rendimiento general de IO. La puerta solo se abrirá cuando la programación, io_schedule o el hilo llamen explícitamente a blk_finish_plug.

8.  Algoritmo de programación de ascensores

Cada cola se puede configurar con un programador de IO, es decir, un programador de IO. Los más comunes incluyen noop, fecha límite, cfq, etc. La programación del elevador fusiona y clasifica aún más las solicitudes de acuerdo con el algoritmo seleccionado (según el intervalo de tiempo, la prioridad del proceso, la sincronización). Asincrónico y otros factores), determinan la próxima solicitud de envío.

9.  Relación entre colas

La capa de dispositivo de bloque de Linux ha cambiado gradualmente a cola múltiple y el código de cola única se eliminó por completo después de Linux 5.0. La idea central de la cola múltiple es asignar una cola de software a cada CPU y una cola de envío de hardware a cada cola de hardware del dispositivo de almacenamiento, lo que reduce en gran medida la competencia de bloqueo. A lo largo de la vida del bloque IO, existen tres tipos de colas comunes: request_queue, blk_mq_ctx, blk_mq_hw_ctx. Cada dispositivo de bloque tiene 1 request_queue, que contiene atributos de cola relacionados con el dispositivo y puede entenderse como el administrador de colas.

Cada dispositivo de bloque tiene una o más colas duras para los controladores subyacentes, como la administración de etiquetas. request_queue, blk_mq_ctx, blk_mq_hw_ctx pueden atravesarse entre sí.

4. Entrega del bloque IO

1. Modelo de productor y consumidor

Después de un largo proceso de generación y programación, finalmente se comenzó a emitir una solicitud al dispositivo. Aquí abstraemos el modelo común de productor-consumidor. Cada dispositivo tiene su propia cola de productor (cola de ascensor, cola de software), pero la cola de consumidor (cola de hardware) puede compartirse. En un escenario de cola de hardware única (actualmente UFS, eMMC).

2. subsistema scsi y dispositivo ufs

El dispositivo ufs utiliza el conjunto de comandos comunes (lectura, escritura, desasignación, etc.) definido por el protocolo scsi, así como varios procesos, como el manejo de excepciones comunes del subsistema scsi, por lo que el controlador ufs se registra en el subsistema scsi después inicialización, como equipo scsi.

Los sdc, sdc1 y sdc2 vistos anteriormente se completan en la función sd_probe anterior.

sd_probe también analizará la tabla de particiones correspondiente a este dispositivo y agregará cada partición correspondiente a este dispositivo al dispositivo de bloque.

3. Estructuras clave de los dispositivos scsi

Cada scsi_device comparte un host y todos los dispositivos scsi se pueden encontrar a través de este host.

Entre los dispositivos scsi scsi_device registrados por Ufs, todos los scsi_devices comparten un hostdata, es decir, ufs_hba.

Diferentes scsi_device tienen su propia request_queue.

Otro scsi_device corresponde a 1 LU. El W-LUN y el LUN en la siguiente figura pertenecen a diferentes scsi_device.

Tomando como ejemplo 6 scsi_devices (3 LUN + 3 W-LUN) en una determinada plataforma, las estructuras de datos correspondientes son las siguientes:

4. Obtención y emisión de IO

Como consumidor, recibes solicitudes de los productores. El proceso de obtención de solicitudes tendrá prioridad. La lista enlazada que obtengas primero depende de diferentes estrategias.

5. Interconexión de los controladores subyacentes de mmc y ufs

Cuando se genera cada dispositivo de bloque, establecerá su propia request_queue y sus atributos y funciones de devolución de llamada. Por ejemplo, los dispositivos mmc y ufs configuran mmc_request_fn y scsi_request_fn como request_fn de esta request_queue respectivamente, logrando así el desacoplamiento de la capa de bloque y el dispositivo. capa conductora. .

6. Manejo de rutas de excepción como scsi_device ocupado

Cuando una solicitud ingresa a la capa scsi, se evaluarán los distintos estados del destino scsi y del host scsi para verificar si cumplen con las condiciones de entrega. Cuando ocurre una excepción de IO, comienza desde la devolución de llamada de tiempo de espera de la capa de bloque, llama a la capa scsi y luego llama a la función de manejo de excepciones de la capa del controlador ufs, como ufshcd_abort, ufshcd_eh_device_reset_handler.

5. Retorno del bloque IO

1. Interrupción brusca del controlador

Después de que el dispositivo de almacenamiento procesa la solicitud, el controlador informa la interrupción al GIC, ingresa a la primera mitad del procesamiento de la interrupción y luego activa el softirq. El proceso general es el siguiente. Algunas solicitudes especifican una determinada CPU, lo que implica problemas de uso compartido de caché entre la mitad superior actual de la CPU que acepta interrupciones y su CPU designada. Si se comparten, incluso si las dos son diferentes, la mitad superior actual de la CPU que acepta interrupciones activará la CPU. current El software de la CPU se ocupa principalmente de problemas de rendimiento.

2. Interrupción suave

3.  Devolución de llamada del sistema de archivos

Después de que cada proceso emite una solicitud de IO, se colocará en la cola de espera. Cuando regrese la solicitud de IO, volverá a llamar de abajo hacia arriba y finalmente se ajustará a wait_on_page_locked para activar el proceso de camarero de la página actual, completando así toda la manzana El curso de vida de IO.

6. Resumen

En problemas de rendimiento, a menudo nos encontramos con el problema de que el tiempo de espera de un determinado proceso es demasiado largo, entonces, ¿cómo se calcula este tiempo y qué rango cubre? Desde la perspectiva de la CPU, es el rango de tiempo desde que el proceso sale de la cola hasta que se vuelve a poner en la cola. Desde la perspectiva del bloque IO, cubre el rango de tiempo de todo el curso de vida del bloque IO iniciado por el proceso. A través de las cuatro etapas de vida de blockIO, podemos comprender mejor la distribución que requiere mucho tiempo de iowait.

Autor original: Kernel Craftsman

 

Supongo que te gusta

Origin blog.csdn.net/youzhangjing_/article/details/132502868
Recomendado
Clasificación