task_policy_get not available?

I'm attempting to use task_policy_get from a KEXT and am receiving the following error:
Code Block
sudo /usr/bin/kmutil load -p myKext
Error Domain=KMErrorDomain Code=31 "Error occurred while building a collection: 
  1: One or more binaries has an error which prevented linking. See other errors.
  2: Could not use 'myKext' because: Failed to bind '_task_policy_get' in 'myKext' (at offset 0x320 in __DATA_CONST, __got) as could not find a kext which exports this symbol"


I would expect that task_policy_get is a usable KPI?
  • 11.3 Beta (20E5210c)

  • Mac mini (M1, 2020)

What I am actually wanting to do is to temporarily increase the qos values for a process. Maybe there is a better way of doing this?

Replies

Oh.. forgot to mention:
Code Block
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.bsd</key>
<string>17.0.0</string>
<key>com.apple.kpi.iokit</key>
<string>17.0.0</string>
<key>com.apple.kpi.libkern</key>
<string>17.0.0</string>
<key>com.apple.kpi.mach</key>
<string>17.0.0</string>
<key>com.apple.kpi.unsupported</key>
<string>17.0.0</string>
</dict>

I would expect that task_policy_get is a usable KPI?

It is not.

What I am actually wanting to do is to temporarily increase the qos
values for a process. Maybe there is a better way of doing this?

Probably not, but it very much depends on what you’re doing in the kernel in the first place. Please elaborate.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Thanks Quinn.

Apologies if this is a dumb question, but for someone who hasn't done a lot of kernel work, how would one determine that task_policy_get is not a usable KPI? I must admit that since it appeared in the kernel headers and in documentation that I kind of thought it was legit.

So what I am doing is working on a FUSE based file system. So I have a process (the client) in userspace accessing a file through fuse (a kernel extension) which is calling back into userspace file system (the filesystem). Communication between the kext and the file system is done via read/write. For some reason on the M1 some of the client processes seem to be getting a high qos number and I think we may be getting some lock inversion with the filesystem which basically locks up the client/filesystem until the filesystem times out and everything errors. FWIW This system has been working fine for some time on Intel.

Basically I was just trying to run some experiments to see if I could boost the qos of the filesystem temporarily and was hoping to use task_policy_get/set to do it.

Yes I'm waving my hands wildly a bit here, but any other ideas would be appreciated.

Cheers,
Dave

Apologies if this is a dumb question, but for someone who hasn't done
a lot of kernel work, how would one determine that task_policy_get
is not a usable KPI?

That is not a dumb question, alas. Indeed, back when I used to support KEXT development (these days other folks in DTS have taken over that work) I wrote QA1575 Supported KPIs to clarify this situation.

Note Sadly one of the documentation migration steps since 2008 has dropped the FindKPI.py attachment. That’s hard to fix (because all Q&As are now in the Documentation Archive) so I’m including a copy here.



So what I am doing is working on a FUSE based file system.

I’m going to encourage you to look at doing this with a File Provider extension. FUSE relies on the VFS KPI and, while that hasn’t been formally deprecated, Apple has announced that we plan to replace and then deprecate, and then eventually drop support for, all KPIs. Indeed, we’ve already been through this process for NKEs.

For some reason on the M1 some of the client processes seem to be
getting a high qos number

A high QoS value is not at all unusual. Ideally you’d do your IPC using a mechanism that supports QoS donation, but this is hard when running inside the kernel.

I have two suggestions here:
  • Use a spin dump to see exactly where things are getting blocked.

  • Use the System Trace instrument to see which threads are being scheduled at which priority.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Thanks again Quinn..

Sigh.. apparently my google-fu is weak in that I couldn't find that tech note previously. The pointer (and python script) is greatly appreciated.


I’m going to encourage you to look at doing this with a File Provider extension. FUSE relies on the VFS KPI and, while that hasn’t been formally deprecated, Apple has announced that we plan to replace and then deprecate, and then eventually drop support for, all KPIs. Indeed, we’ve already been through this process for NKEs.

Yes... I have chatted with the File Provider team, and they are not supporting the scale of what we are doing. Unfortunately their current design is for a pretty specific set of use cases (last I checked).

A high QoS value is not at all unusual. Ideally you’d do your IPC using a mechanism that supports QoS donation, but this is hard when running inside the kernel.

Our current IPC mechanism to the file system is uio <-> read/write. Do you have any pointers towards a mechanism inside the kernel that support QoS donation?

Use a spin dump to see exactly where things are getting blocked.
Use the System Trace instrument to see which threads are being scheduled at which priority.

Yeah. Been playing with spin dump and have some ideas. That's where I found the high QoS numbers. I hadn't thought of trying system trace.

Cheers,
Dave

Do you have any pointers towards a mechanism inside the kernel that
support QoS donation?

AFAIK the only IPC mechanism that supports this is Mach IPC [1]. Switching to Mach IPC is not something I can recommend in general. Honestly, I’m not sure that you’ll be able to make it work at all using supported KPIs and, even if you can, it’s incredibly hard to use correctly.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] And things layered on top of that, like XPC, but those are only available in user space.
Hey Quinn.. the 11.3 b8 release notes had a blurb about

The Kernel Debug Kit (KDK) now runs on Macs with Apple Silicon. (73848762)

but it's disappeared from the RC release notes, and the 11.3 b8 release notes appear to have been removed.

I "assumed" that this meant that kernel extension variants were usable with Apple Silicon. The docs with the KDK still say it's intel only, but the KDK is shipping with development and kasan kernel variants. Is there anyway to get a development kernel variant working on a M1 mini?

I tried just for fun and ran into problems with:

Code Block
sudo kmutil install --volume-root /Users/dmaclach/livemount --update-all -v -a arm64e
Not rebuilding KC for arch: 'arm64e'
kmutil done

Is there anyway to get a development kernel variant working on a M1
mini?

I’m sorry but I’ve no idea (my day job rarely involves KEXTs, and that’s been the case for many years now).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"