mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Revert "nvme-tcp: lockdep: use dynamic lockdep keys per socket instance"
This reverts commit19bdb70c77. The commit19bdb70c77("nvme-tcp: lockdep: use dynamic lockdep keys per socket instance") addressed the lockdep WARN caused by the circular lock dependency among six locks: set->srcu -> sk_lock -> cpu_hotplug_lock -> fs_reclaim -> q_usage_counter -> elevator_lock -> set->srcu As its title says, the commit cut the dependency by introducing the dynamic lockdep keys per socket instance. However, as described in the Link tag URL, the commit made a wrong assumption: it assumed that __fput_sync(queue->sock->file) in nvme_tcp_free_queue() would synchronously destroy the socket. This is wrong: when in-flight packets cause delayed free of the socket, the prematurely freed lockdep key is referred to and causes another WARN. The commit is an imperfect fix. Hence revert it. To address the circular dependency among the six locks, another solution is required. It is provided by the commit0ba6912f7e("Revert "once: don't use a work queue to reset sleepable static key""). It cuts the dependency between sk_lock and cpu_hotplug_lock. This solution is simpler, and reduces the complexity in nvme-tcp. Link: https://lore.kernel.org/lkml/CANn89i+wnTLC==UnXCpjsS4YxvEfhe5oK0N7fttbqr1zKyqdug@mail.gmail.com/ Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Nilay Shroff <nilay@linux.ibm.com> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
parent
2f271b8121
commit
7fc61cdab1
|
|
@ -144,11 +144,6 @@ struct nvme_tcp_queue {
|
|||
void (*state_change)(struct sock *);
|
||||
void (*data_ready)(struct sock *);
|
||||
void (*write_space)(struct sock *);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
struct lock_class_key nvme_tcp_sk_key;
|
||||
struct lock_class_key nvme_tcp_slock_key;
|
||||
#endif
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(nvme_tcp_ctrl_mutex);
|
||||
|
|
@ -185,9 +180,12 @@ static int nvme_tcp_try_send(struct nvme_tcp_queue *queue);
|
|||
* a separate class prevents lockdep from conflating nvme-tcp socket use with
|
||||
* user-space socket API use.
|
||||
*/
|
||||
static void nvme_tcp_reclassify_socket(struct nvme_tcp_queue *queue)
|
||||
static struct lock_class_key nvme_tcp_sk_key[2];
|
||||
static struct lock_class_key nvme_tcp_slock_key[2];
|
||||
|
||||
static void nvme_tcp_reclassify_socket(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = queue->sock->sk;
|
||||
struct sock *sk = sock->sk;
|
||||
|
||||
if (WARN_ON_ONCE(!sock_allow_reclassification(sk)))
|
||||
return;
|
||||
|
|
@ -195,20 +193,22 @@ static void nvme_tcp_reclassify_socket(struct nvme_tcp_queue *queue)
|
|||
switch (sk->sk_family) {
|
||||
case AF_INET:
|
||||
sock_lock_init_class_and_name(sk, "slock-AF_INET-NVME",
|
||||
&queue->nvme_tcp_slock_key,
|
||||
&nvme_tcp_slock_key[0],
|
||||
"sk_lock-AF_INET-NVME",
|
||||
&queue->nvme_tcp_sk_key);
|
||||
&nvme_tcp_sk_key[0]);
|
||||
break;
|
||||
case AF_INET6:
|
||||
sock_lock_init_class_and_name(sk, "slock-AF_INET6-NVME",
|
||||
&queue->nvme_tcp_slock_key,
|
||||
&nvme_tcp_slock_key[1],
|
||||
"sk_lock-AF_INET6-NVME",
|
||||
&queue->nvme_tcp_sk_key);
|
||||
&nvme_tcp_sk_key[1]);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void nvme_tcp_reclassify_socket(struct socket *sock) { }
|
||||
#endif
|
||||
|
||||
static inline struct nvme_tcp_ctrl *to_tcp_ctrl(struct nvme_ctrl *ctrl)
|
||||
|
|
@ -1523,11 +1523,6 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
|
|||
mutex_destroy(&queue->send_mutex);
|
||||
mutex_destroy(&queue->queue_lock);
|
||||
mutex_destroy(&queue->pf_cache_lock);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
lockdep_unregister_key(&queue->nvme_tcp_sk_key);
|
||||
lockdep_unregister_key(&queue->nvme_tcp_slock_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
|
||||
|
|
@ -1874,12 +1869,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid,
|
|||
}
|
||||
|
||||
sk_net_refcnt_upgrade(queue->sock->sk);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
lockdep_register_key(&queue->nvme_tcp_sk_key);
|
||||
lockdep_register_key(&queue->nvme_tcp_slock_key);
|
||||
nvme_tcp_reclassify_socket(queue);
|
||||
#endif
|
||||
nvme_tcp_reclassify_socket(queue->sock);
|
||||
|
||||
/* Single syn retry */
|
||||
tcp_sock_set_syncnt(queue->sock->sk, 1);
|
||||
|
|
@ -1984,10 +1974,6 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid,
|
|||
/* Use sync variant - see nvme_tcp_free_queue() for explanation */
|
||||
__fput_sync(queue->sock->file);
|
||||
queue->sock = NULL;
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
lockdep_unregister_key(&queue->nvme_tcp_sk_key);
|
||||
lockdep_unregister_key(&queue->nvme_tcp_slock_key);
|
||||
#endif
|
||||
err_destroy_mutex:
|
||||
mutex_destroy(&queue->send_mutex);
|
||||
mutex_destroy(&queue->queue_lock);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user