Throttling and passive file io could get some illumination from
https://mjacobson.web/weblog/2022-02-throttling.html
A few of this will likely clarify why my 2013 iMac ran like treacle after replace to Catalina. It flies now I transfer as well from exterior USB Samsung T7 … and thanks/kudos to Bombich for CCC making a bootable Catalina copy so effectively. (This can be the final macOS that may very well be cloned like that.)
In case that evaporates listed below are a couple of details…
On Darwin, threads block inside throttle_lowpri_io after they’re being artificially delayed to decelerate their I/O operations, with the last word objective of optimizing the efficiency of higher-priority I/O. And certainly, in each of those instances (and within the different comparable issues I noticed), the chain of blockage finally results in a thread with less-than-highest I/O precedence.
..
To maintain observe of which I/Os ought to be throttled, the Darwin kernel maintains what I will name throttling domains (the supply calls them struct _throttle_io_info_t). In tough phrases, every throttling area is supposed to correspond one-to-one to a disk gadget.
When an I/O is issued by the spec_strategy routine, the kernel has to find out which throttling area the operation lives in, in order that the operation could both be throttled or trigger throttling of lower-priority operations. The throttling area is decided first by taking the vnode (i.e., file) the I/O is being finished to and strolling as much as its enclosing mount_t.
From there, the code appears on the mount’s mnt_devbsdunit property. The mnt_devbsdunit describes the “disk quantity” of the gadget the filesystem lives on. If a filesystem is mounted from /dev/disk3, then the mount’s mnt_devbsdunit is 3. If the backing disk is definitely a partition of a disk, then the quantity comes from the entire disk, not the partition; e.g., /dev/disk3s2 leads to 3.[2]
The mnt_devbsdunit—which might vary from 0 to 63[3]—determines which throttling area is in play.
..
Logical quantity teams and mnt_throttle_mask
Apple added a logical quantity supervisor, known as CoreStorage, to Mac OS X Lion. In distinction to conventional disk partitions, by which a contiguous vary of a disk gadget is used as a quantity, CoreStorage permits a looser relationship between volumes and backing storage. As an example, a quantity would possibly use storage from a number of completely different disk units—witness Fusion Drive for instance.
This complicates the mnt_devbsdunit state of affairs. Suppose a filesystem is mounted from quantity disk2. In line with the earlier guidelines, mnt_devbsdunit is 2. Nevertheless, disk2 may be a CoreStorage logical quantity, backed by the actual disk units disk0 and disk1.
Furthermore, CoreStorage may not be the one consumer of disk0 and disk1. Suppose additional a second, non-CoreStorage quantity on disk0, known as disk0s3. I/Os to disk2 and disk0s3 could deal with one another. However the mnt_devbsdunit of disk0s3 is 0, so the 2 mounts will probably be in several throttling domains.
To resolve this, enter a second mount_t area, mnt_throttle_mask. mnt_throttle_mask is a 64-bit bit array. A bit is ready solely once I/Os to the mount could contain the correspondingly numbered disk gadget. For our CoreStorage logical quantity disk2, since disk0 and disk1 are included, bits 0 and 1 are set. Bit 2 can be set for the logical quantity itself, so the general masks is 0x7.
In idea, you may think a system whereby a mount may reside in a number of throttling domains. Or maybe the throttling area choice may very well be pushed down in order that CoreStorage may assist make good selections about which to make use of for a specific I/O operation.
The carried out actuality is far more mundane. mnt_devbsdunit is ready to the index of the bottom bit set in mnt_throttle_mask. For disk2, since bit 0 is ready, mnt_devbsdunit is 0. So disk2 and disk0s3 dwell in the identical throttling area (although, notably, a theoretical disk1s3 wouldn’t).
This explains what’s taking place with /System/Volumes/Knowledge above. disk1s1 is a logical quantity introduced by a quantity supervisor[4], and its backing storage is on disk0. Tweaking the dtrace script exhibits that mnt_throttle_mask is 0x3:
..
Use IOPOL_PASSIVE
Along with assigning a precedence tier to its I/O operations, a course of could mark its I/O as passive; passive I/O could also be throttled however does not trigger throttling of different I/Os.
Recompiling dd to name setiopolicy_np(3) can be a problem. A neater manner is to make use of the taskpolicy(8) modifier utility that comes with latest variations of macOS. Although not documented within the manpage, the -d possibility can take the argument passive, like:
# taskpolicy -d passive dd if=…
Flip off throttling briefly
There are a bunch of sysctls out there to tune the habits of the I/O throttling system, together with one to close it off fully:
# 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