ชี้แจงปัญหา nvme apst สำหรับ linux

Sep 30 2020

ผมมีประสบการณ์ปัญหาเกือบจะเหมือนกับหนึ่งที่อธิบายไว้ในaskubuntuชุมชน

เช่นเดียวกับที่ของผู้ใช้ที่โพสต์ปัญหานี้ระบบของฉันมีดิสก์คิงส์ตัน NVME nvme_core.default_ps_max_latency_us=0และเช่นเดียวกับผู้ใช้ที่ได้รับการแก้ไขปัญหาของฉันโดยการเพิ่มตัวเลือกเคอร์เนลต่อไปนี้ในเมนูด้วง:

ความละเอียดที่ระบุของผู้ใช้เริ่มต้นดังนี้:

ปัญหาเกิดจากคุณสมบัติของ SSD การเปลี่ยนสถานะพลังงานอัตโนมัติ (APST) ทำให้เกิดอาการค้าง หากต้องการบรรเทาจนกว่าพวกเขาจะคลายการแก้ไขให้รวมบรรทัดnvme_core.default_ps_max_latency_us=0ในGRUB_CMDLINE_LINUX_DEFAULTตัวเลือก

แม้ว่าจะเป็นประโยชน์ แต่ความคิดเห็นนี้ยังเปิดคำถามหลายข้อรวมถึงสิ่งต่อไปนี้:

  1. ข้อบกพร่องเฉพาะที่ทำให้เกิดปัญหาคืออะไรและที่ไหน?
  2. วิธีแก้ปัญหามีการเปลี่ยนแปลงอย่างไรเพื่อป้องกันการนำเสนอข้อบกพร่อง
  3. ฟังก์ชันใดหรือเอฟเฟกต์ที่ต้องการอื่น ๆ สูญหายเนื่องจากวิธีแก้ปัญหาดังกล่าว
  4. และโดยเฉพาะอย่างยิ่งสิ่งที่จำเป็นต้องได้รับการแก้ไขเคอร์เนลเฟิร์มแวร์สื่อบันทึกข้อมูลเฟิร์มแวร์ระบบ (เช่น UEFI / BIOS) หรือส่วนประกอบอื่น ๆ เพื่อให้ได้ความละเอียดที่เหมาะสม?

ความคิดเห็นใด ๆ ที่เป็นประโยชน์ในการพยายามแก้ไขความสับสนนี้ทั้งหมดหรือบางส่วน

คำตอบ

5 telcoM Sep 30 2020 at 13:26

ความคิดเห็นรหัสภายในdrivers/nvme/host/core.cในแหล่งที่มาของลินุกซ์เคอร์เนลดูเหมือนว่าจะอธิบายได้ดีที่สุด:

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.
     */

ดังนั้น APST จึงเป็นคุณสมบัติที่ช่วยให้คอนโทรลเลอร์ NVMe (ภายใน NVMe SSD) สามารถสลับระหว่างสถานะการจัดการพลังงานได้โดยอัตโนมัติตามกฎที่กำหนดได้ คอนโทรลเลอร์ NVMe ระบุจำนวนไมโครวินาทีในการเข้าและออกจากสถานะประหยัดพลังงานแต่ละสถานะ เคอร์เนลใช้ข้อมูลนี้เพื่อกำหนดค่ากฎการเปลี่ยนสถานะภายในคอนโทรลเลอร์ NVMe

  1. ข้อบกพร่องเฉพาะที่ทำให้เกิดปัญหาคืออะไรและที่ไหน?

ดูเหมือนว่า Kingston NVMe SSD รุ่นนี้เป็นวิธีที่มองโลกในแง่ดีเกินไปในการประมาณการเวลาปลุกหรือไม่สามารถปลุกได้เลย (โดยไม่ต้องรีเซ็ตคอนโทรลเลอร์ทั้งหมด) หลังจากเข้าสู่สถานะประหยัดพลังงานที่ลึกพอ เมื่อได้รับอนุญาตให้ใช้ APST ดูเหมือนว่าจะเข้าสู่สถานะประหยัดพลังงานบางอย่างและไม่สามารถกลับสู่สถานะการทำงานภายในเวลาที่กำหนดซึ่งทำให้เคอร์เนลไม่พึงพอใจ

  1. วิธีแก้ปัญหามีการเปลี่ยนแปลงอย่างไรเพื่อป้องกันการนำเสนอข้อบกพร่อง

จะบอกเวลาสูงสุดที่อนุญาตสำหรับการตื่นจากสถานะการจัดการพลังงาน APST คือ 0 ไมโครวินาทีซึ่งทำให้คุณสมบัติ APST ถูกปิดใช้งาน

  1. ฟังก์ชันใดหรือเอฟเฟกต์ที่ต้องการอื่น ๆ สูญหายเนื่องจากวิธีแก้ปัญหาดังกล่าว

