Contribute
Register

NVMe Power management support - APST

Status
Not open for further replies.
Joined
Sep 10, 2012
Messages
16
Motherboard
Asus Maximus Hero VIII
CPU
i7-6700k
Graphics
RX 570
Mac
  1. iMac
  2. MacBook Pro
Mobile Phone
  1. iOS
Hello,

I've searched everywhere for a way to enable power management for NVMe drivers on Mojave and I need some assistance.

I have a Ideapad 720s-15IKB that comes with a pm961 M.2 NVMe SSD. I managed to set it up properly(sleep, touchpad, CPU PM, iGPU, battery, screen brightness hotkeys and even found a way to enable battery charging threshold via a fn-hotkey with a DSDT patch).

My main concern is that the M.2 does not have proper power saving enabled and this leads to poor battery performance and a hot device.
The SSD is always hot(60-65deg C) in macOS compared to LINUX (30-34deg C) even after a fresh wake from sleep, on idle.
Battery is of course impacted by this, 9wh on Mac vs 4.5wh on Linux/Windows at IDLE(same conditions)

I've disabled my Nvidia card (with DSDT), it should not impact battery life in any way.

Looking at the power-states in linux, one can see where the difference in heat and wattage comes from if the M.2 drive is "stuck" on PS-0.

Code:
sudo nvme id-ctrl /dev/nvme0      
NVME Identify Controller:
vid     : 0x144d
ssvid   : 0x144d
mn      : SAMSUNG MZVLW256HEHP-000L2        
fr      : 4L1QCXB7
rab     : 2
ieee    : 002538
cmic    : 0
mdts    : 0
cntlid  : 2
ver     : 10200
rtd3r   : 186a0
rtd3e   : 4c4b40
oaes    : 0
ctratt  : 0
oacs    : 0x17
acl     : 7
aerl    : 3
frmw    : 0x16
lpa     : 0x3
elpe    : 63
npss    : 4
avscc   : 0x1
apsta   : 0x1
wctemp  : 342
cctemp  : 345
mtfa    : 0
hmpre   : 0
hmmin   : 0
tnvmcap : 256060514304
unvmcap : 0
rpmbs   : 0
edstt   : 35
dsto    : 0
fwug    : 0
kas     : 0
hctma   : 0
mntmt   : 0
mxtmt   : 0
sanicap : 0
hmminds : 0
hmmaxd  : 0
sqes    : 0x66
cqes    : 0x44
maxcmd  : 0
nn      : 1
oncs    : 0x1f
fuses   : 0
fna     : 0
vwc     : 0x1
awun    : 255
awupf   : 0
nvscc   : 1
acwu    : 0
sgls    : 0
subnqn  :
ioccsz  : 0
iorcsz  : 0
icdoff  : 0
ctrattr : 0
msdbd   : 0
ps    0 : mp:7.60W operational enlat:0 exlat:0 rrt:0 rrl:0
          rwt:0 rwl:0 idle_power:- active_power:-
ps    1 : mp:6.00W operational enlat:0 exlat:0 rrt:1 rrl:1
          rwt:1 rwl:1 idle_power:- active_power:-
ps    2 : mp:5.10W operational enlat:0 exlat:0 rrt:2 rrl:2
          rwt:2 rwl:2 idle_power:- active_power:-
ps    3 : mp:0.0400W non-operational enlat:210 exlat:1500 rrt:3 rrl:3
          rwt:3 rwl:3 idle_power:- active_power:-
ps    4 : mp:0.0050W non-operational enlat:2200 exlat:6000 rrt:4 rrl:4
          rwt:4 rwl:4 idle_power:- active_power:-
 
Last edited:
Maybe someone can figure it out how to patch it..I have limited knowledge in macos kernel/drivers.

