Re: [PATCH v3 1/8] powerpc/uaccess: Add unsafe_copy_from_user
flat view
From: Christopher M. Riedl <hidden>
Date: 2021-01-20 05:44:39
On Tue Jan 19, 2021 at 11:27 AM CST, Christophe Leroy wrote:
Le 19/01/2021 à 18:02, Christopher M. Riedl a écrit :quoted
On Tue Jan 19, 2021 at 6:33 AM CST, Christophe Leroy wrote:quoted
Le 19/01/2021 à 03:11, Michael Ellerman a écrit :quoted
"Christopher M. Riedl" [off-list ref] writes:quoted
On Mon Jan 11, 2021 at 7:22 AM CST, Christophe Leroy wrote:quoted
Le 09/01/2021 à 04:25, Christopher M. Riedl a écrit :quoted
Implement raw_copy_from_user_allowed() which assumes that userspace read access is open. Use this new function to implement raw_copy_from_user(). Finally, wrap the new function to follow the usual "unsafe_" convention of taking a label argument.I think there is no point implementing raw_copy_from_user_allowed(), see https://github.com/linuxppc/linux/commit/4b842e4e25b1 and https://patchwork.ozlabs.org/project/linuxppc-dev/patch/8c74fc9ce8131cabb10b3e95dc0e430f396ee83e.1610369143.git.christophe.leroy@csgroup.eu/ You should simply do: #define unsafe_copy_from_user(d, s, l, e) \ unsafe_op_wrap(__copy_tofrom_user((__force void __user *)d, s, l), e)I gave this a try and the signal ops decreased by ~8K. Now, to be honest, I am not sure what an "acceptable" benchmark number here actually is - so maybe this is ok? Same loss with both radix and hash: | | hash | radix | | ------------------------------------ | ------ | ------ | | linuxppc/next | 118693 | 133296 | | linuxppc/next w/o KUAP+KUEP | 228911 | 228654 | | unsafe-signal64 | 200480 | 234067 | | unsafe-signal64 (__copy_tofrom_user) | 192467 | 225119 | To put this into perspective, prior to KUAP and uaccess flush, signal performance in this benchmark was ~290K on hash.If I'm doing the math right 8K is ~4% of the best number. It seems like 4% is worth a few lines of code to handle these constant sizes. It's not like we have performance to throw away. Or, we should chase down where the call sites are that are doing small constant copies with copy_to/from_user() and change them to use get/put_user().Christopher, when you say you gave it a try, is I my series or only the following ? #define unsafe_copy_from_user(d, s, l, e) \ unsafe_op_wrap(__copy_tofrom_user((__force void __user *)d, s, l), e)I only used the above to replace this patch in my series (so none of my changes implementing raw_copy_from_user_allowed() are included).Then I see no reason why the performance would be different, because you only call unsafe_copy_from_user() with non trivial lengthes.
Ok I made a mistake - this actually included the other improvements from your feedback on this series; specifically moving the unsafe_get_user() call to read the msr regs value into the #ifdef. My first pass resulted in another __get_user() call which explains some of the perf loss. With that mistake fixed, the benchmark performance is still only ~197k on hash (consistent). I agree that there are no places where unsafe_copy_from_user() is called with trivial lengths so the only conclusion I can draw is that the changes in this patch marginally speed-up the other __copy_from_user() calls. I started comparing the disassembly but nothing immediately obvious stands out to me. In fact, I observe the speed-up even if I keep this patch _and_ apply this change: #define unsafe_copy_from_user(d, s, l, e) \ unsafe_op_wrap(__copy_tofrom_user((__force void __user *)d, s, l), e) Related to that, I think sigset_t is always 8B on ppc64 so these will probably need a wrapper if we pick-up your series to get rid of trivial size optimizations: __copy_from_user(&set, &uc->uc_sigmask, sizeof(set)) I can bring performance up to ~200K on hash again by replacing the two __copy_from_user(&set, ...) with direct calls to __get_user_size() (it's kind of hacky I think). See the last commit in this tree: https://git.sr.ht/~cmr/linux/log/unsafe-signal64-v4 All my comments apply to performance on radix as well.
quoted
quoted
Because I see no use of unsafe_copy_from_user() that would explain that. Christophe