mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
ceph: drop mdsc->mutex before decoding the MDS reply
handle_reply() held `mdsc->mutex` across parse_reply_info(), i.e. across the full decode of the reply message. For large replies (a big readdir allocates and parses many dir_entries), this can take a while and blocks ceph_mdsc_submit_request() calls meanwhile. The decode does not need `mdsc->mutex`: parse_reply_info() mostly fills the request's `r_reply_info`. Create replies may also add delegated inode numbers to the session xarray, but that xarray is protected by its own lock and is not serialized by `mdsc->mutex` today. By the time we reach parse_reply_info(), all `mdsc->mutex`-protected state has already been updated under the lock (the request has either been unregistered (safe reply) or added to the session's unsafe list (unsafe reply)) and the request is pinned by the reference taken in lookup_get_request(). Drop `mdsc->mutex` before calling parse_reply_info() so reply decoding no longer blocks request submission. This only widens the existing unlocked window that already covers the heavier ceph_fill_trace() / ceph_readdir_prepopulate() processing, so no new races are introduced. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Xiubo Li <xiubo.li@clyso.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
ee611a7509
commit
1319b97dfe
|
|
@ -4142,13 +4142,19 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
|
|||
list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that all mutex-protected state has been updated above
|
||||
* (the request has been unregistered or added to the
|
||||
* session's unsafe list), we can unlock it.
|
||||
*/
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
|
||||
doutc(cl, "tid %lld result %d\n", tid, result);
|
||||
if (test_bit(CEPHFS_FEATURE_REPLY_ENCODING, &session->s_features))
|
||||
err = parse_reply_info(session, msg, req, (u64)-1);
|
||||
else
|
||||
err = parse_reply_info(session, msg, req,
|
||||
session->s_con.peer_features);
|
||||
mutex_unlock(&mdsc->mutex);
|
||||
|
||||
/* Must find target inode outside of mutexes to avoid deadlocks */
|
||||
rinfo = &req->r_reply_info;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user