1 | From: Geliang Tang <tanggeliang@kylinos.cn> | 1 | From: Geliang Tang <tanggeliang@kylinos.cn> |
---|---|---|---|
2 | |||
3 | v4: | ||
4 | - address Matt's comments in v3. | ||
5 | - update pm locks in mptcp_pm_worker. | ||
6 | - move the lock inside mptcp_pm_create_subflow_or_signal_addr. | ||
7 | - move the lock inside mptcp_pm_nl_add_addr_received. | ||
8 | - invoke add_addr_received interface from mptcp_pm_worker. | ||
9 | - invoke rm_addr_received interface from mptcp_pm_rm_addr_or_subflow. | ||
10 | - simply call mptcp_pm_close_subflow() in mptcp_pm_subflow_check_next. | ||
2 | 11 | ||
3 | v3: | 12 | v3: |
4 | - merge 'bugfixes for "BPF path manager, part 6, v2"' into this set. | 13 | - merge 'bugfixes for "BPF path manager, part 6, v2"' into this set. |
14 | - https://patchwork.kernel.org/project/mptcp/cover/cover.1742521397.git.tanggeliang@kylinos.cn/ | ||
5 | 15 | ||
6 | v2: | 16 | v2: |
7 | - address Matt's comments in v1. | 17 | - address Matt's comments in v1. |
8 | - add add_addr_received and rm_addr_received interfaces. | 18 | - add add_addr_received and rm_addr_received interfaces. |
9 | - drop subflow_check_next interface. | 19 | - drop subflow_check_next interface. |
... | ... | ||
13 | v1: | 23 | v1: |
14 | - https://patchwork.kernel.org/project/mptcp/cover/cover.1741685260.git.tanggeliang@kylinos.cn/ | 24 | - https://patchwork.kernel.org/project/mptcp/cover/cover.1741685260.git.tanggeliang@kylinos.cn/ |
15 | 25 | ||
16 | New interfaces for struct mptcp_pm_ops. | 26 | New interfaces for struct mptcp_pm_ops. |
17 | 27 | ||
18 | Geliang Tang (10): | 28 | Geliang Tang (9): |
29 | Squash to "mptcp: pm: add get_local_id() interface" | ||
30 | mptcp: pm: add established interfaces | ||
31 | mptcp: pm: drop is_userspace in subflow_check_next | ||
19 | mptcp: pm: drop redundant MPTCP_MIB_ADDADDRDROP | 32 | mptcp: pm: drop redundant MPTCP_MIB_ADDADDRDROP |
20 | Squash to "mptcp: pm: add get_local_id() interface" | 33 | mptcp: pm: add add_addr_received() interface |
21 | mptcp: pm: add established() interface | 34 | mptcp: pm: add rm_addr_received() interface |
22 | mptcp: pm: add subflow_established() interface | 35 | mptcp: pm: add add_addr_echo() interface |
36 | mptcp: pm: add accept_new_subflow() interface | ||
23 | mptcp: pm: add allow_new_subflow() interface | 37 | mptcp: pm: add allow_new_subflow() interface |
24 | mptcp: pm: add accept_new_subflow() interface | ||
25 | mptcp: pm: add add_addr_received() interface | ||
26 | mptcp: pm: add add_addr_echo() interface | ||
27 | mptcp: pm: add rm_addr_received() interface | ||
28 | mptcp: pm: drop is_userspace in subflow_check_next | ||
29 | 38 | ||
30 | include/net/mptcp.h | 16 ++++++ | 39 | include/net/mptcp.h | 15 ++++++ |
31 | net/mptcp/pm.c | 117 ++++++++++++++++++--------------------- | 40 | net/mptcp/pm.c | 114 ++++++++++++++++++--------------------- |
32 | net/mptcp/pm_kernel.c | 79 ++++++++++++++++++++++---- | 41 | net/mptcp/pm_kernel.c | 91 +++++++++++++++++++++---------- |
33 | net/mptcp/pm_userspace.c | 27 +++++++++ | 42 | net/mptcp/pm_userspace.c | 13 +++++ |
34 | net/mptcp/protocol.h | 4 ++ | 43 | net/mptcp/protocol.h | 3 +- |
35 | net/mptcp/subflow.c | 4 +- | 44 | net/mptcp/subflow.c | 4 +- |
36 | 6 files changed, 171 insertions(+), 76 deletions(-) | 45 | 6 files changed, 148 insertions(+), 92 deletions(-) |
37 | 46 | ||
38 | -- | 47 | -- |
39 | 2.43.0 | 48 | 2.43.0 | diff view generated by jsdifflib |
1 | From: Geliang Tang <tanggeliang@kylinos.cn> | 1 | From: Geliang Tang <tanggeliang@kylinos.cn> |
---|---|---|---|
2 | 2 | ||
3 | Add /* required */ comment for get_local_id and get_priority. | 3 | Add /* required */ comment for get_local_id and get_priority. |
4 | 4 | ||
5 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 5 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
6 | --- | 6 | --- |
7 | include/net/mptcp.h | 1 + | 7 | include/net/mptcp.h | 1 + |
8 | 1 file changed, 1 insertion(+) | 8 | 1 file changed, 1 insertion(+) |
9 | 9 | ||
10 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | 10 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/include/net/mptcp.h | 12 | --- a/include/net/mptcp.h |
13 | +++ b/include/net/mptcp.h | 13 | +++ b/include/net/mptcp.h |
14 | @@ -XXX,XX +XXX,XX @@ struct mptcp_sched_ops { | 14 | @@ -XXX,XX +XXX,XX @@ struct mptcp_sched_ops { |
15 | #define MPTCP_PM_BUF_MAX (MPTCP_PM_NAME_MAX * MPTCP_PM_MAX) | 15 | #define MPTCP_PM_BUF_MAX (MPTCP_PM_NAME_MAX * MPTCP_PM_MAX) |
16 | 16 | ||
17 | struct mptcp_pm_ops { | 17 | struct mptcp_pm_ops { |
18 | + /* required */ | 18 | + /* required */ |
19 | int (*get_local_id)(struct mptcp_sock *msk, | 19 | int (*get_local_id)(struct mptcp_sock *msk, |
20 | struct mptcp_pm_addr_entry *skc); | 20 | struct mptcp_pm_addr_entry *skc); |
21 | bool (*get_priority)(struct mptcp_sock *msk, | 21 | bool (*get_priority)(struct mptcp_sock *msk, |
22 | -- | 22 | -- |
23 | 2.43.0 | 23 | 2.43.0 | diff view generated by jsdifflib |
1 | From: Geliang Tang <tanggeliang@kylinos.cn> | 1 | From: Geliang Tang <tanggeliang@kylinos.cn> |
---|---|---|---|
2 | 2 | ||
3 | This patch adds a .subflow_established interface for struct mptcp_pm_ops, | 3 | This patch adds .established and .subflow_established interfaces for |
4 | and calls pm->ops->subflow_established in from mptcp_pm_worker(). Then | 4 | struct mptcp_pm_ops, and calls pm->ops->established/subflow_established |
5 | get rid of the corresponding code from __mptcp_pm_kernel_worker(). | 5 | in from mptcp_pm_worker(). Then get rid of the corresponding code from |
6 | __mptcp_pm_kernel_worker(). | ||
6 | 7 | ||
7 | Since mptcp_pm_addr_send_ack() is a sleepable kfunc, which is invoked | 8 | Since mptcp_pm_addr_send_ack() is a sleepable kfunc, which is invoked |
8 | by mptcp_pm_create_subflow_or_signal_addr(), .subflow_established() | 9 | by mptcp_pm_create_subflow_or_signal_addr(), .established() and |
9 | interface of BPF PM should be invoked by __bpf_prog_enter_sleepable(), | 10 | .subflow_established() interfaces of BPF PM should be invoked by |
10 | which can't be invoked under a lock. This patch unlocks the pm lock | 11 | __bpf_prog_enter_sleepable(), which can't be invoked under a lock. |
11 | before invoking this interface in mptcp_pm_worker(), while holding this | 12 | This patch unlocks the pm lock before invoking this interface in |
12 | lock in mptcp_pm_kernel_subflow_established(). | 13 | mptcp_pm_worker(), while holding this lock in mptcp_pm_kernel_established() |
14 | and mptcp_pm_kernel_subflow_established(). | ||
13 | 15 | ||
14 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 16 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
15 | --- | 17 | --- |
16 | include/net/mptcp.h | 1 + | 18 | include/net/mptcp.h | 4 ++++ |
17 | net/mptcp/pm.c | 13 +++++++++++-- | 19 | net/mptcp/pm.c | 32 ++++++++++++++++++++++++-------- |
18 | net/mptcp/pm_kernel.c | 9 ++++----- | 20 | net/mptcp/pm_kernel.c | 25 +++++++++++-------------- |
19 | 3 files changed, 16 insertions(+), 7 deletions(-) | 21 | 3 files changed, 39 insertions(+), 22 deletions(-) |
20 | 22 | ||
21 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | 23 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h |
22 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/include/net/mptcp.h | 25 | --- a/include/net/mptcp.h |
24 | +++ b/include/net/mptcp.h | 26 | +++ b/include/net/mptcp.h |
25 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { | 27 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { |
26 | 28 | bool (*get_priority)(struct mptcp_sock *msk, | |
27 | /* optional */ | 29 | struct mptcp_addr_info *skc); |
28 | void (*established)(struct mptcp_sock *msk); | 30 | |
31 | + /* optional */ | ||
32 | + void (*established)(struct mptcp_sock *msk); | ||
29 | + void (*subflow_established)(struct mptcp_sock *msk); | 33 | + void (*subflow_established)(struct mptcp_sock *msk); |
30 | 34 | + | |
31 | char name[MPTCP_PM_NAME_MAX]; | 35 | char name[MPTCP_PM_NAME_MAX]; |
32 | struct module *owner; | 36 | struct module *owner; |
37 | struct list_head list; | ||
33 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 38 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
34 | index XXXXXXX..XXXXXXX 100644 | 39 | index XXXXXXX..XXXXXXX 100644 |
35 | --- a/net/mptcp/pm.c | 40 | --- a/net/mptcp/pm.c |
36 | +++ b/net/mptcp/pm.c | 41 | +++ b/net/mptcp/pm.c |
42 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk) | ||
43 | * be sure to serve this event only once. | ||
44 | */ | ||
45 | if (READ_ONCE(pm->work_pending) && | ||
46 | - !(pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED))) | ||
47 | + !(pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) && | ||
48 | + pm->ops->established) | ||
49 | mptcp_pm_schedule_work(msk, MPTCP_PM_ESTABLISHED); | ||
50 | |||
51 | if ((pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) == 0) | ||
37 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk) | 52 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk) |
38 | 53 | ||
39 | pr_debug("msk=%p\n", msk); | 54 | pr_debug("msk=%p\n", msk); |
40 | 55 | ||
41 | - if (!READ_ONCE(pm->work_pending)) | 56 | - if (!READ_ONCE(pm->work_pending)) |
... | ... | ||
45 | spin_lock_bh(&pm->lock); | 60 | spin_lock_bh(&pm->lock); |
46 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, | 61 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, |
47 | return; | 62 | return; |
48 | } | 63 | } |
49 | 64 | ||
50 | + if (!pm->ops->subflow_established) | 65 | - if (!READ_ONCE(pm->work_pending) && !update_subflows) |
51 | + return; | 66 | + if (!pm->ops->subflow_established || |
52 | + | 67 | + (!READ_ONCE(pm->work_pending) && !update_subflows)) |
53 | if (!READ_ONCE(pm->work_pending) && !update_subflows) | 68 | return; |
54 | return; | 69 | |
55 | 70 | spin_lock_bh(&pm->lock); | |
56 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk, | 71 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk, |
57 | 72 | ||
58 | pr_debug("msk=%p\n", msk); | 73 | pr_debug("msk=%p\n", msk); |
59 | 74 | ||
60 | - if (!READ_ONCE(pm->work_pending)) | 75 | - if (!READ_ONCE(pm->work_pending)) |
61 | + if (!READ_ONCE(pm->work_pending) || !pm->ops->subflow_established) | 76 | + if (!READ_ONCE(pm->work_pending) || !pm->ops->subflow_established) |
62 | return; | 77 | return; |
63 | 78 | ||
64 | spin_lock_bh(&pm->lock); | 79 | spin_lock_bh(&pm->lock); |
65 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_worker(struct mptcp_sock *msk) | 80 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_worker(struct mptcp_sock *msk) |
66 | pm->ops->established(msk); | 81 | if (!(pm->status & MPTCP_PM_WORK_MASK)) |
67 | spin_lock_bh(&pm->lock); | 82 | return; |
68 | } | 83 | |
84 | - spin_lock_bh(&msk->pm.lock); | ||
85 | - | ||
86 | pr_debug("msk=%p status=%x\n", msk, pm->status); | ||
87 | if (pm->status & BIT(MPTCP_PM_ADD_ADDR_SEND_ACK)) { | ||
88 | + spin_lock_bh(&pm->lock); | ||
89 | pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_SEND_ACK); | ||
90 | mptcp_pm_addr_send_ack(msk); | ||
91 | + spin_unlock_bh(&pm->lock); | ||
92 | } | ||
93 | if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) { | ||
94 | + spin_lock_bh(&pm->lock); | ||
95 | pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED); | ||
96 | mptcp_pm_rm_addr_recv(msk); | ||
97 | + spin_unlock_bh(&pm->lock); | ||
98 | + } | ||
99 | + if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) { | ||
100 | + spin_lock_bh(&pm->lock); | ||
101 | + pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); | ||
102 | + spin_unlock_bh(&pm->lock); | ||
103 | + pm->ops->established(msk); | ||
104 | + } | ||
69 | + if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) { | 105 | + if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) { |
106 | + spin_lock_bh(&pm->lock); | ||
70 | + pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED); | 107 | + pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED); |
71 | + spin_unlock_bh(&pm->lock); | 108 | + spin_unlock_bh(&pm->lock); |
72 | + pm->ops->subflow_established(msk); | 109 | + pm->ops->subflow_established(msk); |
73 | + spin_lock_bh(&pm->lock); | 110 | } |
74 | + } | 111 | + spin_lock_bh(&pm->lock); |
75 | __mptcp_pm_kernel_worker(msk); | 112 | __mptcp_pm_kernel_worker(msk); |
76 | 113 | - | |
77 | spin_unlock_bh(&msk->pm.lock); | 114 | - spin_unlock_bh(&msk->pm.lock); |
115 | + spin_unlock_bh(&pm->lock); | ||
116 | } | ||
117 | |||
118 | static void mptcp_pm_ops_init(struct mptcp_sock *msk, | ||
78 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c | 119 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c |
79 | index XXXXXXX..XXXXXXX 100644 | 120 | index XXXXXXX..XXXXXXX 100644 |
80 | --- a/net/mptcp/pm_kernel.c | 121 | --- a/net/mptcp/pm_kernel.c |
81 | +++ b/net/mptcp/pm_kernel.c | 122 | +++ b/net/mptcp/pm_kernel.c |
82 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_kernel_established(struct mptcp_sock *msk) | 123 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) |
83 | spin_unlock_bh(&msk->pm.lock); | 124 | local_addr_max = mptcp_pm_get_local_addr_max(msk); |
84 | } | 125 | subflows_max = mptcp_pm_get_subflows_max(msk); |
126 | |||
127 | + spin_lock_bh(&msk->pm.lock); | ||
128 | /* do lazy endpoint usage accounting for the MPC subflows */ | ||
129 | if (unlikely(!(msk->pm.status & BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED))) && msk->first) { | ||
130 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(msk->first); | ||
131 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) | ||
132 | * current address announce will be completed. | ||
133 | */ | ||
134 | if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) | ||
135 | - return; | ||
136 | + goto out; | ||
137 | |||
138 | if (!select_signal_address(pernet, msk, &local)) | ||
139 | goto subflow; | ||
140 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) | ||
141 | * continuing, and trying to create subflows. | ||
142 | */ | ||
143 | if (!mptcp_pm_alloc_anno_list(msk, &local.addr)) | ||
144 | - return; | ||
145 | + goto out; | ||
146 | |||
147 | __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); | ||
148 | msk->pm.add_addr_signaled++; | ||
149 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) | ||
150 | spin_lock_bh(&msk->pm.lock); | ||
151 | } | ||
152 | mptcp_pm_nl_check_work_pending(msk); | ||
153 | +out: | ||
154 | + spin_unlock_bh(&msk->pm.lock); | ||
155 | } | ||
156 | |||
157 | -static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk) | ||
158 | +static void mptcp_pm_kernel_established(struct mptcp_sock *msk) | ||
159 | { | ||
160 | mptcp_pm_create_subflow_or_signal_addr(msk); | ||
161 | } | ||
85 | 162 | ||
86 | -static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk) | 163 | -static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk) |
87 | +static void mptcp_pm_kernel_subflow_established(struct mptcp_sock *msk) | 164 | +static void mptcp_pm_kernel_subflow_established(struct mptcp_sock *msk) |
88 | { | 165 | { |
89 | + spin_lock_bh(&msk->pm.lock); | ||
90 | mptcp_pm_create_subflow_or_signal_addr(msk); | 166 | mptcp_pm_create_subflow_or_signal_addr(msk); |
91 | + spin_unlock_bh(&msk->pm.lock); | 167 | } |
92 | } | 168 | @@ -XXX,XX +XXX,XX @@ static int mptcp_nl_add_subflow_or_signal_addr(struct net *net, |
93 | 169 | spin_lock_bh(&msk->pm.lock); | |
94 | /* Fill all the local addresses into the array addrs[], | 170 | if (mptcp_addresses_equal(addr, &mpc_addr, addr->port)) |
171 | msk->mpc_endpoint_id = addr->id; | ||
172 | - mptcp_pm_create_subflow_or_signal_addr(msk); | ||
173 | spin_unlock_bh(&msk->pm.lock); | ||
174 | + mptcp_pm_create_subflow_or_signal_addr(msk); | ||
175 | release_sock(sk); | ||
176 | |||
177 | next: | ||
178 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk, | ||
179 | spin_lock_bh(&msk->pm.lock); | ||
180 | mptcp_pm_rm_subflow(msk, &list); | ||
181 | __mark_subflow_endp_available(msk, list.ids[0]); | ||
182 | - mptcp_pm_create_subflow_or_signal_addr(msk); | ||
183 | spin_unlock_bh(&msk->pm.lock); | ||
184 | + mptcp_pm_create_subflow_or_signal_addr(msk); | ||
185 | } | ||
186 | |||
187 | static void mptcp_pm_nl_set_flags_all(struct net *net, | ||
95 | @@ -XXX,XX +XXX,XX @@ void __mptcp_pm_kernel_worker(struct mptcp_sock *msk) | 188 | @@ -XXX,XX +XXX,XX @@ void __mptcp_pm_kernel_worker(struct mptcp_sock *msk) |
96 | pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED); | 189 | pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED); |
97 | mptcp_pm_nl_add_addr_received(msk); | 190 | mptcp_pm_nl_add_addr_received(msk); |
98 | } | 191 | } |
192 | - if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) { | ||
193 | - pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); | ||
194 | - mptcp_pm_nl_fully_established(msk); | ||
195 | - } | ||
99 | - if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) { | 196 | - if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) { |
100 | - pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED); | 197 | - pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED); |
101 | - mptcp_pm_nl_subflow_established(msk); | 198 | - mptcp_pm_nl_subflow_established(msk); |
102 | - } | 199 | - } |
103 | } | 200 | } |
104 | 201 | ||
105 | static int __net_init pm_nl_init_net(struct net *net) | 202 | static int __net_init pm_nl_init_net(struct net *net) |
106 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { | 203 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_kernel_init(struct mptcp_sock *msk) |
204 | struct mptcp_pm_ops mptcp_pm_kernel = { | ||
107 | .get_local_id = mptcp_pm_kernel_get_local_id, | 205 | .get_local_id = mptcp_pm_kernel_get_local_id, |
108 | .get_priority = mptcp_pm_kernel_get_priority, | 206 | .get_priority = mptcp_pm_kernel_get_priority, |
109 | .established = mptcp_pm_kernel_established, | 207 | + .established = mptcp_pm_kernel_established, |
110 | + .subflow_established = mptcp_pm_kernel_subflow_established, | 208 | + .subflow_established = mptcp_pm_kernel_subflow_established, |
111 | .init = mptcp_pm_kernel_init, | 209 | .init = mptcp_pm_kernel_init, |
112 | .name = "kernel", | 210 | .name = "kernel", |
113 | .owner = THIS_MODULE, | 211 | .owner = THIS_MODULE, |
114 | -- | 212 | -- |
115 | 2.43.0 | 213 | 2.43.0 | diff view generated by jsdifflib |
1 | From: Geliang Tang <tanggeliang@kylinos.cn> | 1 | From: Geliang Tang <tanggeliang@kylinos.cn> |
---|---|---|---|
2 | 2 | ||
3 | In mptcp_pm_subflow_check_next(), instead of reducing "pm->subflows" | 3 | This patch moves mptcp_pm_close_subflow() forward to let it be used by both |
4 | for the in-kernel PM in __mptcp_pm_close_subflow(), this patch moves | 4 | the userspace PM and the in-kernel PM in mptcp_pm_subflow_check_next().Then |
5 | "pm->subflows--;" forward to let it be used by both the userspace PM | 5 | mptcp_pm_is_userspace() here can be dropped. |
6 | and the in-kernel PM. Then mptcp_pm_is_userspace() here can be dropped. | ||
7 | 6 | ||
8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 7 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
9 | --- | 8 | --- |
10 | net/mptcp/pm.c | 15 ++++++--------- | 9 | net/mptcp/pm.c | 12 ++---------- |
11 | 1 file changed, 6 insertions(+), 9 deletions(-) | 10 | 1 file changed, 2 insertions(+), 10 deletions(-) |
12 | 11 | ||
13 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 12 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
14 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/net/mptcp/pm.c | 14 | --- a/net/mptcp/pm.c |
16 | +++ b/net/mptcp/pm.c | 15 | +++ b/net/mptcp/pm.c |
... | ... | ||
23 | - spin_lock_bh(&pm->lock); | 22 | - spin_lock_bh(&pm->lock); |
24 | - pm->subflows--; | 23 | - pm->subflows--; |
25 | - spin_unlock_bh(&pm->lock); | 24 | - spin_unlock_bh(&pm->lock); |
26 | - } | 25 | - } |
27 | - return; | 26 | - return; |
28 | + if (update_subflows) { | 27 | - } |
29 | + spin_lock_bh(&pm->lock); | 28 | + if (update_subflows) |
30 | + pm->subflows--; | 29 | + mptcp_pm_close_subflow(msk); |
31 | + spin_unlock_bh(&pm->lock); | 30 | |
32 | } | 31 | if (!pm->ops->subflow_established || |
33 | 32 | (!READ_ONCE(pm->work_pending) && !update_subflows)) | |
34 | if (!pm->ops->subflow_established) | ||
35 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, | ||
36 | return; | 33 | return; |
37 | 34 | ||
38 | spin_lock_bh(&pm->lock); | 35 | spin_lock_bh(&pm->lock); |
39 | - if (update_subflows) | 36 | - if (update_subflows) |
40 | - __mptcp_pm_close_subflow(msk); | 37 | - __mptcp_pm_close_subflow(msk); |
41 | + if (update_subflows && msk->pm.subflows < mptcp_pm_get_subflows_max(msk)) | ||
42 | + WRITE_ONCE(msk->pm.accept_subflow, true); | ||
43 | 38 | ||
44 | /* Even if this subflow is not really established, tell the PM to try | 39 | /* Even if this subflow is not really established, tell the PM to try |
45 | * to pick the next ones, if possible. | 40 | * to pick the next ones, if possible. |
46 | -- | 41 | -- |
47 | 2.43.0 | 42 | 2.43.0 | diff view generated by jsdifflib |
1 | From: Geliang Tang <tanggeliang@kylinos.cn> | 1 | From: Geliang Tang <tanggeliang@kylinos.cn> |
---|---|---|---|
2 | 2 | ||
3 | MPTCP_MIB_ADDADDRDROP MIB counter is incremented from both the in-kernel PM | 3 | MPTCP_MIB_ADDADDRDROP MIB counter is incremented from both the in-kernel PM |
4 | and the userspace PM. This can be called only once to reduce redundant | 4 | and the userspace PM. This can be called only once to reduce redundant |
5 | code. | 5 | code. |
6 | 6 | ||
7 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 7 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
8 | --- | 8 | --- |
9 | net/mptcp/pm.c | 8 ++++++-- | 9 | net/mptcp/pm.c | 8 ++++++-- |
10 | 1 file changed, 6 insertions(+), 2 deletions(-) | 10 | 1 file changed, 6 insertions(+), 2 deletions(-) |
11 | 11 | ||
12 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 12 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
13 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/net/mptcp/pm.c | 14 | --- a/net/mptcp/pm.c |
15 | +++ b/net/mptcp/pm.c | 15 | +++ b/net/mptcp/pm.c |
16 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, | 16 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, |
17 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); | 17 | struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); |
18 | struct mptcp_sock *msk = mptcp_sk(subflow->conn); | 18 | struct mptcp_sock *msk = mptcp_sk(subflow->conn); |
19 | struct mptcp_pm_data *pm = &msk->pm; | 19 | struct mptcp_pm_data *pm = &msk->pm; |
20 | + int ret = 0; | 20 | + int ret = 0; |
21 | 21 | ||
22 | pr_debug("msk=%p remote_id=%d accept=%d\n", msk, addr->id, | 22 | pr_debug("msk=%p remote_id=%d accept=%d\n", msk, addr->id, |
23 | READ_ONCE(pm->accept_addr)); | 23 | READ_ONCE(pm->accept_addr)); |
24 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, | 24 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, |
25 | mptcp_pm_announce_addr(msk, addr, true); | 25 | mptcp_pm_announce_addr(msk, addr, true); |
26 | mptcp_pm_add_addr_send_ack(msk); | 26 | mptcp_pm_add_addr_send_ack(msk); |
27 | } else { | 27 | } else { |
28 | - __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); | 28 | - __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); |
29 | + ret = -EINVAL; | 29 | + ret = -EINVAL; |
30 | } | 30 | } |
31 | /* id0 should not have a different address */ | 31 | /* id0 should not have a different address */ |
32 | } else if ((addr->id == 0 && !mptcp_pm_is_init_remote_addr(msk, addr)) || | 32 | } else if ((addr->id == 0 && !mptcp_pm_is_init_remote_addr(msk, addr)) || |
33 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, | 33 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, |
34 | } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) { | 34 | } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) { |
35 | pm->remote = *addr; | 35 | pm->remote = *addr; |
36 | } else { | 36 | } else { |
37 | - __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); | 37 | - __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); |
38 | + ret = -EINVAL; | 38 | + ret = -EINVAL; |
39 | } | 39 | } |
40 | 40 | ||
41 | + if (ret) | 41 | + if (ret) |
42 | + __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); | 42 | + __MPTCP_INC_STATS(sock_net((struct sock *)msk), MPTCP_MIB_ADDADDRDROP); |
43 | + | 43 | + |
44 | spin_unlock_bh(&pm->lock); | 44 | spin_unlock_bh(&pm->lock); |
45 | } | 45 | } |
46 | 46 | ||
47 | -- | 47 | -- |
48 | 2.43.0 | 48 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Geliang Tang <tanggeliang@kylinos.cn> | ||
2 | 1 | ||
3 | This patch adds a .established interface for struct mptcp_pm_ops, and | ||
4 | calls pm->ops->established in from mptcp_pm_worker(). Then get rid of | ||
5 | the corresponding code from __mptcp_pm_kernel_worker(). | ||
6 | |||
7 | Since mptcp_pm_addr_send_ack() is a sleepable kfunc, which is invoked | ||
8 | by mptcp_pm_create_subflow_or_signal_addr(), .established() interface | ||
9 | of BPF PM should be invoked by __bpf_prog_enter_sleepable(), which | ||
10 | can't be invoked under a lock. This patch unlocks the pm lock before | ||
11 | invoking this interface in mptcp_pm_worker(), while holding this lock | ||
12 | in mptcp_pm_kernel_established(). | ||
13 | |||
14 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | ||
15 | --- | ||
16 | include/net/mptcp.h | 3 +++ | ||
17 | net/mptcp/pm.c | 9 ++++++++- | ||
18 | net/mptcp/pm_kernel.c | 9 ++++----- | ||
19 | 3 files changed, 15 insertions(+), 6 deletions(-) | ||
20 | |||
21 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/include/net/mptcp.h | ||
24 | +++ b/include/net/mptcp.h | ||
25 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { | ||
26 | bool (*get_priority)(struct mptcp_sock *msk, | ||
27 | struct mptcp_addr_info *skc); | ||
28 | |||
29 | + /* optional */ | ||
30 | + void (*established)(struct mptcp_sock *msk); | ||
31 | + | ||
32 | char name[MPTCP_PM_NAME_MAX]; | ||
33 | struct module *owner; | ||
34 | struct list_head list; | ||
35 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | ||
36 | index XXXXXXX..XXXXXXX 100644 | ||
37 | --- a/net/mptcp/pm.c | ||
38 | +++ b/net/mptcp/pm.c | ||
39 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_fully_established(struct mptcp_sock *msk, const struct sock *ssk) | ||
40 | * be sure to serve this event only once. | ||
41 | */ | ||
42 | if (READ_ONCE(pm->work_pending) && | ||
43 | - !(pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED))) | ||
44 | + !(pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) && | ||
45 | + pm->ops->established) | ||
46 | mptcp_pm_schedule_work(msk, MPTCP_PM_ESTABLISHED); | ||
47 | |||
48 | if ((pm->status & BIT(MPTCP_PM_ALREADY_ESTABLISHED)) == 0) | ||
49 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_worker(struct mptcp_sock *msk) | ||
50 | pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED); | ||
51 | mptcp_pm_rm_addr_recv(msk); | ||
52 | } | ||
53 | + if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) { | ||
54 | + pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); | ||
55 | + spin_unlock_bh(&pm->lock); | ||
56 | + pm->ops->established(msk); | ||
57 | + spin_lock_bh(&pm->lock); | ||
58 | + } | ||
59 | __mptcp_pm_kernel_worker(msk); | ||
60 | |||
61 | spin_unlock_bh(&msk->pm.lock); | ||
62 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c | ||
63 | index XXXXXXX..XXXXXXX 100644 | ||
64 | --- a/net/mptcp/pm_kernel.c | ||
65 | +++ b/net/mptcp/pm_kernel.c | ||
66 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) | ||
67 | mptcp_pm_nl_check_work_pending(msk); | ||
68 | } | ||
69 | |||
70 | -static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk) | ||
71 | +static void mptcp_pm_kernel_established(struct mptcp_sock *msk) | ||
72 | { | ||
73 | + spin_lock_bh(&msk->pm.lock); | ||
74 | mptcp_pm_create_subflow_or_signal_addr(msk); | ||
75 | + spin_unlock_bh(&msk->pm.lock); | ||
76 | } | ||
77 | |||
78 | static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk) | ||
79 | @@ -XXX,XX +XXX,XX @@ void __mptcp_pm_kernel_worker(struct mptcp_sock *msk) | ||
80 | pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED); | ||
81 | mptcp_pm_nl_add_addr_received(msk); | ||
82 | } | ||
83 | - if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) { | ||
84 | - pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); | ||
85 | - mptcp_pm_nl_fully_established(msk); | ||
86 | - } | ||
87 | if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) { | ||
88 | pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED); | ||
89 | mptcp_pm_nl_subflow_established(msk); | ||
90 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_kernel_init(struct mptcp_sock *msk) | ||
91 | struct mptcp_pm_ops mptcp_pm_kernel = { | ||
92 | .get_local_id = mptcp_pm_kernel_get_local_id, | ||
93 | .get_priority = mptcp_pm_kernel_get_priority, | ||
94 | + .established = mptcp_pm_kernel_established, | ||
95 | .init = mptcp_pm_kernel_init, | ||
96 | .name = "kernel", | ||
97 | .owner = THIS_MODULE, | ||
98 | -- | ||
99 | 2.43.0 | diff view generated by jsdifflib |
1 | From: Geliang Tang <tanggeliang@kylinos.cn> | 1 | From: Geliang Tang <tanggeliang@kylinos.cn> |
---|---|---|---|
2 | 2 | ||
3 | This patch adds an optional .add_addr_received interface for struct | 3 | This patch adds an optional .add_addr_received interface for struct |
4 | mptcp_pm_ops and invokes it in mptcp_pm_add_addr_received(). A new helper | 4 | mptcp_pm_ops and invokes it in mptcp_pm_worker(). |
5 | mptcp_pm_add_addr_recv() is added to allow the MPTCP_PM_ADD_ADDR_RECEIVED | 5 | |
6 | worker can be invoke from the in-kernel PM. | 6 | This interface is only implemented in the in-kernel PM as a wrapper |
7 | of mptcp_pm_nl_add_addr_received(). | ||
7 | 8 | ||
8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 9 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
9 | --- | 10 | --- |
10 | include/net/mptcp.h | 4 ++++ | 11 | include/net/mptcp.h | 1 + |
11 | net/mptcp/pm.c | 9 +++++++-- | 12 | net/mptcp/pm.c | 18 +++++++++++------- |
12 | net/mptcp/pm_kernel.c | 13 +++++++++++++ | 13 | net/mptcp/pm_kernel.c | 24 +++++++++++------------- |
13 | net/mptcp/protocol.h | 1 + | 14 | net/mptcp/protocol.h | 1 - |
14 | 4 files changed, 25 insertions(+), 2 deletions(-) | 15 | 4 files changed, 23 insertions(+), 21 deletions(-) |
15 | 16 | ||
16 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | 17 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h |
17 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/include/net/mptcp.h | 19 | --- a/include/net/mptcp.h |
19 | +++ b/include/net/mptcp.h | 20 | +++ b/include/net/mptcp.h |
20 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { | 21 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { |
21 | bool (*allow_new_subflow)(struct mptcp_sock *msk); | 22 | /* optional */ |
22 | bool (*accept_new_subflow)(const struct mptcp_sock *msk); | 23 | void (*established)(struct mptcp_sock *msk); |
23 | 24 | void (*subflow_established)(struct mptcp_sock *msk); | |
24 | + /* optional */ | 25 | + void (*add_addr_received)(struct mptcp_sock *msk); |
25 | + int (*add_addr_received)(struct mptcp_sock *msk, | 26 | |
26 | + const struct mptcp_addr_info *addr); | ||
27 | + | ||
28 | char name[MPTCP_PM_NAME_MAX]; | 27 | char name[MPTCP_PM_NAME_MAX]; |
29 | struct module *owner; | 28 | struct module *owner; |
30 | struct list_head list; | ||
31 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 29 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
32 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/net/mptcp/pm.c | 31 | --- a/net/mptcp/pm.c |
34 | +++ b/net/mptcp/pm.c | 32 | +++ b/net/mptcp/pm.c |
35 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, | ||
36 | spin_unlock_bh(&pm->lock); | ||
37 | } | ||
38 | |||
39 | +bool mptcp_pm_add_addr_recv(struct mptcp_sock *msk) | ||
40 | +{ | ||
41 | + return mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED); | ||
42 | +} | ||
43 | + | ||
44 | void mptcp_pm_add_addr_received(const struct sock *ssk, | ||
45 | const struct mptcp_addr_info *addr) | ||
46 | { | ||
47 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, | 33 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, |
48 | (addr->id > 0 && !READ_ONCE(pm->accept_addr))) { | 34 | (addr->id > 0 && !READ_ONCE(pm->accept_addr))) { |
49 | mptcp_pm_announce_addr(msk, addr, true); | 35 | mptcp_pm_announce_addr(msk, addr, true); |
50 | mptcp_pm_add_addr_send_ack(msk); | 36 | mptcp_pm_add_addr_send_ack(msk); |
51 | - } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) { | 37 | - } else if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) { |
52 | - pm->remote = *addr; | 38 | - pm->remote = *addr; |
53 | } else { | 39 | - } else { |
54 | ret = -EINVAL; | 40 | - ret = -EINVAL; |
55 | + if (pm->ops->add_addr_received) | 41 | + } else if (pm->ops->add_addr_received) { |
56 | + ret = pm->ops->add_addr_received(msk, addr); | 42 | + if (mptcp_pm_schedule_work(msk, MPTCP_PM_ADD_ADDR_RECEIVED)) |
43 | + pm->remote = *addr; | ||
44 | + else | ||
45 | + ret = -EINVAL; | ||
57 | } | 46 | } |
58 | 47 | ||
59 | if (ret) | 48 | if (ret) |
49 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_worker(struct mptcp_sock *msk) | ||
50 | return; | ||
51 | |||
52 | pr_debug("msk=%p status=%x\n", msk, pm->status); | ||
53 | + if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) { | ||
54 | + spin_lock_bh(&pm->lock); | ||
55 | + pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED); | ||
56 | + spin_unlock_bh(&pm->lock); | ||
57 | + pm->ops->add_addr_received(msk); | ||
58 | + } | ||
59 | if (pm->status & BIT(MPTCP_PM_ADD_ADDR_SEND_ACK)) { | ||
60 | spin_lock_bh(&pm->lock); | ||
61 | pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_SEND_ACK); | ||
62 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_worker(struct mptcp_sock *msk) | ||
63 | spin_unlock_bh(&pm->lock); | ||
64 | pm->ops->subflow_established(msk); | ||
65 | } | ||
66 | - spin_lock_bh(&pm->lock); | ||
67 | - __mptcp_pm_kernel_worker(msk); | ||
68 | - spin_unlock_bh(&pm->lock); | ||
69 | } | ||
70 | |||
71 | static void mptcp_pm_ops_init(struct mptcp_sock *msk, | ||
60 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c | 72 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c |
61 | index XXXXXXX..XXXXXXX 100644 | 73 | index XXXXXXX..XXXXXXX 100644 |
62 | --- a/net/mptcp/pm_kernel.c | 74 | --- a/net/mptcp/pm_kernel.c |
63 | +++ b/net/mptcp/pm_kernel.c | 75 | +++ b/net/mptcp/pm_kernel.c |
64 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_kernel_accept_new_subflow(const struct mptcp_sock *msk) | 76 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) |
65 | return READ_ONCE(msk->pm.accept_subflow); | 77 | msk->pm.add_addr_accepted, add_addr_accept_max, |
78 | msk->pm.remote.family); | ||
79 | |||
80 | + spin_lock_bh(&msk->pm.lock); | ||
81 | remote = msk->pm.remote; | ||
82 | mptcp_pm_announce_addr(msk, &remote, true); | ||
83 | mptcp_pm_addr_send_ack(msk); | ||
84 | |||
85 | if (lookup_subflow_by_daddr(&msk->conn_list, &remote)) | ||
86 | - return; | ||
87 | + goto out; | ||
88 | |||
89 | /* pick id 0 port, if none is provided the remote address */ | ||
90 | if (!remote.port) | ||
91 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) | ||
92 | */ | ||
93 | nr = fill_local_addresses_vec(msk, &remote, locals); | ||
94 | if (nr == 0) | ||
95 | - return; | ||
96 | + goto out; | ||
97 | |||
98 | spin_unlock_bh(&msk->pm.lock); | ||
99 | for (i = 0; i < nr; i++) | ||
100 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) | ||
101 | msk->pm.subflows >= subflows_max) | ||
102 | WRITE_ONCE(msk->pm.accept_addr, false); | ||
103 | } | ||
104 | +out: | ||
105 | + spin_unlock_bh(&msk->pm.lock); | ||
66 | } | 106 | } |
67 | 107 | ||
68 | +static int mptcp_pm_kernel_add_addr_received(struct mptcp_sock *msk, | 108 | void mptcp_pm_nl_rm_addr(struct mptcp_sock *msk, u8 rm_id) |
69 | + const struct mptcp_addr_info *addr) | 109 | @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk) |
110 | return true; | ||
111 | } | ||
112 | |||
113 | -/* Called under PM lock */ | ||
114 | -void __mptcp_pm_kernel_worker(struct mptcp_sock *msk) | ||
115 | -{ | ||
116 | - struct mptcp_pm_data *pm = &msk->pm; | ||
117 | - | ||
118 | - if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) { | ||
119 | - pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED); | ||
120 | - mptcp_pm_nl_add_addr_received(msk); | ||
121 | - } | ||
122 | -} | ||
123 | - | ||
124 | static int __net_init pm_nl_init_net(struct net *net) | ||
125 | { | ||
126 | struct pm_nl_pernet *pernet = pm_nl_get_pernet(net); | ||
127 | @@ -XXX,XX +XXX,XX @@ static struct pernet_operations mptcp_pm_pernet_ops = { | ||
128 | .size = sizeof(struct pm_nl_pernet), | ||
129 | }; | ||
130 | |||
131 | +static void mptcp_pm_kernel_add_addr_received(struct mptcp_sock *msk) | ||
70 | +{ | 132 | +{ |
71 | + int ret = 0; | 133 | + mptcp_pm_nl_add_addr_received(msk); |
72 | + | ||
73 | + if (mptcp_pm_add_addr_recv(msk)) | ||
74 | + msk->pm.remote = *addr; | ||
75 | + else | ||
76 | + ret = -EINVAL; | ||
77 | + return ret; | ||
78 | +} | 134 | +} |
79 | + | 135 | + |
80 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) | 136 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) |
81 | { | 137 | { |
82 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); | 138 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); |
83 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { | 139 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { |
140 | .get_priority = mptcp_pm_kernel_get_priority, | ||
141 | .established = mptcp_pm_kernel_established, | ||
84 | .subflow_established = mptcp_pm_kernel_subflow_established, | 142 | .subflow_established = mptcp_pm_kernel_subflow_established, |
85 | .allow_new_subflow = mptcp_pm_kernel_allow_new_subflow, | ||
86 | .accept_new_subflow = mptcp_pm_kernel_accept_new_subflow, | ||
87 | + .add_addr_received = mptcp_pm_kernel_add_addr_received, | 143 | + .add_addr_received = mptcp_pm_kernel_add_addr_received, |
88 | .init = mptcp_pm_kernel_init, | 144 | .init = mptcp_pm_kernel_init, |
89 | .name = "kernel", | 145 | .name = "kernel", |
90 | .owner = THIS_MODULE, | 146 | .owner = THIS_MODULE, |
91 | diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h | 147 | diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h |
92 | index XXXXXXX..XXXXXXX 100644 | 148 | index XXXXXXX..XXXXXXX 100644 |
93 | --- a/net/mptcp/protocol.h | 149 | --- a/net/mptcp/protocol.h |
94 | +++ b/net/mptcp/protocol.h | 150 | +++ b/net/mptcp/protocol.h |
95 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk); | 151 | @@ -XXX,XX +XXX,XX @@ void __init mptcp_pm_kernel_register(void); |
96 | bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk); | 152 | void __init mptcp_pm_userspace_register(void); |
97 | void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, | 153 | void __init mptcp_pm_nl_init(void); |
98 | const struct mptcp_subflow_context *subflow); | 154 | void mptcp_pm_worker(struct mptcp_sock *msk); |
99 | +bool mptcp_pm_add_addr_recv(struct mptcp_sock *msk); | 155 | -void __mptcp_pm_kernel_worker(struct mptcp_sock *msk); |
100 | void mptcp_pm_add_addr_received(const struct sock *ssk, | 156 | unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk); |
101 | const struct mptcp_addr_info *addr); | 157 | unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk); |
102 | void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk, | 158 | unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk); |
103 | -- | 159 | -- |
104 | 2.43.0 | 160 | 2.43.0 | diff view generated by jsdifflib |
1 | From: Geliang Tang <tanggeliang@kylinos.cn> | 1 | From: Geliang Tang <tanggeliang@kylinos.cn> |
---|---|---|---|
2 | 2 | ||
3 | This patch adds an optional .rm_addr_received interface for struct | 3 | This patch adds an optional .rm_addr_received interface for struct |
4 | mptcp_pm_ops and invokes it in mptcp_pm_worker() without PM lock. | 4 | mptcp_pm_ops and invokes it in mptcp_pm_rm_addr_or_subflow(). |
5 | Since mptcp_subflow_shutdown() and mptcp_close_ssk() are sleepable | ||
6 | kfuncs, .rm_addr_received interface of BPF PM should be invoked by | ||
7 | __bpf_prog_enter_sleepable(), which can't be invoked under a lock. | ||
8 | This patch unlocks the pm lock before invoking this interface in | ||
9 | mptcp_pm_worker(), while holding this lock in mptcp_pm_rm_addr_recv(). | ||
10 | 5 | ||
11 | Export mptcp_pm_rm_addr_recv() is to allow the MPTCP_PM_RM_ADDR_RECEIVED | 6 | This interface is only implemented in the in-kernel PM as a wrapper |
12 | worker can be invoke from the in-kernel PM. | 7 | of mptcp_pm_nl_rm_addr(). |
13 | |||
14 | With this, mptcp_pm_is_kernel() in mptcp_pm_rm_addr_or_subflow() can be | ||
15 | dropped. | ||
16 | 8 | ||
17 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 9 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
18 | --- | 10 | --- |
19 | include/net/mptcp.h | 1 + | 11 | include/net/mptcp.h | 1 + |
20 | net/mptcp/pm.c | 13 ++++++++++--- | 12 | net/mptcp/pm.c | 4 ++-- |
21 | net/mptcp/pm_kernel.c | 6 ++++++ | 13 | net/mptcp/pm_kernel.c | 6 ++++++ |
22 | net/mptcp/protocol.h | 1 + | 14 | 3 files changed, 9 insertions(+), 2 deletions(-) |
23 | 4 files changed, 18 insertions(+), 3 deletions(-) | ||
24 | 15 | ||
25 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | 16 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h |
26 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
27 | --- a/include/net/mptcp.h | 18 | --- a/include/net/mptcp.h |
28 | +++ b/include/net/mptcp.h | 19 | +++ b/include/net/mptcp.h |
29 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { | 20 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { |
30 | /* optional */ | 21 | void (*established)(struct mptcp_sock *msk); |
31 | int (*add_addr_received)(struct mptcp_sock *msk, | 22 | void (*subflow_established)(struct mptcp_sock *msk); |
32 | const struct mptcp_addr_info *addr); | 23 | void (*add_addr_received)(struct mptcp_sock *msk); |
33 | + void (*rm_addr_received)(struct mptcp_sock *msk); | 24 | + void (*rm_addr_received)(struct mptcp_sock *msk, u8 id); |
34 | 25 | ||
35 | char name[MPTCP_PM_NAME_MAX]; | 26 | char name[MPTCP_PM_NAME_MAX]; |
36 | struct module *owner; | 27 | struct module *owner; |
37 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 28 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
38 | index XXXXXXX..XXXXXXX 100644 | 29 | index XXXXXXX..XXXXXXX 100644 |
... | ... | ||
41 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_rm_addr_or_subflow(struct mptcp_sock *msk, | 32 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_rm_addr_or_subflow(struct mptcp_sock *msk, |
42 | 33 | ||
43 | if (rm_type == MPTCP_MIB_RMADDR) { | 34 | if (rm_type == MPTCP_MIB_RMADDR) { |
44 | __MPTCP_INC_STATS(sock_net(sk), rm_type); | 35 | __MPTCP_INC_STATS(sock_net(sk), rm_type); |
45 | - if (removed && mptcp_pm_is_kernel(msk)) | 36 | - if (removed && mptcp_pm_is_kernel(msk)) |
46 | + if (removed) | 37 | - mptcp_pm_nl_rm_addr(msk, rm_id); |
47 | mptcp_pm_nl_rm_addr(msk, rm_id); | 38 | + if (removed && msk->pm.ops->rm_addr_received) |
39 | + msk->pm.ops->rm_addr_received(msk, rm_id); | ||
48 | } | 40 | } |
49 | } | 41 | } |
50 | } | 42 | } |
51 | |||
52 | -static void mptcp_pm_rm_addr_recv(struct mptcp_sock *msk) | ||
53 | +void mptcp_pm_rm_addr_recv(struct mptcp_sock *msk) | ||
54 | { | ||
55 | + spin_lock_bh(&msk->pm.lock); | ||
56 | mptcp_pm_rm_addr_or_subflow(msk, &msk->pm.rm_list_rx, MPTCP_MIB_RMADDR); | ||
57 | + spin_unlock_bh(&msk->pm.lock); | ||
58 | } | ||
59 | |||
60 | void mptcp_pm_rm_subflow(struct mptcp_sock *msk, | ||
61 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, | ||
62 | for (i = 0; i < rm_list->nr; i++) | ||
63 | mptcp_event_addr_removed(msk, rm_list->ids[i]); | ||
64 | |||
65 | + if (!pm->ops->rm_addr_received) | ||
66 | + return; | ||
67 | + | ||
68 | spin_lock_bh(&pm->lock); | ||
69 | if (mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED)) | ||
70 | pm->rm_list_rx = *rm_list; | ||
71 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_worker(struct mptcp_sock *msk) | ||
72 | } | ||
73 | if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) { | ||
74 | pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED); | ||
75 | - mptcp_pm_rm_addr_recv(msk); | ||
76 | + spin_unlock_bh(&pm->lock); | ||
77 | + pm->ops->rm_addr_received(msk); | ||
78 | + spin_lock_bh(&pm->lock); | ||
79 | } | ||
80 | if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) { | ||
81 | pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); | ||
82 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c | 43 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c |
83 | index XXXXXXX..XXXXXXX 100644 | 44 | index XXXXXXX..XXXXXXX 100644 |
84 | --- a/net/mptcp/pm_kernel.c | 45 | --- a/net/mptcp/pm_kernel.c |
85 | +++ b/net/mptcp/pm_kernel.c | 46 | +++ b/net/mptcp/pm_kernel.c |
86 | @@ -XXX,XX +XXX,XX @@ static int mptcp_pm_kernel_add_addr_received(struct mptcp_sock *msk, | 47 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_kernel_add_addr_received(struct mptcp_sock *msk) |
87 | return ret; | 48 | mptcp_pm_nl_add_addr_received(msk); |
88 | } | 49 | } |
89 | 50 | ||
90 | +static void mptcp_pm_kernel_rm_addr_received(struct mptcp_sock *msk) | 51 | +static void mptcp_pm_kernel_rm_addr_received(struct mptcp_sock *msk, u8 id) |
91 | +{ | 52 | +{ |
92 | + mptcp_pm_rm_addr_recv(msk); | 53 | + mptcp_pm_nl_rm_addr(msk, id); |
93 | +} | 54 | +} |
94 | + | 55 | + |
95 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) | 56 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) |
96 | { | 57 | { |
97 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); | 58 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); |
98 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { | 59 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { |
99 | .accept_new_subflow = mptcp_pm_kernel_accept_new_subflow, | 60 | .established = mptcp_pm_kernel_established, |
100 | .add_addr_echo = mptcp_pm_kernel_add_addr_echo, | 61 | .subflow_established = mptcp_pm_kernel_subflow_established, |
101 | .add_addr_received = mptcp_pm_kernel_add_addr_received, | 62 | .add_addr_received = mptcp_pm_kernel_add_addr_received, |
102 | + .rm_addr_received = mptcp_pm_kernel_rm_addr_received, | 63 | + .rm_addr_received = mptcp_pm_kernel_rm_addr_received, |
103 | .init = mptcp_pm_kernel_init, | 64 | .init = mptcp_pm_kernel_init, |
104 | .name = "kernel", | 65 | .name = "kernel", |
105 | .owner = THIS_MODULE, | 66 | .owner = THIS_MODULE, |
106 | diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h | ||
107 | index XXXXXXX..XXXXXXX 100644 | ||
108 | --- a/net/mptcp/protocol.h | ||
109 | +++ b/net/mptcp/protocol.h | ||
110 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_rm_subflow(struct mptcp_sock *msk, | ||
111 | const struct mptcp_rm_list *rm_list); | ||
112 | void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, | ||
113 | const struct mptcp_rm_list *rm_list); | ||
114 | +void mptcp_pm_rm_addr_recv(struct mptcp_sock *msk); | ||
115 | void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup); | ||
116 | void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq); | ||
117 | int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk, | ||
118 | -- | 67 | -- |
119 | 2.43.0 | 68 | 2.43.0 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
5 | reasonable to add a mandatory .add_addr_echo interface for struct | 5 | reasonable to add a mandatory .add_addr_echo interface for struct |
6 | mptcp_pm_ops. | 6 | mptcp_pm_ops. |
7 | 7 | ||
8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
9 | --- | 9 | --- |
10 | include/net/mptcp.h | 2 ++ | 10 | include/net/mptcp.h | 4 ++++ |
11 | net/mptcp/pm.c | 18 +++++------------- | 11 | net/mptcp/pm.c | 20 +++++++------------- |
12 | net/mptcp/pm_kernel.c | 9 +++++++++ | 12 | net/mptcp/pm_kernel.c | 9 +++++++++ |
13 | net/mptcp/pm_userspace.c | 7 +++++++ | 13 | net/mptcp/pm_userspace.c | 7 +++++++ |
14 | net/mptcp/protocol.h | 2 ++ | 14 | net/mptcp/protocol.h | 2 ++ |
15 | 5 files changed, 25 insertions(+), 13 deletions(-) | 15 | 5 files changed, 29 insertions(+), 13 deletions(-) |
16 | 16 | ||
17 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | 17 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h |
18 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/include/net/mptcp.h | 19 | --- a/include/net/mptcp.h |
20 | +++ b/include/net/mptcp.h | 20 | +++ b/include/net/mptcp.h |
21 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { | 21 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { |
22 | /* required */ | 22 | void (*add_addr_received)(struct mptcp_sock *msk); |
23 | bool (*allow_new_subflow)(struct mptcp_sock *msk); | 23 | void (*rm_addr_received)(struct mptcp_sock *msk, u8 id); |
24 | bool (*accept_new_subflow)(const struct mptcp_sock *msk); | 24 | |
25 | + /* required */ | ||
25 | + bool (*add_addr_echo)(struct mptcp_sock *msk, | 26 | + bool (*add_addr_echo)(struct mptcp_sock *msk, |
26 | + const struct mptcp_addr_info *addr); | 27 | + const struct mptcp_addr_info *addr); |
27 | 28 | + | |
28 | /* optional */ | 29 | char name[MPTCP_PM_NAME_MAX]; |
29 | int (*add_addr_received)(struct mptcp_sock *msk, | 30 | struct module *owner; |
31 | struct list_head list; | ||
30 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 32 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
31 | index XXXXXXX..XXXXXXX 100644 | 33 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/net/mptcp/pm.c | 34 | --- a/net/mptcp/pm.c |
33 | +++ b/net/mptcp/pm.c | 35 | +++ b/net/mptcp/pm.c |
34 | @@ -XXX,XX +XXX,XX @@ void mptcp_remote_address(const struct sock_common *skc, | 36 | @@ -XXX,XX +XXX,XX @@ void mptcp_remote_address(const struct sock_common *skc, |
... | ... | ||
57 | - } else if ((addr->id == 0 && !mptcp_pm_is_init_remote_addr(msk, addr)) || | 59 | - } else if ((addr->id == 0 && !mptcp_pm_is_init_remote_addr(msk, addr)) || |
58 | - (addr->id > 0 && !READ_ONCE(pm->accept_addr))) { | 60 | - (addr->id > 0 && !READ_ONCE(pm->accept_addr))) { |
59 | + if (pm->ops->add_addr_echo(msk, addr)) { | 61 | + if (pm->ops->add_addr_echo(msk, addr)) { |
60 | mptcp_pm_announce_addr(msk, addr, true); | 62 | mptcp_pm_announce_addr(msk, addr, true); |
61 | mptcp_pm_add_addr_send_ack(msk); | 63 | mptcp_pm_add_addr_send_ack(msk); |
62 | } else { | 64 | } else if (pm->ops->add_addr_received) { |
65 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_add_addr_received(const struct sock *ssk, | ||
66 | pm->remote = *addr; | ||
67 | else | ||
68 | ret = -EINVAL; | ||
69 | + } else { | ||
70 | + ret = -EINVAL; | ||
71 | } | ||
72 | |||
73 | if (ret) | ||
63 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name) | 74 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name) |
75 | |||
64 | int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops) | 76 | int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops) |
65 | { | 77 | { |
66 | if (!pm_ops->get_local_id || !pm_ops->get_priority || | 78 | - if (!pm_ops->get_local_id || !pm_ops->get_priority) { |
67 | - !pm_ops->allow_new_subflow || !pm_ops->accept_new_subflow) { | 79 | + if (!pm_ops->get_local_id || !pm_ops->get_priority || |
68 | + !pm_ops->allow_new_subflow || !pm_ops->accept_new_subflow || | ||
69 | + !pm_ops->add_addr_echo) { | 80 | + !pm_ops->add_addr_echo) { |
70 | pr_err("%s does not implement required ops\n", pm_ops->name); | 81 | pr_err("%s does not implement required ops\n", pm_ops->name); |
71 | return -EINVAL; | 82 | return -EINVAL; |
72 | } | 83 | } |
73 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c | 84 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c |
74 | index XXXXXXX..XXXXXXX 100644 | 85 | index XXXXXXX..XXXXXXX 100644 |
75 | --- a/net/mptcp/pm_kernel.c | 86 | --- a/net/mptcp/pm_kernel.c |
76 | +++ b/net/mptcp/pm_kernel.c | 87 | +++ b/net/mptcp/pm_kernel.c |
77 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_kernel_accept_new_subflow(const struct mptcp_sock *msk) | 88 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_kernel_rm_addr_received(struct mptcp_sock *msk, u8 id) |
78 | return READ_ONCE(msk->pm.accept_subflow); | 89 | mptcp_pm_nl_rm_addr(msk, id); |
79 | } | 90 | } |
80 | 91 | ||
81 | +static bool mptcp_pm_kernel_add_addr_echo(struct mptcp_sock *msk, | 92 | +static bool mptcp_pm_kernel_add_addr_echo(struct mptcp_sock *msk, |
82 | + const struct mptcp_addr_info *addr) | 93 | + const struct mptcp_addr_info *addr) |
83 | +{ | 94 | +{ |
84 | + /* id0 should not have a different address */ | 95 | + /* id0 should not have a different address */ |
85 | + return (addr->id == 0 && !mptcp_pm_is_init_remote_addr(msk, addr)) || | 96 | + return (addr->id == 0 && !mptcp_pm_is_init_remote_addr(msk, addr)) || |
86 | + (addr->id > 0 && !READ_ONCE(msk->pm.accept_addr)); | 97 | + (addr->id > 0 && !READ_ONCE(msk->pm.accept_addr)); |
87 | +} | 98 | +} |
88 | + | 99 | + |
89 | static int mptcp_pm_kernel_add_addr_received(struct mptcp_sock *msk, | 100 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) |
90 | const struct mptcp_addr_info *addr) | ||
91 | { | 101 | { |
102 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); | ||
92 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { | 103 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { |
93 | .subflow_established = mptcp_pm_kernel_subflow_established, | 104 | .subflow_established = mptcp_pm_kernel_subflow_established, |
94 | .allow_new_subflow = mptcp_pm_kernel_allow_new_subflow, | 105 | .add_addr_received = mptcp_pm_kernel_add_addr_received, |
95 | .accept_new_subflow = mptcp_pm_kernel_accept_new_subflow, | 106 | .rm_addr_received = mptcp_pm_kernel_rm_addr_received, |
96 | + .add_addr_echo = mptcp_pm_kernel_add_addr_echo, | 107 | + .add_addr_echo = mptcp_pm_kernel_add_addr_echo, |
97 | .add_addr_received = mptcp_pm_kernel_add_addr_received, | ||
98 | .init = mptcp_pm_kernel_init, | 108 | .init = mptcp_pm_kernel_init, |
99 | .name = "kernel", | 109 | .name = "kernel", |
110 | .owner = THIS_MODULE, | ||
100 | diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c | 111 | diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c |
101 | index XXXXXXX..XXXXXXX 100644 | 112 | index XXXXXXX..XXXXXXX 100644 |
102 | --- a/net/mptcp/pm_userspace.c | 113 | --- a/net/mptcp/pm_userspace.c |
103 | +++ b/net/mptcp/pm_userspace.c | 114 | +++ b/net/mptcp/pm_userspace.c |
104 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_userspace_accept_new_subflow(const struct mptcp_sock *msk) | 115 | @@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr, |
105 | return mptcp_userspace_pm_active(msk); | 116 | return ret; |
106 | } | 117 | } |
107 | 118 | ||
108 | +static bool mptcp_pm_userspace_add_addr_echo(struct mptcp_sock *msk, | 119 | +static bool mptcp_pm_userspace_add_addr_echo(struct mptcp_sock *msk, |
109 | + const struct mptcp_addr_info *addr) | 120 | + const struct mptcp_addr_info *addr) |
110 | +{ | 121 | +{ |
111 | + return mptcp_userspace_pm_active(msk); | 122 | + return mptcp_userspace_pm_active(msk); |
112 | +} | 123 | +} |
113 | + | 124 | + |
114 | static void mptcp_pm_userspace_release(struct mptcp_sock *msk) | 125 | static void mptcp_pm_userspace_release(struct mptcp_sock *msk) |
115 | { | 126 | { |
116 | mptcp_userspace_pm_free_local_addr_list(msk); | 127 | mptcp_userspace_pm_free_local_addr_list(msk); |
117 | @@ -XXX,XX +XXX,XX @@ static struct mptcp_pm_ops mptcp_pm_userspace = { | 128 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_userspace_release(struct mptcp_sock *msk) |
129 | static struct mptcp_pm_ops mptcp_pm_userspace = { | ||
130 | .get_local_id = mptcp_pm_userspace_get_local_id, | ||
118 | .get_priority = mptcp_pm_userspace_get_priority, | 131 | .get_priority = mptcp_pm_userspace_get_priority, |
119 | .allow_new_subflow = mptcp_pm_userspace_allow_new_subflow, | ||
120 | .accept_new_subflow = mptcp_pm_userspace_accept_new_subflow, | ||
121 | + .add_addr_echo = mptcp_pm_userspace_add_addr_echo, | 132 | + .add_addr_echo = mptcp_pm_userspace_add_addr_echo, |
122 | .release = mptcp_pm_userspace_release, | 133 | .release = mptcp_pm_userspace_release, |
123 | .name = "userspace", | 134 | .name = "userspace", |
124 | .owner = THIS_MODULE, | 135 | .owner = THIS_MODULE, |
125 | diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h | 136 | diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h |
... | ... | ||
130 | bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk); | 141 | bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk); |
131 | void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, | 142 | void mptcp_pm_subflow_check_next(struct mptcp_sock *msk, |
132 | const struct mptcp_subflow_context *subflow); | 143 | const struct mptcp_subflow_context *subflow); |
133 | +bool mptcp_pm_is_init_remote_addr(struct mptcp_sock *msk, | 144 | +bool mptcp_pm_is_init_remote_addr(struct mptcp_sock *msk, |
134 | + const struct mptcp_addr_info *remote); | 145 | + const struct mptcp_addr_info *remote); |
135 | bool mptcp_pm_add_addr_recv(struct mptcp_sock *msk); | ||
136 | void mptcp_pm_add_addr_received(const struct sock *ssk, | 146 | void mptcp_pm_add_addr_received(const struct sock *ssk, |
137 | const struct mptcp_addr_info *addr); | 147 | const struct mptcp_addr_info *addr); |
148 | void mptcp_pm_add_addr_echoed(struct mptcp_sock *msk, | ||
138 | -- | 149 | -- |
139 | 2.43.0 | 150 | 2.43.0 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
5 | reasonable to add a mandatory .accept_new_subflow interface for struct | 5 | reasonable to add a mandatory .accept_new_subflow interface for struct |
6 | mptcp_pm_ops. | 6 | mptcp_pm_ops. |
7 | 7 | ||
8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
9 | --- | 9 | --- |
10 | include/net/mptcp.h | 1 + | 10 | include/net/mptcp.h | 1 + |
11 | net/mptcp/pm.c | 2 +- | 11 | net/mptcp/pm.c | 31 +++++++++++-------------------- |
12 | net/mptcp/pm_kernel.c | 6 ++++++ | 12 | net/mptcp/pm_kernel.c | 6 ++++++ |
13 | net/mptcp/pm_userspace.c | 6 ++++++ | 13 | net/mptcp/pm_userspace.c | 6 ++++++ |
14 | net/mptcp/subflow.c | 4 +--- | 14 | net/mptcp/subflow.c | 4 +--- |
15 | 5 files changed, 15 insertions(+), 4 deletions(-) | 15 | 5 files changed, 25 insertions(+), 23 deletions(-) |
16 | 16 | ||
17 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | 17 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h |
18 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/include/net/mptcp.h | 19 | --- a/include/net/mptcp.h |
20 | +++ b/include/net/mptcp.h | 20 | +++ b/include/net/mptcp.h |
21 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { | 21 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { |
22 | |||
23 | /* required */ | 22 | /* required */ |
24 | bool (*allow_new_subflow)(struct mptcp_sock *msk); | 23 | bool (*add_addr_echo)(struct mptcp_sock *msk, |
24 | const struct mptcp_addr_info *addr); | ||
25 | + bool (*accept_new_subflow)(const struct mptcp_sock *msk); | 25 | + bool (*accept_new_subflow)(const struct mptcp_sock *msk); |
26 | 26 | ||
27 | char name[MPTCP_PM_NAME_MAX]; | 27 | char name[MPTCP_PM_NAME_MAX]; |
28 | struct module *owner; | 28 | struct module *owner; |
29 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 29 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
30 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
31 | --- a/net/mptcp/pm.c | 31 | --- a/net/mptcp/pm.c |
32 | +++ b/net/mptcp/pm.c | 32 | +++ b/net/mptcp/pm.c |
33 | @@ -XXX,XX +XXX,XX @@ bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk) | ||
34 | { | ||
35 | struct mptcp_pm_data *pm = &msk->pm; | ||
36 | unsigned int subflows_max; | ||
37 | - int ret = 0; | ||
38 | + bool ret = true; | ||
39 | |||
40 | - if (mptcp_pm_is_userspace(msk)) { | ||
41 | - if (mptcp_userspace_pm_active(msk)) { | ||
42 | - spin_lock_bh(&pm->lock); | ||
43 | - pm->subflows++; | ||
44 | - spin_unlock_bh(&pm->lock); | ||
45 | - return true; | ||
46 | - } | ||
47 | + if (!pm->ops->accept_new_subflow(msk)) | ||
48 | return false; | ||
49 | - } | ||
50 | - | ||
51 | - subflows_max = mptcp_pm_get_subflows_max(msk); | ||
52 | |||
53 | - pr_debug("msk=%p subflows=%d max=%d allow=%d\n", msk, pm->subflows, | ||
54 | - subflows_max, READ_ONCE(pm->accept_subflow)); | ||
55 | + spin_lock_bh(&pm->lock); | ||
56 | + if (!mptcp_pm_is_userspace(msk) && READ_ONCE(pm->accept_subflow)) { | ||
57 | + subflows_max = mptcp_pm_get_subflows_max(msk); | ||
58 | |||
59 | - /* try to avoid acquiring the lock below */ | ||
60 | - if (!READ_ONCE(pm->accept_subflow)) | ||
61 | - return false; | ||
62 | + pr_debug("msk=%p subflows=%d max=%d allow=%d\n", msk, pm->subflows, | ||
63 | + subflows_max, READ_ONCE(pm->accept_subflow)); | ||
64 | |||
65 | - spin_lock_bh(&pm->lock); | ||
66 | - if (READ_ONCE(pm->accept_subflow)) { | ||
67 | ret = pm->subflows < subflows_max; | ||
68 | - if (ret && ++pm->subflows == subflows_max) | ||
69 | + if (ret && pm->subflows == subflows_max - 1) | ||
70 | WRITE_ONCE(pm->accept_subflow, false); | ||
71 | } | ||
72 | + if (ret) | ||
73 | + pm->subflows++; | ||
74 | spin_unlock_bh(&pm->lock); | ||
75 | |||
76 | return ret; | ||
33 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name) | 77 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name) |
34 | int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops) | 78 | int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops) |
35 | { | 79 | { |
36 | if (!pm_ops->get_local_id || !pm_ops->get_priority || | 80 | if (!pm_ops->get_local_id || !pm_ops->get_priority || |
37 | - !pm_ops->allow_new_subflow) { | 81 | - !pm_ops->add_addr_echo) { |
38 | + !pm_ops->allow_new_subflow || !pm_ops->accept_new_subflow) { | 82 | + !pm_ops->add_addr_echo || !pm_ops->accept_new_subflow) { |
39 | pr_err("%s does not implement required ops\n", pm_ops->name); | 83 | pr_err("%s does not implement required ops\n", pm_ops->name); |
40 | return -EINVAL; | 84 | return -EINVAL; |
41 | } | 85 | } |
42 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c | 86 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c |
43 | index XXXXXXX..XXXXXXX 100644 | 87 | index XXXXXXX..XXXXXXX 100644 |
44 | --- a/net/mptcp/pm_kernel.c | 88 | --- a/net/mptcp/pm_kernel.c |
45 | +++ b/net/mptcp/pm_kernel.c | 89 | +++ b/net/mptcp/pm_kernel.c |
46 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_kernel_allow_new_subflow(struct mptcp_sock *msk) | 90 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_kernel_add_addr_echo(struct mptcp_sock *msk, |
47 | return ret; | 91 | (addr->id > 0 && !READ_ONCE(msk->pm.accept_addr)); |
48 | } | 92 | } |
49 | 93 | ||
50 | +static bool mptcp_pm_kernel_accept_new_subflow(const struct mptcp_sock *msk) | 94 | +static bool mptcp_pm_kernel_accept_new_subflow(const struct mptcp_sock *msk) |
51 | +{ | 95 | +{ |
52 | + return READ_ONCE(msk->pm.accept_subflow); | 96 | + return READ_ONCE(msk->pm.accept_subflow); |
53 | +} | 97 | +} |
54 | + | 98 | + |
55 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) | 99 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) |
56 | { | 100 | { |
57 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); | 101 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); |
58 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { | 102 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { |
59 | .established = mptcp_pm_kernel_established, | 103 | .add_addr_received = mptcp_pm_kernel_add_addr_received, |
60 | .subflow_established = mptcp_pm_kernel_subflow_established, | 104 | .rm_addr_received = mptcp_pm_kernel_rm_addr_received, |
61 | .allow_new_subflow = mptcp_pm_kernel_allow_new_subflow, | 105 | .add_addr_echo = mptcp_pm_kernel_add_addr_echo, |
62 | + .accept_new_subflow = mptcp_pm_kernel_accept_new_subflow, | 106 | + .accept_new_subflow = mptcp_pm_kernel_accept_new_subflow, |
63 | .init = mptcp_pm_kernel_init, | 107 | .init = mptcp_pm_kernel_init, |
64 | .name = "kernel", | 108 | .name = "kernel", |
65 | .owner = THIS_MODULE, | 109 | .owner = THIS_MODULE, |
66 | diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c | 110 | diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c |
67 | index XXXXXXX..XXXXXXX 100644 | 111 | index XXXXXXX..XXXXXXX 100644 |
68 | --- a/net/mptcp/pm_userspace.c | 112 | --- a/net/mptcp/pm_userspace.c |
69 | +++ b/net/mptcp/pm_userspace.c | 113 | +++ b/net/mptcp/pm_userspace.c |
70 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_userspace_allow_new_subflow(struct mptcp_sock *msk) | 114 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_userspace_add_addr_echo(struct mptcp_sock *msk, |
71 | return false; | 115 | return mptcp_userspace_pm_active(msk); |
72 | } | 116 | } |
73 | 117 | ||
74 | +static bool mptcp_pm_userspace_accept_new_subflow(const struct mptcp_sock *msk) | 118 | +static bool mptcp_pm_userspace_accept_new_subflow(const struct mptcp_sock *msk) |
75 | +{ | 119 | +{ |
76 | + return mptcp_userspace_pm_active(msk); | 120 | + return mptcp_userspace_pm_active(msk); |
... | ... | ||
80 | { | 124 | { |
81 | mptcp_userspace_pm_free_local_addr_list(msk); | 125 | mptcp_userspace_pm_free_local_addr_list(msk); |
82 | @@ -XXX,XX +XXX,XX @@ static struct mptcp_pm_ops mptcp_pm_userspace = { | 126 | @@ -XXX,XX +XXX,XX @@ static struct mptcp_pm_ops mptcp_pm_userspace = { |
83 | .get_local_id = mptcp_pm_userspace_get_local_id, | 127 | .get_local_id = mptcp_pm_userspace_get_local_id, |
84 | .get_priority = mptcp_pm_userspace_get_priority, | 128 | .get_priority = mptcp_pm_userspace_get_priority, |
85 | .allow_new_subflow = mptcp_pm_userspace_allow_new_subflow, | 129 | .add_addr_echo = mptcp_pm_userspace_add_addr_echo, |
86 | + .accept_new_subflow = mptcp_pm_userspace_accept_new_subflow, | 130 | + .accept_new_subflow = mptcp_pm_userspace_accept_new_subflow, |
87 | .release = mptcp_pm_userspace_release, | 131 | .release = mptcp_pm_userspace_release, |
88 | .name = "userspace", | 132 | .name = "userspace", |
89 | .owner = THIS_MODULE, | 133 | .owner = THIS_MODULE, |
90 | diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c | 134 | diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c |
... | ... | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
5 | reasonable to add a mandatory .allow_new_subflow interface for struct | 5 | reasonable to add a mandatory .allow_new_subflow interface for struct |
6 | mptcp_pm_ops. | 6 | mptcp_pm_ops. |
7 | 7 | ||
8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> | 8 | Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn> |
9 | --- | 9 | --- |
10 | include/net/mptcp.h | 3 +++ | 10 | include/net/mptcp.h | 3 +++ |
11 | net/mptcp/pm.c | 36 +++--------------------------------- | 11 | net/mptcp/pm.c | 13 ++----------- |
12 | net/mptcp/pm_kernel.c | 27 +++++++++++++++++++++++++++ | 12 | net/mptcp/pm_kernel.c | 21 +++++++++++++++++++++ |
13 | net/mptcp/pm_userspace.c | 14 ++++++++++++++ | 13 | 3 files changed, 26 insertions(+), 11 deletions(-) |
14 | 4 files changed, 47 insertions(+), 33 deletions(-) | ||
15 | 14 | ||
16 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h | 15 | diff --git a/include/net/mptcp.h b/include/net/mptcp.h |
17 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/include/net/mptcp.h | 17 | --- a/include/net/mptcp.h |
19 | +++ b/include/net/mptcp.h | 18 | +++ b/include/net/mptcp.h |
20 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { | 19 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops { |
21 | void (*established)(struct mptcp_sock *msk); | 20 | const struct mptcp_addr_info *addr); |
22 | void (*subflow_established)(struct mptcp_sock *msk); | 21 | bool (*accept_new_subflow)(const struct mptcp_sock *msk); |
23 | 22 | ||
24 | + /* required */ | 23 | + /* optional */ |
25 | + bool (*allow_new_subflow)(struct mptcp_sock *msk); | 24 | + bool (*allow_new_subflow)(struct mptcp_sock *msk); |
26 | + | 25 | + |
27 | char name[MPTCP_PM_NAME_MAX]; | 26 | char name[MPTCP_PM_NAME_MAX]; |
28 | struct module *owner; | 27 | struct module *owner; |
29 | struct list_head list; | 28 | struct list_head list; |
30 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c | 29 | diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c |
31 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/net/mptcp/pm.c | 31 | --- a/net/mptcp/pm.c |
33 | +++ b/net/mptcp/pm.c | 32 | +++ b/net/mptcp/pm.c |
34 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int | 33 | @@ -XXX,XX +XXX,XX @@ void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int |
35 | |||
36 | bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk) | 34 | bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk) |
37 | { | 35 | { |
38 | - struct mptcp_pm_data *pm = &msk->pm; | 36 | struct mptcp_pm_data *pm = &msk->pm; |
39 | - unsigned int subflows_max; | 37 | - unsigned int subflows_max; |
40 | - int ret = 0; | 38 | bool ret = true; |
39 | |||
40 | if (!pm->ops->accept_new_subflow(msk)) | ||
41 | return false; | ||
42 | |||
43 | spin_lock_bh(&pm->lock); | ||
44 | - if (!mptcp_pm_is_userspace(msk) && READ_ONCE(pm->accept_subflow)) { | ||
45 | - subflows_max = mptcp_pm_get_subflows_max(msk); | ||
41 | - | 46 | - |
42 | - if (mptcp_pm_is_userspace(msk)) { | 47 | - pr_debug("msk=%p subflows=%d max=%d allow=%d\n", msk, pm->subflows, |
43 | - if (mptcp_userspace_pm_active(msk)) { | 48 | - subflows_max, READ_ONCE(pm->accept_subflow)); |
44 | - spin_lock_bh(&pm->lock); | ||
45 | - pm->subflows++; | ||
46 | - spin_unlock_bh(&pm->lock); | ||
47 | - return true; | ||
48 | - } | ||
49 | - return false; | ||
50 | - } | ||
51 | - | 49 | - |
52 | - subflows_max = mptcp_pm_get_subflows_max(msk); | ||
53 | - | ||
54 | - pr_debug("msk=%p subflows=%d max=%d allow=%d\n", msk, pm->subflows, | ||
55 | - subflows_max, READ_ONCE(pm->accept_subflow)); | ||
56 | - | ||
57 | - /* try to avoid acquiring the lock below */ | ||
58 | - if (!READ_ONCE(pm->accept_subflow)) | ||
59 | - return false; | ||
60 | - | ||
61 | - spin_lock_bh(&pm->lock); | ||
62 | - if (READ_ONCE(pm->accept_subflow)) { | ||
63 | - ret = pm->subflows < subflows_max; | 50 | - ret = pm->subflows < subflows_max; |
64 | - if (ret && ++pm->subflows == subflows_max) | 51 | - if (ret && pm->subflows == subflows_max - 1) |
65 | - WRITE_ONCE(pm->accept_subflow, false); | 52 | - WRITE_ONCE(pm->accept_subflow, false); |
66 | - } | 53 | - } |
67 | - spin_unlock_bh(&pm->lock); | 54 | + if (pm->ops->allow_new_subflow) |
68 | - | 55 | + ret = pm->ops->allow_new_subflow(msk); |
69 | - return ret; | 56 | if (ret) |
70 | + return msk->pm.ops->allow_new_subflow(msk); | 57 | pm->subflows++; |
71 | } | 58 | spin_unlock_bh(&pm->lock); |
72 | |||
73 | /* return true if the new status bit is currently cleared, that is, this event | ||
74 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops *mptcp_pm_find(const char *name) | ||
75 | |||
76 | int mptcp_pm_validate(struct mptcp_pm_ops *pm_ops) | ||
77 | { | ||
78 | - if (!pm_ops->get_local_id || !pm_ops->get_priority) { | ||
79 | + if (!pm_ops->get_local_id || !pm_ops->get_priority || | ||
80 | + !pm_ops->allow_new_subflow) { | ||
81 | pr_err("%s does not implement required ops\n", pm_ops->name); | ||
82 | return -EINVAL; | ||
83 | } | ||
84 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c | 59 | diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c |
85 | index XXXXXXX..XXXXXXX 100644 | 60 | index XXXXXXX..XXXXXXX 100644 |
86 | --- a/net/mptcp/pm_kernel.c | 61 | --- a/net/mptcp/pm_kernel.c |
87 | +++ b/net/mptcp/pm_kernel.c | 62 | +++ b/net/mptcp/pm_kernel.c |
88 | @@ -XXX,XX +XXX,XX @@ static struct pernet_operations mptcp_pm_pernet_ops = { | 63 | @@ -XXX,XX +XXX,XX @@ static bool mptcp_pm_kernel_accept_new_subflow(const struct mptcp_sock *msk) |
89 | .size = sizeof(struct pm_nl_pernet), | 64 | return READ_ONCE(msk->pm.accept_subflow); |
90 | }; | 65 | } |
91 | 66 | ||
92 | +static bool mptcp_pm_kernel_allow_new_subflow(struct mptcp_sock *msk) | 67 | +static bool mptcp_pm_kernel_allow_new_subflow(struct mptcp_sock *msk) |
93 | +{ | 68 | +{ |
94 | + struct mptcp_pm_data *pm = &msk->pm; | 69 | + struct mptcp_pm_data *pm = &msk->pm; |
95 | + unsigned int subflows_max; | 70 | + unsigned int subflows_max; |
96 | + int ret = 0; | 71 | + bool ret = false; |
97 | + | 72 | + |
98 | + subflows_max = mptcp_pm_get_subflows_max(msk); | 73 | + subflows_max = mptcp_pm_get_subflows_max(msk); |
99 | + | 74 | + |
100 | + pr_debug("msk=%p subflows=%d max=%d allow=%d\n", msk, pm->subflows, | 75 | + pr_debug("msk=%p subflows=%d max=%d allow=%d\n", msk, pm->subflows, |
101 | + subflows_max, READ_ONCE(pm->accept_subflow)); | 76 | + subflows_max, READ_ONCE(pm->accept_subflow)); |
102 | + | 77 | + |
103 | + /* try to avoid acquiring the lock below */ | ||
104 | + if (!READ_ONCE(pm->accept_subflow)) | ||
105 | + return false; | ||
106 | + | ||
107 | + spin_lock_bh(&pm->lock); | ||
108 | + if (READ_ONCE(pm->accept_subflow)) { | 78 | + if (READ_ONCE(pm->accept_subflow)) { |
109 | + ret = pm->subflows < subflows_max; | 79 | + ret = pm->subflows < subflows_max; |
110 | + if (ret && ++pm->subflows == subflows_max) | 80 | + if (ret && pm->subflows == subflows_max - 1) |
111 | + WRITE_ONCE(pm->accept_subflow, false); | 81 | + WRITE_ONCE(pm->accept_subflow, false); |
112 | + } | 82 | + } |
113 | + spin_unlock_bh(&pm->lock); | ||
114 | + | 83 | + |
115 | + return ret; | 84 | + return ret; |
116 | +} | 85 | +} |
117 | + | 86 | + |
118 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) | 87 | static void mptcp_pm_kernel_init(struct mptcp_sock *msk) |
119 | { | 88 | { |
120 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); | 89 | bool subflows_allowed = !!mptcp_pm_get_subflows_max(msk); |
121 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { | 90 | @@ -XXX,XX +XXX,XX @@ struct mptcp_pm_ops mptcp_pm_kernel = { |
122 | .get_priority = mptcp_pm_kernel_get_priority, | 91 | .rm_addr_received = mptcp_pm_kernel_rm_addr_received, |
123 | .established = mptcp_pm_kernel_established, | 92 | .add_addr_echo = mptcp_pm_kernel_add_addr_echo, |
124 | .subflow_established = mptcp_pm_kernel_subflow_established, | 93 | .accept_new_subflow = mptcp_pm_kernel_accept_new_subflow, |
125 | + .allow_new_subflow = mptcp_pm_kernel_allow_new_subflow, | 94 | + .allow_new_subflow = mptcp_pm_kernel_allow_new_subflow, |
126 | .init = mptcp_pm_kernel_init, | 95 | .init = mptcp_pm_kernel_init, |
127 | .name = "kernel", | 96 | .name = "kernel", |
128 | .owner = THIS_MODULE, | 97 | .owner = THIS_MODULE, |
129 | diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c | ||
130 | index XXXXXXX..XXXXXXX 100644 | ||
131 | --- a/net/mptcp/pm_userspace.c | ||
132 | +++ b/net/mptcp/pm_userspace.c | ||
133 | @@ -XXX,XX +XXX,XX @@ int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr, | ||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | +static bool mptcp_pm_userspace_allow_new_subflow(struct mptcp_sock *msk) | ||
138 | +{ | ||
139 | + struct mptcp_pm_data *pm = &msk->pm; | ||
140 | + | ||
141 | + if (mptcp_userspace_pm_active(msk)) { | ||
142 | + spin_lock_bh(&pm->lock); | ||
143 | + pm->subflows++; | ||
144 | + spin_unlock_bh(&pm->lock); | ||
145 | + return true; | ||
146 | + } | ||
147 | + return false; | ||
148 | +} | ||
149 | + | ||
150 | static void mptcp_pm_userspace_release(struct mptcp_sock *msk) | ||
151 | { | ||
152 | mptcp_userspace_pm_free_local_addr_list(msk); | ||
153 | @@ -XXX,XX +XXX,XX @@ static void mptcp_pm_userspace_release(struct mptcp_sock *msk) | ||
154 | static struct mptcp_pm_ops mptcp_pm_userspace = { | ||
155 | .get_local_id = mptcp_pm_userspace_get_local_id, | ||
156 | .get_priority = mptcp_pm_userspace_get_priority, | ||
157 | + .allow_new_subflow = mptcp_pm_userspace_allow_new_subflow, | ||
158 | .release = mptcp_pm_userspace_release, | ||
159 | .name = "userspace", | ||
160 | .owner = THIS_MODULE, | ||
161 | -- | 98 | -- |
162 | 2.43.0 | 99 | 2.43.0 | diff view generated by jsdifflib |