aclarando problemas de nvme apst para linux

Sep 30 2020

He experimentado un problema casi idéntico al descrito en la comunidad askubuntu .

Al igual que la del usuario que publicó este tema, mi sistema cuenta con un disco Kingston NVMe, y como con ese usuario, mi problema resuelto mediante la adición de la opción del kernel siguiente en el menú de grub: nvme_core.default_ps_max_latency_us=0.

La resolución declarada por el usuario comienza de la siguiente manera:

El problema era de las características de un SSD, las Transiciones de estado de energía autónoma (APST) estaban causando las congelaciones. Para mitigarlo, hasta que publiquen la solución, incluya la línea nvme_core.default_ps_max_latency_us=0en las GRUB_CMDLINE_LINUX_DEFAULTopciones.

Aunque es útil, este comentario deja varias preguntas abiertas, incluidas las siguientes:

  1. ¿Cuál y dónde está la falla específica que causa el problema?
  2. ¿Qué cambia la solución alternativa para evitar la presentación del defecto?
  3. ¿Qué funcionalidad u otro efecto deseado se pierde debido a esta solución?
  4. Y especialmente, ¿qué se requiere arreglar, el kernel, el firmware de los medios de almacenamiento, el firmware del sistema (es decir, UEFI / BIOS), o algún otro componente, para proporcionar una resolución adecuada?

Cualquier comentario es útil para intentar resolver total o parcialmente esta confusión.

Respuestas

5 telcoM Sep 30 2020 at 13:26

El comentario de código dentro drivers/nvme/host/core.cde la fuente del kernel de Linux parece explicarlo mejor:

