From c8076f0095ce85b10b287e6c5d92f8b5520018f2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 19 Jan 2010 11:41:45 -0800 Subject: [PATCH] Speed up DeviceKit device probing on really slow devices 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 Signed-off-by: David Zeuthen --- src/helpers/partutil.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/helpers/partutil.c b/src/helpers/partutil.c index f42587a..8923334 100644 --- a/src/helpers/partutil.c +++ b/src/helpers/partutil.c @@ -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) { -- 2.7.4