I found a value that is not found on my PM961(ioreg):
"Controller Characteristics" = {"Low Power Mode"=Yes,..

This value is set in IONVMeController::SetSystemRequirements(unsigned char). I'm digging around in the IONVMeFamily binary right now.

Something I found online (from a 2015 Apple 12 Inch Retina MacBook)
Code:
AppleNVMeController  <class AppleNVMeController, id 0x100000200, registered, matched, active, busy 0 (213 ms), retain 11>  
{
"IOClass" = "AppleNVMeController"
"IOPolledInterface" = "AppleNVMeControllerPolledAdapter is not serializable"
"IOMaximumSegmentByteCountRead" = 0x1000
"IOMaximumSegmentByteCountWrite" = 0x1000
"IOReportLegendPublic" = Yes
"IOProviderClass" = "IOPCIDevice"
"Physical Interconnect Location" = "Internal"
"IOPowerManagement" = {"ChildrenPowerState"=0x3,"MaxPowerState"=0x3,"CurrentPowerState"=0x3,"CapabilityFlags"=0x8000,"ChildProxyPowerState"=0x3,"DriverPowerState"=0x0}
"IOMaximumSegmentCountRead" = 0x40
"Model Number" = "APPLE SSD AP0512H"
"IOProbeScore" = 0x0
"IOMaximumSegmentCountWrite" = 0x40
"Serial Number" = "***"
"NVMe Revision Supported" = "1.01"
"IOPCIPauseCompatible" = Yes
"Physical Interconnect" = "PCI-Express"
"Chipset Name" = "SSD Controller"
"Controller Characteristics" = {"Low Power Mode"=Yes,"Preferred IO Size"=0x40000}
"IOMatchCategory" = "IODefaultMatchCategory"
"CFBundleIdentifier" = "com.apple.iokit.IONVMeFamily"
"Vendor Name" = "Apple"
"IOMinimumSegmentAlignmentByteCount" = 0x4
"Firmware Revision" = "5.841.01"
"IOPCITunnelCompatible" = Yes
"IOReportLegend" = ({"IOReportChannels"=((0x4e564d6520507772,0x400020002,"NVMe Power States")),"IOReportGroupName"="NVMe","IOReportChannelInfo"={"IOReportChannelUnit"=0x100007600000001}})
"IOUnitName" = "disk"
"IOPCIClassMatch" = "0x01800200&0xffffff00"
}

My Samsung:
Code:
IONVMeController  <class IONVMeController, id 0x100000342, registered, matched, active, busy 0 (501 ms), retain 10>
{
"IOClass" = "IONVMeController"
"IOPolledInterface" = "IONVMeControllerPolledAdapter is not serializable"
"IOMaximumSegmentByteCountRead" = 4096
"IOPlatformPanicAction" = 0
"IOReportLegendPublic" = Yes
"IOCommandPoolSize" = 256
"IOProviderClass" = "IOPCIDevice"
"Physical Interconnect Location" = "Internal"
"IOMaximumSegmentByteCountWrite" = 4096
"IOMaximumSegmentCountRead" = 256
"Model Number" = "SAMSUNG MZVLW256HEHP-000L2"
"IOProbeScore" = 0
"IOPowerManagement" = {"DevicePowerState"=2,"CurrentPowerState"=2,"CapabilityFlags"=32768,"MaxPowerState"=2,"DriverPowerState"=2}
"IOMaximumSegmentCountWrite" = 256
"IOMinimumSaturationByteCount" = 8388608
"NVMe Revision Supported" = "1.20"
"IOPCIPauseCompatible" = Yes
"Serial Number" = "***"
"Physical Interconnect" = "PCI-Express"
"Chipset Name" = "SSD Controller"
"Controller Characteristics" = {"Preferred IO Size"=1048576}
"IOMatchCategory" = "IODefaultMatchCategory"
"CFBundleIdentifier" = "com.apple.iokit.IONVMeFamily"
"Vendor Name" = "Apple"
"IOMinimumSegmentAlignmentByteCount" = 4
"Firmware Revision" = "4L1QCXB7"
"IOPCITunnelCompatible" = Yes
"IOReportLegend" = ({"IOReportChannels"=((5644784279684675442,12885032962,"NVMe Power States")),"IOReportGroupName"="NVMe","IOReportChannelInfo"={"IOReportChannelUnit"=72058100844068865}})
"IOUnitName" = "disk"
"IOPCIClassMatch" = "0x01080200&0xffffff00"
}

EDIT:
This patch enables it in ioreg.. not sure of the effects yet.. so far it only adds Low Power Mode = yes in IOREG. Sensor temperatures seem the same, battery the same :(
Code:
            <dict>
                <key>Comment</key>
                <string>try patch pm nvme</string>
                <key>Disabled</key>
                <false/>
                <key>Find</key>
                <data>
                AACAuzACAAAAdDi/AgAAAA==
                </data>
                <key>InfoPlistPatch</key>
                <false/>
                <key>Name</key>
                <string>com.apple.iokit.IONVMeFamily</string>
                <key>Replace</key>
                <data>
                AACAuzACAAAAdTi/AgAAAA==
                </data>
            </dict>
 
Last edited:
Hi,
i'm following your work because i've the same problem. I think that my M.2 NVMe driver is draining my battery faster than Windows. I noticed that in Windows my laptop in idle use 1,.1watt while on macOS in the same situation it is using 2,4w. I'm not able to help you solving the problem but please keep me posted about your results.
Thanks

Mattia
 
Hi, yeah nothing so far.. I want to try something this weekend, use a external HDD to boot MacOS and eject the NVMe drive(I can patch the DSDT to make it removable) and watch power draw. At this point I'm not sure APST is even implemented/supported in the Apple driver, most of what I found in the driver seems related to sleep power state.

Also I noticed my cpu doesn't reach some lower idle C states like in Windows, what I can only assume is caused by the NVMe being active all the time. CPU power draw is 1.72w idle on Mac(@800mhz) while on Windows 0,5w(@800mhz). Assuming the Intel reading is correct. On Windows, the CPU Package goes into C8 and lowers idle draw below 0.5w. While on MacOS it only goes to C3(according to power metrics).

Side note: disabling the discrete card in BIOS for my device yields worse power draw(in any OS). So I disabled it with a DSDT patch and left it enabled in bios.
 
Hi, yeah nothing so far.. I want to try something this weekend, use a external HDD to boot MacOS and eject the NVMe drive(I can patch the DSDT to make it removable) and watch power draw. At this point I'm not sure APST is even implemented/supported in the Apple driver, most of what I found in the driver seems related to sleep power state.

Also I noticed my cpu doesn't reach some lower idle C states like in Windows, what I can only assume is caused by the nvme being active all the time. CPU power draw is 1.72w idle on Mac(@800mhz) while on Windows 0,5w(@800mhz). Assuming the Intel reading is correct. On Windows, the CPU Package goes into C8 and lowers idle draw below 0.5w. While on MacOS it only goes to C3(according to powermetrics).

Side note: disabling the discrete card in BIOS for my device yields worse power draw(in any OS). So I disabled it with a DSDT patch and left it enabled in bios.

I wanted to try that too so I was having some time this evening and I tried. I disabled the PCI Express nvme controller in bios and installed Mojave on an external usb drive using the same EFI partition I'm using for the NVME (so the same config.plist, kexts etc). The result is that using the USB in intel power gadget now the watt consumption on idle is 0.90 while in the same situation using the NVME I got 2.10.
Cpu temperature are lower (around 4-5° compared to the nvme controller version).
So it's the nvme controller (right now there is no nvme reference in ioregistryexplorer) causing the battery drain but I don't know how to improve the situation ... Maybe I will switch to a normal SSD disk to avoid the problem.

Mattia
 
@tmbt You confirmed my theory. If you can, you should switch to a regular SSD, I would also do that but for my device I can only use NVME :(
Hi, i just replaced my NVME m.2 drive with a normal SSD m.2 drive and now i'm on 0.9w on idle so this confirmed the theory .. there is not PM in the Apple NVME kext and this cause the battery drain ... I'm not noticing a daily use slow down so i will keep the SSD at least until someone will find a fix for this situation.

Mattia
 
@icex if any of you guys have a real MacBook/air/pro with OEM Apple nvme, it would be nice if you guys can upload ACPI Tables and ioreg so I can analyze/reverse engineer on how do they implement power management on their nvme drives and attempt to implement on third party nvme drives for macOS.
 
Status
Not open for further replies.
Back
Top