• Jim Schutt's avatar
    ceph: ceph_pagelist_append might sleep while atomic · 39be95e9
    Jim Schutt authored
    Ceph's encode_caps_cb() worked hard to not call __page_cache_alloc()
    while holding a lock, but it's spoiled because ceph_pagelist_addpage()
    always calls kmap(), which might sleep.  Here's the result:
    
    [13439.295457] ceph: mds0 reconnect start
    [13439.300572] BUG: sleeping function called from invalid context at include/linux/highmem.h:58
    [13439.309243] in_atomic(): 1, irqs_disabled(): 0, pid: 12059, name: kworker/1:1
        . . .
    [13439.376225] Call Trace:
    [13439.378757]  [<ffffffff81076f4c>] __might_sleep+0xfc/0x110
    [13439.384353]  [<ffffffffa03f4ce0>] ceph_pagelist_append+0x120/0x1b0 [libceph]
    [13439.391491]  [<ffffffffa0448fe9>] ceph_encode_locks+0x89/0x190 [ceph]
    [13439.398035]  [<ffffffff814ee849>] ? _raw_spin_lock+0x49/0x50
    [13439.403775]  [<ffffffff811cadf5>] ? lock_flocks+0x15/0x20
    [13439.409277]  [<ffffffffa045e2af>] encode_caps_cb+0x41f/0x4a0 [ceph]
    [13439.415622]  [<ffffffff81196748>] ? igrab+0x28/0x70
    [13439.420610]  [<ffffffffa045e9f8>] ? iterate_session_caps+0xe8/0x250 [ceph]
    [13439.427584]  [<ffffffffa045ea25>] iterate_session_caps+0x115/0x250 [ceph]
    [13439.434499]  [<ffffffffa045de90>] ? set_request_path_attr+0x2d0/0x2d0 [ceph]
    [13439.441646]  [<ffffffffa0462888>] send_mds_reconnect+0x238/0x450 [ceph]
    [13439.448363]  [<ffffffffa0464542>] ? ceph_mdsmap_decode+0x5e2/0x770 [ceph]
    [13439.455250]  [<ffffffffa0462e42>] check_new_map+0x352/0x500 [ceph]
    [13439.461534]  [<ffffffffa04631ad>] ceph_mdsc_handle_map+0x1bd/0x260 [ceph]
    [13439.468432]  [<ffffffff814ebc7e>] ? mutex_unlock+0xe/0x10
    [13439.473934]  [<ffffffffa043c612>] extra_mon_dispatch+0x22/0x30 [ceph]
    [13439.480464]  [<ffffffffa03f6c2c>] dispatch+0xbc/0x110 [libceph]
    [13439.486492]  [<ffffffffa03eec3d>] process_message+0x1ad/0x1d0 [libceph]
    [13439.493190]  [<ffffffffa03f1498>] ? read_partial_message+0x3e8/0x520 [libceph]
        . . .
    [13439.587132] ceph: mds0 reconnect success
    [13490.720032] ceph: mds0 caps stale
    [13501.235257] ceph: mds0 recovery completed
    [13501.300419] ceph: mds0 caps renewed
    
    Fix it up by encoding locks into a buffer first, and when the number
    of encoded locks is stable, copy that into a ceph_pagelist.
    
    [elder@inktank.com: abbreviated the stack info a bit.]
    
    Cc: stable@vger.kernel.org # 3.4+
    Signed-off-by: default avatarJim Schutt <jaschut@sandia.gov>
    Reviewed-by: default avatarAlex Elder <elder@inktank.com>
    39be95e9
super.h 25.8 KB