Do fuswintr/suswintr make sense?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Do fuswintr/suswintr make sense?

Brooks Davis-2
The fuswintr() and suswintr() are intended to be safe in interrupt
context.  They are used in the profiling code and if they fail the code
falls back to triggering a trap with appropriate fields in struct
thread.  This is fine as such, but amd64, arm, i386, and powerpc have
implementations that always fail.  arm64, mips, riscv, and sparc64 all
add code to the trap handler to detect that this particular code has
faulted and return to the handler before doing and processing that might
result in a sleep.  This optimization came from 4.4BSD.

Does this optimization actually make sense in 2017, particularly
given that we're not taking advantage of it on x86 (and worse, our
implementations of return (-1) aren't inlined so they have cache
impacts)?

-- Brooks

signature.asc (465 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Do fuswintr/suswintr make sense?

Konstantin Belousov
On Mon, Apr 16, 2018 at 04:10:12PM +0000, Brooks Davis wrote:

> The fuswintr() and suswintr() are intended to be safe in interrupt
> context.  They are used in the profiling code and if they fail the code
> falls back to triggering a trap with appropriate fields in struct
> thread.  This is fine as such, but amd64, arm, i386, and powerpc have
> implementations that always fail.  arm64, mips, riscv, and sparc64 all
> add code to the trap handler to detect that this particular code has
> faulted and return to the handler before doing and processing that might
> result in a sleep.  This optimization came from 4.4BSD.
>
> Does this optimization actually make sense in 2017, particularly
> given that we're not taking advantage of it on x86 (and worse, our
> implementations of return (-1) aren't inlined so they have cache
> impacts)?

I do not see a reason to keep them around.

When I worked on copyin_nofault(), I specifically decided to not make it
working from the interrupt handlers contexts.  You need to be at the top
of the kernel to be able to use it.  So far there were no requests to
change that.

Since there is no other users of interrupt-safe usermode access, and since
the only user cope with such access not working, I do not see a point.
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"
Reply | Threaded
Open this post in threaded view
|

Re: Do fuswintr/suswintr make sense?

Bruce Evans-4
In reply to this post by Brooks Davis-2
On Mon, 16 Apr 2018, Brooks Davis wrote:

> The fuswintr() and suswintr() are intended to be safe in interrupt
> context.  They are used in the profiling code and if they fail the code
> falls back to triggering a trap with appropriate fields in struct
> thread.  This is fine as such, but amd64, arm, i386, and powerpc have
> implementations that always fail.  arm64, mips, riscv, and sparc64 all
> add code to the trap handler to detect that this particular code has
> faulted and return to the handler before doing and processing that might
> result in a sleep.  This optimization came from 4.4BSD.

Not having it for i386 also came from 4.4BSD.  NetBSD fixed it for i386
in 1994 or earlier (locore.s 1.41)

> Does this optimization actually make sense in 2017, particularly
> given that we're not taking advantage of it on x86 (and worse, our
> implementations of return (-1) aren't inlined so they have cache
> impacts)?

Profiling is even more in need of optimizations in 2017.  But not this
one, at least on i386.  [fs]uswintr() might be worth using if they
looked like [fs]uword16() and the latter and were efficient.
   (I don't see any reason why they can't be essentially the same.  If
   the user memory is not mapped then they will cause the same page
   fault, and they just have to fail instead of trying to handle the
   page fault.)
But [fs]uword16() are now extremely inefficient on i386.  The user and
kernel memory are in a different address spaces.  The functions are
implemented using a trampoline that has to map user memory, and this
is even slower than having a trampoline.  But not as slow as switching
the whole memory map on every crossing of the user-kernel boundary
including for profiling interrupts.

Since accessing 1 word at a time is too slow on i386 no matter how it is
done. the correct optimization looks more like a fancier ast() than
fsuswintr(): use a kernel buffer with a few hundred addresses instead of
only 1, and tell the application about the addresses in a single operation.
Do a full switch back to user context and run a trampoline to add 1 to
many addresses there, since the addresses are expected to be on many
different pages.  (The buffer now is { td_profil_addr; td_profil_ticks; }.
It can hold several ticks but only at 1 address.  Multiple ticks occur
mainly when the system can't keep up; then the address is clobbered but
the ticks count is charged to a new address.)

Bruce
_______________________________________________
[hidden email] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "[hidden email]"