หากไม่สามารถใช้คุณสมบัติการจัดการพลังงานอัตโนมัติของคอนโทรลเลอร์ NVMe ได้คอนโทรลเลอร์จะได้รับอนุญาตให้เข้าสู่สถานะประหยัดพลังงานเมื่อเคอร์เนลร้องขอโดยเฉพาะ ซึ่งหมายความว่าการประหยัดพลังงานมักจะไม่ดีเท่ากับการใช้งาน APST

  1. และโดยเฉพาะอย่างยิ่งสิ่งที่จำเป็นต้องได้รับการแก้ไขเคอร์เนลเฟิร์มแวร์สื่อบันทึกข้อมูลเฟิร์มแวร์ระบบ (เช่น UEFI / BIOS) หรือส่วนประกอบอื่น ๆ เพื่อให้ผู้ใช้ได้รับความละเอียดที่เหมาะสม

การแก้ไขที่ดีที่สุดคือ Kingston จัดเตรียมการอัปเดตเฟิร์มแวร์ดิสก์ NVMe ที่ทำให้การจัดการพลังงาน APST ทำงานได้อย่างถูกต้องหรืออย่างน้อยที่สุดก็ทำให้ไดรฟ์ไม่สัญญาว่าจะส่งมอบไม่ได้เช่นไม่ประกาศโหมด APST ที่มีเวลาเปลี่ยนผ่านในแง่ดีเกินไป และ / หรือไม่ประกาศในโหมด APST ใด ๆ ที่จะทำให้คอนโทรลเลอร์ล้มเหลวหากใช้

หากปรากฎว่าปัญหาสามารถหลีกเลี่ยงได้โดยการเขียนโปรแกรม APST เพื่อหลีกเลี่ยงสถานะการประหยัดพลังงานที่ลึกที่สุดอย่างสมบูรณ์อาจเป็นไปได้ที่จะสร้างวิธีแก้ปัญหาระดับเคอร์เนลที่เฉพาะเจาะจงมากขึ้น ไดรเวอร์อุปกรณ์จำนวนมากในเคอร์เนล Linux มี "ตารางมุมแหลม" เพื่อระบุวิธีแก้ปัญหาสำหรับฮาร์ดแวร์รุ่นเฉพาะ ในกรณีของ NVMe คุณสามารถค้นหาได้ในdrivers/nvme/host/pci.cซอร์สเคอร์เนลของ 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, },
[...]

ที่นี่การNVME_QUIRK_ตั้งค่าต่างๆจะทริกเกอร์โค้ดวิธีแก้ปัญหาต่างๆภายในไดรเวอร์

โปรดทราบว่ามีการตั้งชื่อNVME_QUIRK_NO_DEEPEST_PSแปลก ๆอยู่แล้วซึ่งป้องกันการเปลี่ยนสถานะเป็นสถานะการจัดการพลังงานที่ลึกที่สุด หากปัญหา APST ของ Kingston NVMe ของคุณพบว่ามีวิธีแก้ปัญหาเดียวกันกับที่ติดตั้งไว้แล้วสำหรับ Intel 600P / P3100 และ ADATA SX8200PNP สิ่งที่ต้องทำก็คือการเขียนรายการตารางมุมแหลมใหม่เช่นนี้ (แทนที่สิ่งต่างๆภายใน<angle brackets>ด้วยค่าที่เหมาะสม คุณสามารถรับได้ด้วย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, },

และคอมไพล์เคอร์เนลใหม่ด้วยการปรับเปลี่ยนนี้

เห็นได้ชัดว่าต้องมีคนที่มี SSD รุ่นนี้แน่นอนเพื่อทดสอบสิ่งนี้ หากคุณคุ้นเคยกับพื้นฐานการเขียนโปรแกรม C และวิธีรวบรวมเมล็ดที่กำหนดเองนี่อาจเป็นโอกาสของคุณที่จะได้รับชื่อของคุณในรายชื่อผู้สนับสนุนเคอร์เนล Linux หากคุณสนใจคุณควรอ่านkernelnewbies.orgเพื่อดูรายละเอียดเพิ่มเติม

การเขียนโปรแกรมเคอร์เนลไม่ได้ซับซ้อนลึกซึ้งเสมอไปมีส่วนง่ายๆมากมายที่ต้องการเพียงแค่คนที่มีฮาร์ดแวร์ที่เหมาะสมและมีความรู้พื้นฐานในการเขียนโปรแกรม ฉันได้ส่งแพตช์เล็ก ๆ น้อย ๆ เช่นนี้

หากการตั้งค่าNVME_QUIRK_NO_DEEPEST_PSปรากฎว่าไม่สามารถแก้ไขปัญหาได้อาจจำเป็นต้องใช้มุมแหลมใหม่ อาจมีความซับซ้อนมากขึ้นและอาจต้องมีการทดลองหรือข้อมูลที่เหมาะสมจาก Kingston เพื่อค้นหาสิ่งที่ต้องทำเพื่อหลีกเลี่ยงปัญหานี้และอาจปรึกษากับผู้ดูแลไดรเวอร์ Linux NVMe ถึงวิธีที่ดีที่สุดในการนำไปใช้