summaryrefslogtreecommitdiffstats
path: root/results/classifier/zero-shot/118/graphic/1343827
blob: 067ffafa74673470dadcde0dc6bc9e675cc0bbc2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
graphic: 0.838
device: 0.699
kernel: 0.623
socket: 0.622
ppc: 0.507
performance: 0.481
register: 0.467
boot: 0.409
semantic: 0.405
PID: 0.390
network: 0.385
architecture: 0.311
arm: 0.305
user-level: 0.296
vnc: 0.262
risc-v: 0.257
VMM: 0.223
files: 0.213
debug: 0.194
mistranslation: 0.186
permissions: 0.177
TCG: 0.159
assembly: 0.136
x86: 0.121
i386: 0.118
peripherals: 0.112
virtual: 0.099
hypervisor: 0.085
KVM: 0.064

block.c: multiwrite_merge() truncates overlapping requests

If the list of requests passed to multiwrite_merge() contains two requests where the first is for a range of sectors that is a strict subset of the second's, the second request is truncated to end where the first starts, so the second half of the second request is lost.

This is easy to reproduce by running fio against a virtio-blk device running on qemu 2.1.0-rc1 with the below fio script. At least with fio 2.0.13, the randwrite pass will issue overlapping bios to the block driver, which the kernel is happy to pass along to qemu:

[global]
randrepeat=0
ioengine=libaio
iodepth=64
direct=1
size=1M
numjobs=1
verify_fatal=1
verify_dump=1

filename=$dev

[seqwrite]
blocksize_range=4k-1M
rw=write
verify=crc32c-intel

[randwrite]
stonewall
blocksize_range=4k-1M
rw=randwrite
verify=meta

Here is a naive fix for the problem that simply avoids merging problematic requests. I guess a better solution would be to redo qemu_iovec_concat() to do the right thing.

diff -ur old/qemu-2.1.0-rc2/block.c qemu-2.1.0-rc2/block.c
--- old/qemu-2.1.0-rc2/block.c  2014-07-15 14:49:14.000000000 -0700
+++ qemu-2.1.0-rc2/block.c      2014-07-17 23:03:14.224169741 -0700
@@ -4460,7 +4460,9 @@
         int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
 
         // Handle exactly sequential writes and overlapping writes.
-        if (reqs[i].sector <= oldreq_last) {
+        // If this request ends before the previous one, don't merge.
+        if (reqs[i].sector <= oldreq_last &&
+            reqs[i].sector + reqs[i].nb_sectors >= oldreq_last) {
             merge = 1;
         }

Thanks for reporting this bug.  I'm writing a test case and fix, will CC you on the patches.

Please keep in mind that no ordering is guaranteed between requests that are in-flight at the same time.  Therefore it is unusual to submit overlapping requests and could indicate a bug in the application.

Triaging old bug tickets... has Stefan's fix be included? Could we close this ticket nowadays?

[Expired for QEMU because there has been no activity for 60 days.]