static int nvme_configure_apst(struct nvme_ctrl *ctrl)
{
    /*
     * APST (Autonomous Power State Transition) lets us program a
     * table of power state transitions that the controller will
     * perform automatically.  We configure it with a simple
     * heuristic: we are willing to spend at most 2% of the time
     * transitioning between power states.  Therefore, when running
     * in any given state, we will enter the next lower-power
     * non-operational state after waiting 50 * (enlat + exlat)
     * microseconds, as long as that state's exit latency is under
     * the requested maximum latency.
     *
     * We will not autonomously enter any non-operational state for
     * which the total latency exceeds ps_max_latency_us.  Users
     * can set ps_max_latency_us to zero to turn off APST.
     */

Entonces, APST es una característica que permite al controlador NVMe (dentro del SSD NVMe) cambiar entre estados de administración de energía de forma autónoma, siguiendo reglas configurables. El controlador NVMe especifica cuántos microsegundos necesita para entrar y salir de cada estado de ahorro de energía; el kernel usa esta información para configurar las reglas de transición de estado dentro del controlador NVMe.

  1. ¿Cuál y dónde está la falla específica que causa el problema?

Parece que este SSD Kingston NVMe en particular es demasiado optimista en sus estimaciones de tiempo de activación o no se despierta en absoluto (sin restablecer completamente el controlador) después de ingresar a un estado de ahorro de energía lo suficientemente profundo. Cuando se le da permiso para usar APST, aparentemente entra en algún estado de ahorro de energía y luego no regresa al estado operativo dentro del tiempo especificado, lo que hace que el kernel no esté satisfecho.

  1. ¿Qué cambia la solución alternativa para evitar la presentación del defecto?

Indica que el tiempo máximo permitido para despertar de los estados de administración de energía de APST es exactamente 0 microsegundos, lo que hace que la función APST se desactive.

  1. ¿Qué funcionalidad u otro efecto deseado se pierde debido a esta solución?

Si no se puede utilizar la función de administración de energía autónoma del controlador NVMe, el controlador solo podrá entrar en estados de ahorro de energía cuando lo solicite específicamente el kernel. Esto significa que los ahorros de energía probablemente no serán tan grandes como con APST en uso.

  1. Y especialmente, ¿qué se requiere arreglar, el kernel, el firmware de los medios de almacenamiento, el firmware del sistema (es decir, UEFI / BIOS), o algún otro componente, para que los usuarios experimenten una resolución adecuada?

La solución óptima sería que Kingston proporcione una actualización del firmware del disco NVMe que haga que la administración de energía APST funcione correctamente o, como mínimo, haga que la unidad no prometa algo que no puede ofrecer, es decir, no anuncie los modos APST con tiempos de transición demasiado optimistas. y / o no anunciar en absoluto ningún modo APST que hará que el controlador falle si se usa.

Si resulta que el problema puede evitarse, por ejemplo, programando APST para evitar por completo el estado de ahorro de energía más profundo, podría ser posible crear una solución alternativa más específica a nivel de kernel. Muchos controladores de dispositivos en el kernel de Linux tienen "tablas de peculiaridades" que especifican soluciones para modelos de hardware específicos. En el caso de NVMe, puede encontrar uno drivers/nvme/host/pci.cdentro de la fuente del kernel de Linux:

static const struct pci_device_id nvme_id_table[] = {
    { PCI_VDEVICE(INTEL, 0x0953),   /* Intel 750/P3500/P3600/P3700 */
        .driver_data = NVME_QUIRK_STRIPE_SIZE |
                NVME_QUIRK_DEALLOCATE_ZEROES, },
    { PCI_VDEVICE(INTEL, 0x0a53),   /* Intel P3520 */
        .driver_data = NVME_QUIRK_STRIPE_SIZE |
                NVME_QUIRK_DEALLOCATE_ZEROES, },
    { PCI_VDEVICE(INTEL, 0x0a54),   /* Intel P4500/P4600 */
        .driver_data = NVME_QUIRK_STRIPE_SIZE |
                NVME_QUIRK_DEALLOCATE_ZEROES, },
    { PCI_VDEVICE(INTEL, 0x0a55),   /* Dell Express Flash P4600 */
        .driver_data = NVME_QUIRK_STRIPE_SIZE |
                NVME_QUIRK_DEALLOCATE_ZEROES, },
    { PCI_VDEVICE(INTEL, 0xf1a5),   /* Intel 600P/P3100 */
        .driver_data = NVME_QUIRK_NO_DEEPEST_PS |
                NVME_QUIRK_MEDIUM_PRIO_SQ |
                NVME_QUIRK_NO_TEMP_THRESH_CHANGE |
                NVME_QUIRK_DISABLE_WRITE_ZEROES, },
[...]

Aquí, las diversas NVME_QUIRK_configuraciones activan varias piezas de código de solución dentro del controlador.

Tenga en cuenta que ya existe una configuración peculiar llamada NVME_QUIRK_NO_DEEPEST_PSque evita las transiciones de estado al estado de administración de energía más profundo. Si el problema APST de su Kingston NVMe resulta tener la misma solución que ya se implementó para Intel 600P / P3100 y ADATA SX8200PNP, entonces todo lo que necesitaría es escribir una nueva entrada de tabla de peculiaridades como esta (reemplazando las cosas dentro <angle brackets>con valores apropiados, puedes conseguirlos con lspci -nn):

    { PCI_DEVICE(<PCI vendor ID>, <PCI product ID of the SSD>),   /* <specify make/model of SSD here> */
        .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },

y recompilar el kernel con esta modificación.

Obviamente, se necesita alguien que realmente tenga este modelo SSD exacto para probar esto. Si está familiarizado con los conceptos básicos de la programación en C y cómo compilar núcleos personalizados, esta podría ser su oportunidad de llevar su nombre a la larga lista de contribuyentes del núcleo de Linux. Si está interesado, probablemente debería leer kernelnewbies.org para obtener más detalles.

La programación del kernel no siempre es muy compleja: hay muchas partes simples que solo necesitan una persona con el tipo de hardware adecuado y algunos conocimientos básicos de programación. He enviado algunos parches menores como este.

Si configurar los NVME_QUIRK_NO_DEEPEST_PSresultados no soluciona el problema, entonces podría ser necesario implementar una nueva peculiaridad. Eso podría ser más complicado y podría requerir algo de experimentación o, idealmente, información de Kingston para averiguar qué se debe hacer exactamente para evitar este problema, y ​​tal vez discutir con el encargado del controlador NVMe de Linux sobre la mejor manera de implementarlo.