mptcp: refactor token container
Replace the radix tree with a hash table allocated at boot time. The radix tree has some shortcoming: a single lock is contented by all the mptcp operation, the lookup currently use such lock, and traversing all the items would require a lock, too. With hash table instead we trade a little memory to address all the above - a per bucket lock is used. To hash the MPTCP sockets, we re-use the msk' sk_node entry: the MPTCP sockets are never hashed by the stack. Replace the existing hash proto callbacks with a dummy implementation, annotating the above constraint. Additionally refactor the token creation to code to: - limit the number of consecutive attempts to a fixed maximum. Hitting a hash bucket with a long chain is considered a failed attempt - accept() no longer can fail to token management. - if token creation fails at connect() time, we do fallback to TCP (before the connection was closed) v1 -> v2: - fix "no newline at end of file" - Jakub Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
d39dceca38
commit
2c5ebd001d
@@ -32,12 +32,9 @@ static void SUBFLOW_REQ_INC_STATS(struct request_sock *req,
|
||||
static int subflow_rebuild_header(struct sock *sk)
|
||||
{
|
||||
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
|
||||
int local_id, err = 0;
|
||||
int local_id;
|
||||
|
||||
if (subflow->request_mptcp && !subflow->token) {
|
||||
pr_debug("subflow=%p", sk);
|
||||
err = mptcp_token_new_connect(sk);
|
||||
} else if (subflow->request_join && !subflow->local_nonce) {
|
||||
if (subflow->request_join && !subflow->local_nonce) {
|
||||
struct mptcp_sock *msk = (struct mptcp_sock *)subflow->conn;
|
||||
|
||||
pr_debug("subflow=%p", sk);
|
||||
@@ -57,9 +54,6 @@ static int subflow_rebuild_header(struct sock *sk)
|
||||
}
|
||||
|
||||
out:
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return subflow->icsk_af_ops->rebuild_header(sk);
|
||||
}
|
||||
|
||||
@@ -72,8 +66,7 @@ static void subflow_req_destructor(struct request_sock *req)
|
||||
if (subflow_req->msk)
|
||||
sock_put((struct sock *)subflow_req->msk);
|
||||
|
||||
if (subflow_req->mp_capable)
|
||||
mptcp_token_destroy_request(subflow_req->token);
|
||||
mptcp_token_destroy_request(req);
|
||||
tcp_request_sock_ops.destructor(req);
|
||||
}
|
||||
|
||||
@@ -135,6 +128,7 @@ static void subflow_init_req(struct request_sock *req,
|
||||
subflow_req->mp_capable = 0;
|
||||
subflow_req->mp_join = 0;
|
||||
subflow_req->msk = NULL;
|
||||
mptcp_token_init_request(req);
|
||||
|
||||
#ifdef CONFIG_TCP_MD5SIG
|
||||
/* no MPTCP if MD5SIG is enabled on this socket or we may run out of
|
||||
@@ -250,7 +244,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
|
||||
subflow->remote_nonce = mp_opt.nonce;
|
||||
pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow,
|
||||
subflow->thmac, subflow->remote_nonce);
|
||||
} else if (subflow->request_mptcp) {
|
||||
} else {
|
||||
tp->is_mptcp = 0;
|
||||
}
|
||||
|
||||
@@ -386,7 +380,7 @@ static void mptcp_sock_destruct(struct sock *sk)
|
||||
sock_orphan(sk);
|
||||
}
|
||||
|
||||
mptcp_token_destroy(mptcp_sk(sk)->token);
|
||||
mptcp_token_destroy(mptcp_sk(sk));
|
||||
inet_sock_destruct(sk);
|
||||
}
|
||||
|
||||
@@ -505,6 +499,7 @@ create_child:
|
||||
*/
|
||||
new_msk->sk_destruct = mptcp_sock_destruct;
|
||||
mptcp_pm_new_connection(mptcp_sk(new_msk), 1);
|
||||
mptcp_token_accept(subflow_req, mptcp_sk(new_msk));
|
||||
ctx->conn = new_msk;
|
||||
new_msk = NULL;
|
||||
|
||||
|
Reference in New Issue
Block a user