Lei Xue
7bb0c53384
cachefiles: Fix race between read_waiter and read_copier involving op->to_do
...
There is a potential race in fscache operation enqueuing for reading and
copying multiple pages from cachefiles to netfs. The problem can be seen
easily on a heavy loaded system (for example many processes reading files
continually on an NFS share covered by fscache triggered this problem within
a few minutes).
The race is due to cachefiles_read_waiter() adding the op to the monitor
to_do list and then then drop the object->work_lock spinlock before
completing fscache_enqueue_operation(). Once the lock is dropped,
cachefiles_read_copier() grabs the op, completes processing it, and
makes it through fscache_retrieval_complete() which sets the op->state to
the final state of FSCACHE_OP_ST_COMPLETE(4). When cachefiles_read_waiter()
finally gets through the remainder of fscache_enqueue_operation()
it sees the invalid state, and hits the ASSERTCMP and the following
oops is seen:
[ 2259.612361] FS-Cache:
[ 2259.614785] FS-Cache: Assertion failed
[ 2259.618639] FS-Cache: 4 == 5 is false
[ 2259.622456] ------------[ cut here ]------------
[ 2259.627190] kernel BUG at fs/fscache/operation.c:70!
...
[ 2259.791675] RIP: 0010:[<ffffffffc061b4cf>] [<ffffffffc061b4cf>] fscache_enqueue_operation+0xff/0x170 [fscache]
[ 2259.802059] RSP: 0000:ffffa0263d543be0 EFLAGS: 00010046
[ 2259.807521] RAX: 0000000000000019 RBX: ffffa01a4d390480 RCX: 0000000000000006
[ 2259.814847] RDX: 0000000000000000 RSI: 0000000000000046 RDI: ffffa0263d553890
[ 2259.822176] RBP: ffffa0263d543be8 R08: 0000000000000000 R09: ffffa0263c2d8708
[ 2259.829502] R10: 0000000000001e7f R11: 0000000000000000 R12: ffffa01a4d390480
[ 2259.844483] R13: ffff9fa9546c5920 R14: ffffa0263d543c80 R15: ffffa0293ff9bf10
[ 2259.859554] FS: 00007f4b6efbd700(0000) GS:ffffa0263d540000(0000) knlGS:0000000000000000
[ 2259.875571] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2259.889117] CR2: 00007f49e1624ff0 CR3: 0000012b38b38000 CR4: 00000000007607e0
[ 2259.904015] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 2259.918764] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 2259.933449] PKRU: 55555554
[ 2259.943654] Call Trace:
[ 2259.953592] <IRQ>
[ 2259.955577] [<ffffffffc03a7c12>] cachefiles_read_waiter+0x92/0xf0 [cachefiles]
[ 2259.978039] [<ffffffffa34d3942>] __wake_up_common+0x82/0x120
[ 2259.991392] [<ffffffffa34d3a63>] __wake_up_common_lock+0x83/0xc0
[ 2260.004930] [<ffffffffa34d3510>] ? task_rq_unlock+0x20/0x20
[ 2260.017863] [<ffffffffa34d3ab3>] __wake_up+0x13/0x20
[ 2260.030230] [<ffffffffa34c72a0>] __wake_up_bit+0x50/0x70
[ 2260.042535] [<ffffffffa35bdcdb>] unlock_page+0x2b/0x30
[ 2260.054495] [<ffffffffa35bdd09>] page_endio+0x29/0x90
[ 2260.066184] [<ffffffffa368fc81>] mpage_end_io+0x51/0x80
CPU1
cachefiles_read_waiter()
20 static int cachefiles_read_waiter(wait_queue_entry_t *wait, unsigned mode,
21 int sync, void *_key)
22 {
...
61 spin_lock(&object->work_lock);
62 list_add_tail(&monitor->op_link, &op->to_do);
63 spin_unlock(&object->work_lock);
<begin race window>
64
65 fscache_enqueue_retrieval(op);
182 static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
183 {
184 fscache_enqueue_operation(&op->op);
185 }
58 void fscache_enqueue_operation(struct fscache_operation *op)
59 {
60 struct fscache_cookie *cookie = op->object->cookie;
61
62 _enter("{OBJ%x OP%x,%u}",
63 op->object->debug_id, op->debug_id, atomic_read(&op->usage));
64
65 ASSERT(list_empty(&op->pend_link));
66 ASSERT(op->processor != NULL);
67 ASSERT(fscache_object_is_available(op->object));
68 ASSERTCMP(atomic_read(&op->usage), >, 0);
<end race window>
CPU2
cachefiles_read_copier()
168 while (!list_empty(&op->to_do)) {
...
202 fscache_end_io(op, monitor->netfs_page, error);
203 put_page(monitor->netfs_page);
204 fscache_retrieval_complete(op, 1);
CPU1
58 void fscache_enqueue_operation(struct fscache_operation *op)
59 {
...
69 ASSERTIFCMP(op->state != FSCACHE_OP_ST_IN_PROGRESS,
70 op->state, ==, FSCACHE_OP_ST_CANCELLED);
Signed-off-by: Lei Xue <carmark.dlut@gmail.com>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
2020-05-08 23:01:10 +01:00
..
2020-03-27 09:29:56 +00:00
2020-01-25 11:31:59 -05:00
2019-11-18 14:26:43 +01:00
2020-04-24 16:33:32 +01:00
2020-03-13 21:08:17 -04:00
2019-08-30 07:27:17 -07:00
2019-08-30 07:27:17 -07:00
2020-04-17 15:20:08 +02:00
2020-05-08 23:01:10 +01:00
2020-04-13 19:33:47 +02:00
2020-04-22 20:29:11 -05:00
2019-09-19 09:42:37 -07:00
2019-12-08 19:10:50 -05:00
2020-02-07 14:48:41 -05:00
2020-03-31 12:58:36 -07:00
2020-04-17 17:08:50 +02:00
2019-09-03 09:30:56 -04:00
2019-12-18 18:07:31 +01:00
2020-02-17 21:08:37 -08:00
2020-02-23 21:59:42 +01:00
2019-08-30 07:27:17 -07:00
2020-03-03 23:40:52 +08:00
2020-04-22 20:14:06 +09:00
2019-11-11 09:21:59 -05:00
2020-03-23 13:01:37 +01:00
2020-04-15 23:58:49 -04:00
2020-04-07 13:48:26 -07:00
2020-03-06 07:06:09 -06:00
2019-08-30 07:27:17 -07:00
2020-02-04 03:05:26 +00:00
2020-02-13 09:16:07 +01:00
2020-03-31 14:16:03 -07:00
2019-12-18 18:07:32 +01:00
2020-04-10 15:36:20 -07:00
2020-03-29 23:23:00 +02:00
2019-10-23 17:23:46 +02:00
2020-04-02 09:35:32 -07:00
2020-04-08 21:37:18 -07:00
2019-09-19 09:42:37 -07:00
2020-03-05 20:25:05 -05:00
2020-02-07 14:48:37 -05:00
2020-02-05 05:28:20 +00:00
2020-03-16 15:53:47 -04:00
2020-02-04 03:05:26 +00:00
2019-08-30 07:27:17 -07:00
2020-05-08 22:20:24 +01:00
2019-05-21 10:50:46 +02:00
2020-04-17 12:40:31 -04:00
2019-10-23 17:23:46 +02:00
2019-05-21 10:50:46 +02:00
2020-03-30 12:40:53 +02:00
2020-03-28 13:21:08 +01:00
2020-04-10 15:36:21 -07:00
2019-08-30 08:11:25 -07:00
2019-07-19 10:42:02 -07:00
2020-04-08 09:39:11 -04:00
2020-03-27 16:51:02 +01:00
2020-04-25 12:25:32 -07:00
2020-03-09 14:45:40 -07:00
2019-08-30 07:27:17 -07:00
2019-08-30 07:27:17 -07:00
2020-01-30 15:37:41 -08:00
2020-02-07 14:48:37 -05:00
2020-04-07 10:43:44 -07:00
2019-09-19 10:06:57 -07:00
2019-09-19 10:06:57 -07:00
2020-04-05 11:34:35 -07:00
2019-08-30 07:27:18 -07:00
2019-12-10 22:29:58 -05:00
2020-04-07 12:40:56 -07:00
2020-04-10 15:36:22 -07:00
2019-09-19 09:42:37 -07:00
2020-03-25 11:50:48 +01:00
2020-02-08 17:34:58 -05:00
2020-01-14 13:28:28 -08:00
2020-04-16 09:07:42 -07:00
2020-03-25 11:28:26 +09:00
2020-02-03 17:27:47 -07:00
2019-07-19 10:42:02 -07:00
2019-12-08 19:10:50 -05:00
2019-05-21 10:50:45 +02:00
2019-11-15 14:38:29 +01:00
2020-04-07 10:43:44 -07:00
2019-05-21 10:50:45 +02:00
2019-07-16 19:23:22 -07:00
2019-07-19 10:42:02 -07:00
2019-05-21 10:50:45 +02:00
2020-04-21 09:51:10 -06:00
2020-04-24 12:44:19 -07:00
2020-01-06 20:10:26 +01:00
2019-11-15 14:38:29 +01:00
2019-06-19 17:09:55 +02:00
2020-04-21 11:11:56 -07:00
2019-08-30 19:31:09 -04:00
2020-04-02 19:15:03 -07:00
2019-12-08 11:08:28 -08:00
2019-05-21 10:50:45 +02:00
2020-01-04 13:55:09 -08:00
2019-12-18 00:03:01 -05:00
2020-02-03 17:27:38 -07:00
2020-04-07 10:43:44 -07:00
2020-04-02 11:22:17 -07:00
2020-03-03 10:55:06 -05:00
2019-08-07 21:51:47 -04:00
2019-08-19 11:00:39 -04:00
2020-03-20 08:47:27 -06:00
2020-04-10 15:36:22 -07:00
2020-02-07 14:48:35 -05:00
2020-04-02 09:35:26 -07:00
2019-07-16 22:52:37 -04:00
2019-05-21 10:50:45 +02:00
2020-01-31 10:30:36 -08:00
2020-02-07 14:48:35 -05:00
2020-03-06 11:06:15 +01:00
2020-04-02 12:30:08 -07:00
2020-04-19 13:55:27 -06:00
2020-04-03 11:35:57 -06:00
2020-04-03 11:35:57 -06:00
2020-02-08 13:44:41 -08:00
2020-03-05 21:00:40 -05:00
2019-06-24 09:16:47 +10:00
2020-03-24 13:27:16 +01:00
2020-03-18 13:03:38 -07:00
2020-03-05 21:00:40 -05:00
2019-05-21 10:50:45 +02:00
2019-07-16 22:52:37 -04:00
2020-01-09 08:16:12 -07:00
2020-04-06 10:38:59 -04:00
2020-03-13 21:08:17 -04:00
2019-05-30 11:26:32 -07:00
2020-03-12 17:33:11 -07:00
2020-04-02 12:30:08 -07:00
2020-04-02 09:35:28 -07:00
2019-06-17 17:36:09 -04:00
2019-05-30 11:29:53 -07:00
2020-01-04 13:55:09 -08:00
2019-09-06 21:28:49 +02:00
2020-04-03 00:09:59 +11:00
2020-01-23 10:15:28 -08:00
2019-11-15 14:38:29 +01:00
2020-04-10 15:36:22 -07:00
2020-03-02 14:04:31 -07:00
2019-12-08 14:37:36 +01:00
2020-01-20 17:03:54 -07:00
2019-10-03 14:21:35 -07:00
2019-12-18 00:03:01 -05:00
2019-05-14 09:47:50 -07:00
2020-01-14 12:20:53 +01:00
2020-04-07 10:43:40 -07:00
2019-12-08 19:10:50 -05:00
2020-03-16 15:53:47 -04:00