Page MenuHomeFreeBSD

powerpc: Optimize copyinstr() to avoid repeatedly mapping user strings
AcceptedPublic

Authored by jhibbits on Jun 4 2020, 6:20 PM.

Details

Reviewers
nwhitehorn
bdragon
Group Reviewers
PowerPC
Summary

Currently copyinstr() uses fubyte() to read each byte from userspace.
However, this means that for each byte, it calls pmap_map_user_ptr() to
map the string into memory. This is needlessly wasteful, since the
string will rarely ever cross a segment boundary. Instead, map a
segment at a time, and copy as much from that segment as possible at a
time.

Measured with the HPT pmap on powerpc64, this saves roughly 8% time on
buildkernel, and 5% on buildworld, in wallclock time.

Diff Detail

Lint
Lint Skipped
Unit
Unit Tests Skipped
Build Status
Buildable 31510
Build 29114: arc lint + arc unit

Event Timeline

jhibbits created this revision.
sys/powerpc/powerpc/copyinout.c
268

nit: gets set to NULL again in done.

291

should this get moved to beginning of done: just in case the *done = t line faults?

sys/powerpc/powerpc/copyinout.c
268

Good point, will remove before commit.

291

This matches the fu* functions already, and any fault in the target address is a programming error. The API contract requires that done be either NULL or a valid address. No such requirement is made on the user side.

tl;dr; doesn't really matter one way or the other.

Address bdragon's feedback.

Now that the dependencies of this have landed:

RB800 ok
X5000 ok
AIM32 ok
AIM64 HPT ok
AIM64 Radix ok
QEMU BOOKE64 untested (I don't have a root disk at the moment)

Is there a good way to test the segment-crossing bits?

This revision is now accepted and ready to land.Jun 11 2020, 3:21 AM