Since we're accessing btree_trans objects owned by another thread, we
need to guard against using pointers to freed key cache entries: we need
our own srcu read lock, and we should skip a btree_trans if it didn't
hold the srcu lock (and thus it might have pointers to freed key cache
entries).
00693 Mem abort info:
00693 ESR = 0x0000000096000005
00693 EC = 0x25: DABT (current EL), IL = 32 bits
00693 SET = 0, FnV = 0
00693 EA = 0, S1PTW = 0
00693 FSC = 0x05: level 1 translation fault
00693 Data abort info:
00693 ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
00693 CM = 0, WnR = 0, TnD = 0, TagAccess = 0
00693 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
00693 user pgtable: 4k pages, 39-bit VAs, pgdp=
000000012e650000
00693 [
000000008fb96218] pgd=
0000000000000000, p4d=
0000000000000000, pud=
0000000000000000
00693 Internal error: Oops:
0000000096000005 [#1] SMP
00693 Modules linked in:
00693 CPU: 0 UID: 0 PID: 4307 Comm: cat Not tainted
6.16.0-rc2-ktest-g9e15af94fd86 #27578 NONE
00693 Hardware name: linux,dummy-virt (DT)
00693 pstate:
60001005 (nZCv daif -PAN -UAO -TCO -DIT +SSBS BTYPE=--)
00693 pc : six_lock_counts+0x20/0xe8
00693 lr : bch2_btree_bkey_cached_common_to_text+0x38/0x130
00693 sp :
ffffff80ca98bb60
00693 x29:
ffffff80ca98bb60 x28:
000000008fb96200 x27:
0000000000000007
00693 x26:
ffffff80eafd06b8 x25:
0000000000000000 x24:
ffffffc080d75a60
00693 x23:
ffffff80eafd0000 x22:
ffffffc080bdfcc0 x21:
ffffff80eafd0210
00693 x20:
ffffff80c192ff08 x19:
000000008fb96200 x18:
00000000ffffffff
00693 x17:
0000000000000000 x16:
0000000000000000 x15:
00000000ffffffff
00693 x14:
0000000000000000 x13:
ffffff80ceb5a29a x12:
20796220646c6568
00693 x11:
72205d3e303c5b20 x10:
0000000000000020 x9 :
ffffffc0805fb6b0
00693 x8 :
0000000000000020 x7 :
0000000000000000 x6 :
0000000000000020
00693 x5 :
ffffff80ceb5a29c x4 :
0000000000000001 x3 :
000000000000029c
00693 x2 :
0000000000000000 x1 :
ffffff80ef66c000 x0 :
000000008fb96200
00693 Call trace:
00693 six_lock_counts+0x20/0xe8 (P)
00693 bch2_btree_bkey_cached_common_to_text+0x38/0x130
00693 bch2_btree_trans_to_text+0x260/0x2a8
00693 bch2_btree_transactions_read+0xac/0x1e8
00693 full_proxy_read+0x74/0xd8
00693 vfs_read+0x90/0x300
00693 ksys_read+0x6c/0x108
00693 __arm64_sys_read+0x20/0x30
00693 invoke_syscall.constprop.0+0x54/0xe8
00693 do_el0_svc+0x44/0xc8
00693 el0_svc+0x18/0x58
00693 el0t_64_sync_handler+0x104/0x130
00693 el0t_64_sync+0x154/0x158
00693 Code:
910003fd f9423c22 f90017e2 d2800002 (
f9400c01)
00693 ---[ end trace
0000000000000000 ]---
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
i->ubuf = buf;
i->size = size;
i->ret = 0;
+
+ int srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
restart:
seqmutex_lock(&c->btree_trans_lock);
list_sort(&c->btree_trans_list, list_ptr_order_cmp);
if (!closure_get_not_zero(&trans->ref))
continue;
+ if (!trans->srcu_held) {
+ closure_put(&trans->ref);
+ continue;
+ }
+
u32 seq = seqmutex_unlock(&c->btree_trans_lock);
bch2_btree_trans_to_text(&i->buf, trans);
}
seqmutex_unlock(&c->btree_trans_lock);
unlocked:
+ srcu_read_unlock(&c->btree_trans_barrier, srcu_idx);
+
if (i->buf.allocation_failure)
ret = -ENOMEM;