[hackers] [ubase] dd doesn't handle reading from high latency files well

From: Eric Pruitt <eric.pruitt_AT_gmail.com>
Date: Tue, 5 Sep 2017 21:31:04 -0700

While testing a shell script with sbase and ubase, I ran into a problem
where dd would chew up my CPU whenever it read from a slow file. I
noticed this when running "dd" in a pipeline with "/dev/random" while my
system was low on entropy. Here are the timing outputs from ubase's dd
compared to GNU coreutils running on the same system:

    # Suckless Unportable Base:
    $ time (ubase-box dd if=/dev/random bs=1 count=16 &>/dev/null)
    real 0m12.673s
    user 0m2.992s
    sys 0m9.656s

    # GNU Core Utilities:
    $ time (coreutils --coreutils-prog=dd if=/dev/random bs=1 count=16 &>/dev/null)
    real 0m16.987s
    user 0m0.000s
    sys 0m0.004s

The amount of sys time spent by ubase's dd is always a lot higher than
coreutil's even when the wall-clock time of the runs is comparable. I
haven't spent a lot of time looking into this yet, so I don't have a
patch prepared, but glancing at strace showed rapid invocations of
select(2) which often alternated between succeeding and ENOSYS:

    $ strace -o '!uniq -c >&2' ubase-box dd if=/dev/random bs=1 count=16 >/dev/null
    [...]
          1 splice(4, NULL, 1, NULL, 1, SPLICE_F_MORE) = 1
          1 select(4, [3], [1], NULL, NULL) = 2 (in [3], out [1])
          1 splice(3, NULL, 5, NULL, 1, SPLICE_F_MORE) = 1
          1 splice(4, NULL, 1, NULL, 1, SPLICE_F_MORE) = 1
       5074 select(4, [3], [1], NULL, NULL) = 1 (out [1])
     152992 select(4, [], [1], NULL, NULL) = -1 ENOSYS (Function
    not implemented)
          1 select(4, [3], [1], NULL, NULL) = 1 (out [1])
          1 select(4, [3], [1], NULL, NULL) = -1 ENOSYS (Function
    not implemented)
      34335 select(4, [], [1], NULL, NULL) = -1 ENOSYS (Function
    not implemented)
      34778 select(4, [3], [1], NULL, NULL) = 1 (out [1])
          1 select(4, [3], [1], NULL, NULL) = 2 (in [3], out [1])
          1 splice(3, NULL, 5, NULL, 1, SPLICE_F_MORE) = 1
          1 splice(4, NULL, 1, NULL, 1, SPLICE_F_MORE) = 1
          1 select(4, [3], [1], NULL, NULL) = 2 (in [3], out [1])
    [...]

Eric
Received on Wed Sep 06 2017 - 06:31:04 CEST

This archive was generated by hypermail 2.3.0 : Wed Sep 06 2017 - 06:36:20 CEST