On Mon, May 10, 2021 at 12:44:29PM +0900, Kuniyuki Iwashima wrote: > diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c > index e690d1cff36e..fe666dc5c621 100644 > --- a/net/ipv4/inet_connection_sock.c > +++ b/net/ipv4/inet_connection_sock.c > @@ -1075,10 +1075,38 @@ struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child, > if (own_req) { > inet_csk_reqsk_queue_drop(sk, req); > reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); In the migration case 'sk != req->rsk_listener', is sk the right one to pass in the above two functions? > - if (inet_csk_reqsk_queue_add(sk, req, child)) > + > + if (sk != req->rsk_listener) { > + /* another listening sk has been selected, > + * migrate the req to it. > + */ > + struct request_sock *nreq; > + > + /* hold a refcnt for the nreq->rsk_listener > + * which is assigned in reqsk_clone() > + */ > + sock_hold(sk); > + nreq = reqsk_clone(req, sk); > + if (!nreq) { > + inet_child_forget(sk, req, child); > + goto child_put; > + } > + > + refcount_set(&nreq->rsk_refcnt, 1); > + if (inet_csk_reqsk_queue_add(sk, nreq, child)) { > + reqsk_migrate_reset(req); > + reqsk_put(req); > + return child; > + } > + > + reqsk_migrate_reset(nreq); > + __reqsk_free(nreq); > + } else if (inet_csk_reqsk_queue_add(sk, req, child)) { > return child; > + } > } > /* Too bad, another child took ownership of the request, undo. */ > +child_put: > bh_unlock_sock(child); > sock_put(child); > return NULL;