mac: use a sleepable rmlock instead of an sx lock

If any non-static modules are loaded (and mac_ntpd tends to be), the lock is
taken all the time al over the kernel. On platforms like arm64 this results in
an avoidable significant performance degradation. Since write-locking is almost
never needed, use a primitive optimized towards read-locking.

Sample result of building the kernel on tmpfs 11 times:
stock           11142.80s user 6704.44s system 4924% cpu 6:02.42 total
patched         11118.95s user 2374.94s system 4547% cpu 4:56.71 total
This commit is contained in:
Mateusz Guzik 2019-12-27 11:23:32 +00:00
parent 1f162fef76
commit deb2e577a2

View file

@ -176,6 +176,7 @@ MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
#ifndef MAC_STATIC
static struct rmlock mac_policy_rm; /* Non-sleeping entry points. */
static struct sx mac_policy_sx; /* Sleeping entry points. */
static struct rmslock mac_policy_rms;
#endif
struct mac_policy_list_head mac_policy_list;
@ -209,7 +210,7 @@ mac_policy_slock_sleep(void)
if (!mac_late)
return;
sx_slock(&mac_policy_sx);
rms_rlock(&mac_policy_rms);
#endif
}
@ -233,7 +234,7 @@ mac_policy_sunlock_sleep(void)
if (!mac_late)
return;
sx_sunlock(&mac_policy_sx);
rms_runlock(&mac_policy_rms);
#endif
}
@ -249,6 +250,7 @@ mac_policy_xlock(void)
return;
sx_xlock(&mac_policy_sx);
rms_wlock(&mac_policy_rms);
rm_wlock(&mac_policy_rm);
#endif
}
@ -262,6 +264,7 @@ mac_policy_xunlock(void)
return;
rm_wunlock(&mac_policy_rm);
rms_wunlock(&mac_policy_rms);
sx_xunlock(&mac_policy_sx);
#endif
}
@ -294,6 +297,7 @@ mac_init(void)
rm_init_flags(&mac_policy_rm, "mac_policy_rm", RM_NOWITNESS |
RM_RECURSE);
sx_init_flags(&mac_policy_sx, "mac_policy_sx", SX_NOWITNESS);
rms_init(&mac_policy_rms, "mac_policy_rms");
#endif
}