Page MenuHomeFreeBSD

geom/zero: Add support for unmapped I/O
ClosedPublic

Authored by 0mp on Oct 9 2025, 4:17 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Nov 24, 6:06 PM
Unknown Object (File)
Wed, Nov 12, 7:15 AM
Unknown Object (File)
Wed, Nov 12, 1:09 AM
Unknown Object (File)
Tue, Nov 11, 11:15 PM
Unknown Object (File)
Tue, Nov 11, 10:17 PM
Unknown Object (File)
Tue, Nov 11, 10:17 PM
Unknown Object (File)
Tue, Nov 11, 10:07 PM
Unknown Object (File)
Tue, Nov 11, 9:10 PM
Subscribers

Details

Summary

geom/zero: Add support for unmapped I/O

This patch adds support for unmapped I/O to gzero(4).

Let's consider the following script to illustrate the change in
gzero(4)'s behavior:

dd="dd if=/dev/gzero of=/dev/null bs=512 count=100000"
dtrace -q -c "$dd" -n '
    fbt::pmap_qenter:entry,
    fbt::uiomove_fromphys:entry,
    fbt::memset:entry
    /execname == "dd"/
    {
        @[probefunc] = count();
    }
'

Let's run that script 4 times:

==> 1: unmapped I/O not supported (fallback to mapped I/O), kern.geom.zero.clear=1
51200000 bytes transferred in 1.795809 secs (28510829 bytes/sec)
  pmap_qenter                                                  100000
  memset                                                       400011

==> 2: unmapped I/O not supported (fallback to mapped I/O), kern.geom.zero.clear=0
51200000 bytes transferred in 0.701079 secs (73030337 bytes/sec)
  memset                                                       300011

==> 3: unmapped I/O supported, kern.geom.zero.clear=1
51200000 bytes transferred in 0.771680 secs (66348750 bytes/sec)
  uiomove_fromphys                                             100000
  memset                                                       300011

==> 4: unmapped I/O supported, kern.geom.zero.clear=0
51200000 bytes transferred in 0.621303 secs (82407407 bytes/sec)
  memset                                                       300011

If kern.geom.zero.clear=0, then nothing really changes as no copying takes
place. Otherwise, we see by adding unmapped I/O support we avoid calls to
pmap_qenter(), which was called by GEOM to turn unmapped I/O requests into
mapped ones before passing them for processing to gzero(4).

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 68482
Build 65365: arc lint + arc unit

Event Timeline

0mp requested review of this revision.Oct 9 2025, 4:17 PM
0mp planned changes to this revision.Tue, Oct 28, 2:15 PM
0mp retitled this revision from geom/zero: Implement unmapped IO to geom/zero: Add support for unmapped I/O.Fri, Oct 31, 5:33 PM
0mp edited the summary of this revision. (Show Details)
0mp added reviewers: markj, bnovkov.
  • Fix implementation
  • Add comments
  • Add commit message
sys/geom/zero/g_zero.c
68–71

This is out of scope for now.

122–128

Bojan suggested that I actually check for !g_zero_clear here and break early, but we need to fall through to BIO_WRITE to set bio_completed and error, so breaking early is not an option.

sys/geom/zero/g_zero.c
103

We should break from the loop once resid == 0.

117

This comment is very pedantic. I understand that it's useful to write it out when doing this kind of thing for the first time, but I don't think it's necessary to spell it out. The comment before the loop is good, but the rest are overkill IMO.

121
154–155
0mp marked 3 inline comments as done.
  • Address feedback
0mp added inline comments.
sys/geom/zero/g_zero.c
103

I'll bring that check back.

I've removed it because I assume that if my math around length is correct, then the check is redundant under the assumption that the amount of memory given to us via bio_ma , bio_ma_n`, and bio_ma_offset is exactly equal to bp->bio_length.

117

Great! Thanks for the feedback. I'll remove the other comments. Bojan told me earlier that he'd like to see more comments explaining what is going on here since it's rare to see a for loop around uiomove_fromphys(). However, it seems like I went a bit too far with the comments, haha.

This revision is now accepted and ready to land.Wed, Nov 5, 10:50 AM

Thanks, Bojan! I'll wait a couple of days for Mark's feedback before committing.

  • Rebase onto recent main
  • Fix a copy/paste mistake where I applied CTLFLAG_MPSAFE to SYSCTL_INT of kern.geom.zero.clear instead of applying it to SYSCTL_PROC of kern.geom.zero.byte. The reason for this confusion was that:
    • SYSCTL_PROC(_kern_geom_zero, ..., clear becomes SYSCTL_INT(_kern_geom_zero, ..., clear in my change because the clear flag no longer needs to be handled by a function.
    • SYSCTL_INT(_kern_geom_zero, ..., byte, becomes SYSCTL_PROC(_kern_geom_zero, ..., byte in my change because the fill byte now needs to fill the g_zero_buffer when the fill byte is changed.

      Now I fixed that and CTLFLAG_MPSAFE is applied to SYSCTL_PROC.
This revision now requires review to proceed.Sun, Nov 9, 3:04 PM
markj added inline comments.
sys/geom/zero/g_zero.c
68

I believe it will be, but it's worth trying the experiment to verify it.

70

I don't think it's important to lock the update, given that this class is really only useful for benchmarking.

This revision is now accepted and ready to land.Tue, Nov 11, 2:38 PM
This revision was automatically updated to reflect the committed changes.