La limitación y la E/S de archivos pasiva pueden recibir algo de iluminación desde https://mjacobson.net/blog/2022-02-throttling.html
Algunas de estas pueden explicar por qué mi iMac de 2013 iba tan lento después de la actualización a Catalina. Ahora vuela después de que lo mueva para que arranque desde el Samsung T7 USB externo... y gracias/reconocimiento a Bombich por CCC por hacer una copia de Catalina booteable tan bien. (Esta puede ser la última macOS que podría ser clonada de esa manera.)
En caso de que esto desaparezca, aquí hay algunos puntos principales...
En Darwin, los hilos se bloquean dentro de throttle_lowpri_io cuando son artificialmente retrasados para disminuir la velocidad de sus operaciones de E/S, con el objetivo final de optimizar el rendimiento de E/S de mayor prioridad. Y de hecho, en ambos de estos casos (y en otros problemas similares que vi), la cadena de bloqueo conduce en última instancia a un hilo con una prioridad de E/S menos que la más alta.
.. Para llevar un registro de qué E/S deben ser limitadas, el kernel de Darwin mantiene lo que llamaré dominios de limitación (la fuente los llama struct _throttle_io_info_t). En términos generales, cada dominio de limitación está destinado a corresponder uno a uno a un dispositivo de disco.
Cuando se emite una E/S a través de la rutina spec_strategy, el kernel tiene que determinar en qué dominio de limitación vive la operación, para que la operación pueda ser limitada o causar la limitación de operaciones de menor prioridad. El dominio de limitación se determina primero tomando el vnod...>
..
Grupos de volúmenes lógicos y mnt_throttle_mask
Apple agregó un administrador de volúmenes lógicos, llamado CoreStorage, a Mac OS X Lion. A diferencia de las particiones de disco tradicionales, en las que se utiliza un rango continuo de un dispositivo de disco como un volumen, CoreStorage permite una relación menos estricta entre los volúmenes y el almacenamiento de respaldo. Por ejemplo, un volumen podría utilizar almacenamiento de múltiples dispositivos de disco diferentes, como se ve con Fusion Drive, por ejemplo.
Esto complica la situación de mnt_devbsdunit. Supongamos que un sistema de archivos está montado desde el volumen disk2. Según las reglas anteriores, mnt_devbsdunit es 2. Sin embargo, disk2 podría ser un volumen lógico de CoreStorage, respaldado por los dispositivos de disco reales disk0 y disk1.
Además, CoreStorage podría no ser el único usuario de disk0 y disk1. Supongamos además que hay un segundo volumen no perteneciente a CoreStorage en disk0, llamado disk0s3. Las E/S a disk2 y disk0s3 podrían competir entre sí. Pero el mnt_devbsdunit de disk0s3 es 0, por lo que los dos montajes estarán en diferentes dominios de limitación.
Para resolver esto, entra en juego un segundo campo de montaje, mnt_throttle_mask. mnt_throttle_mask es un array de bits de 64 bits. Un bit se establece solo cuando las E/S al montaje pueden implicar al dispositivo de disco con el número correspondiente. Para nuestro volumen lógico de CoreStorage disk2, como disk0 y disk1 están incluidos, se establecen los bits 0 y 1. El bit 2 también se establece para el volumen lógico en sí, por lo que la máscara general es 0x7.
En teoría, podría imaginar un sistema en el que un montaje pudiera residir en múltiples dominios de limitación. O tal vez la decisión del dominio de limitación podría ser delegada para que CoreStorage pudiera ayudar a tomar decisiones inteligentes sobre cuál usar para una operación de E/S particular.
La realidad implementada es mucho más mundana. mnt_devbsdunit se establece en el índice del bit más bajo establecido en mnt_throttle_mask. Para disk2, como el bit 0 está establecido, mnt_devbsdunit es 0. Por lo tanto, disk2 y disk0s3 viven en el mismo dominio de limitación (aunque, cabe destacar, que un disk1s3 teórico no lo haría).
Esto explica lo que está sucediendo con /System/Volumes/Data arriba. disk1s1 es un volumen lógico presentado por un administrador de volúmenes, y su almacenamiento de respaldo está en disk0. Ajustar el script de dtrace muestra que mnt_throttle_mask es 0x3:
..
Usar IOPOL_PASSIVE
Además de asignar una jerarquía de prioridad a sus operaciones de E/S, un proceso puede marcar sus E/S como pasivas; las E/S pasivas pueden ser limitadas pero no causan la limitación de otras E/S.
Volver a compilar dd para llamar a setiopolicy_np(3) sería una molestia. Una forma más fácil es usar el modificador de utilidad taskpolicy(8) que viene con las versiones recientes de macOS. Aunque no está documentado en la página del manual, la opción -d puede llevar el argumento passive, como:
# taskpolicy -d passive dd if=... Desactivar temporalmente la limitación
Hay un montón de sysctls disponibles para ajustar el comportamiento del sistema de limitación de E/S, incluido uno para apagarlo por completo:
# sysctl debug | fgrep lowpri_throttle debug.lowpri_throttle_max_iosize: 131072 debug.lowpri_throttle_tier1_window_msecs: 25 debug.lowpri_throttle_tier2_window_msecs: 100 debug.lowpri_throttle_tier3_window_msecs: 500 debug.lowpri_throttle_tier1_io_period_msecs: 40 debug.lowpri_throttle_tier2_io_period_msecs: 85 debug.lowpri_throttle_tier3_io_period_msecs: 200 debug.lowpri_throttle_tier1_io_period_ssd_msecs: 5 debug.lowpri_throttle_tier2_io_period_ssd_msecs: 15 debug.lowpri_throttle_tier3_io_period_ssd_msecs: 25 debug.lowpri_throttle_enabled: 1
# sysctl -w debug.lowpri_throttle_enabled=0 debug.lowpri_throttle_enabled: 1 -> 0