Speed up DeviceKit device probing on really slow devices
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 19 Jan 2010 19:41:45 +0000 (11:41 -0800)
committerDavid Zeuthen <davidz@redhat.com>
Tue, 19 Jan 2010 21:49:39 +0000 (16:49 -0500)
My wife has a embroidery machine that acts as a USB memory stick when
plugged into a computer through its USB port. It has a truly stunning read
speed of 15kB/s (yes, really), and it turns out that both udev and
DeviceKit react very badly to devices that are slow, because they read too
much data off it.

udev - through blkid - ended up reading closer to two hundred kB off the
device in order to check all possible filesystems. DeviceKit is much
better, and only does a single 512-byte read to figure out the DOS
partitioning sceme.

However, unluckily, both udev and DeviceKit end up triggering read-ahead
on the device. The kernel decides that if you start reading from the
beginning (and the partition info is at the start), you're likely going to
continue reading. Which is a reasonable assumption in general, but isn't
true for odd things like "read just the partition table".

So even though DeviceKit only does a 512-byte read, read-ahead will turn
it into a 16kB device access, and you get timing behavior like this:

time /lib/udev/devkit-disks-part-id /dev/sdc

real 0m1.043s
user 0m0.004s
sys 0m0.008s

which basically delays figuring out what to do with the newly plugged in
hardware by a second (blkid took 13+ seconds for both the full device and
the partition it contained, so DeviceKit is positively wonderful in
comparison ;).

Making part-id just ask for no read-ahead (by saying that the access
patterns are random) ends up helping performance noticeably. Recompiling
part-id with this patch results in:

time ./src/probers/udisks-part-id /dev/sdc

real 0m0.276s
user 0m0.005s
sys 0m0.007s

because the kernel will now only read 4kB off the disk (4kB is the caching
granularity, so you'll never see an actual 512-byte read without doing
special odd things).

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: David Zeuthen <davidz@redhat.com>
src/helpers/partutil.c

index f42587a..8923334 100644 (file)
@@ -972,6 +972,11 @@ part_table_load_from_disk (int fd)
       goto out;
     }
 
+#ifdef POSIX_FADV_RANDOM
+  /* No read-ahead, please */
+  posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
+#endif
+
   p = part_table_parse_msdos (fd, 0, size, block_size, &found_gpt);
   if (p != NULL)
     {