Linus Torvalds 本周三向内核合并了自己编写的一个补丁,该补丁通过修改几行代码,就在英特尔的某项性能基准测试中(名为"will it scale"的 per-thread-ops 基准测试)实现了 2.6% 的性能提升。
“64 位 copy_from_user () 中的 barrier_nospec () 函数运行速度很慢。
如果地址无效,可以使用 pointer masking 来强制用户指针全为 1。”
@@ -38,6 +38,7 @@
#else
#define can_do_masked_user_access() 0
#define masked_user_access_begin(src) NULL
+ #define mask_user_address(src) (src)
#endif
/*
@@ -159,19 +160,27 @@ _inline_copy_from_user(void *to, const void __user *from, unsigned long n)
{
unsigned long res = n;
might_fault();
- if (!should_fail_usercopy() && likely(access_ok(from, n))) {
+ if (should_fail_usercopy())
+ goto fail;
+ if (can_do_masked_user_access())
+ from = mask_user_address(from);
+ else {
+ if (!access_ok(from, n))
+ goto fail;
/*
* Ensure that bad access_ok() speculation will not
* lead to nasty side effects *after* the copy is
* finished:
*/
barrier_nospec();
- instrument_copy_from_user_before(to, from, n);
- res = raw_copy_from_user(to, from, n);
- instrument_copy_from_user_after(to, from, n, res);
}
- if (unlikely(res))
- memset(to + (n - res), 0, res);
+ instrument_copy_from_user_before(to, from, n);
+ res = raw_copy_from_user(to, from, n);
+ instrument_copy_from_user_after(to, from, n, res);
+ if (likely(!res))
+ return 0;
+fail:
+ memset(to + (n - res), 0, res);
return res;
}
extern __must_check unsigned long
该补丁已合并到 Linux 内核的 Git 代码仓库中,并将成为 11 月下旬发布的 Linux 6.12 稳定版的一部分。
详情查看发布公告:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0fc810ae3ae110f9e2fcccce80fc8c8d62f97907
END