Skip to content

Commit 67b0c1a

Browse files
w1ldptrdavem330
authored andcommitted
net: sched: act_pedit: remove dependency on rtnl lock
Rearrange pedit init code to only access pedit action data while holding tcf spinlock. Change keys allocation type to atomic to allow it to execute while holding tcf spinlock. Take tcf spinlock in dump function when accessing pedit action data. Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ff25276 commit 67b0c1a

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

net/sched/act_pedit.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -187,51 +187,48 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
187187
tcf_idr_cleanup(tn, parm->index);
188188
goto out_free;
189189
}
190-
p = to_pedit(*a);
191-
keys = kmalloc(ksize, GFP_KERNEL);
192-
if (!keys) {
193-
tcf_idr_release(*a, bind);
194-
ret = -ENOMEM;
195-
goto out_free;
196-
}
197190
ret = ACT_P_CREATED;
198191
} else if (err > 0) {
199192
if (bind)
200193
goto out_free;
201194
if (!ovr) {
202-
tcf_idr_release(*a, bind);
203195
ret = -EEXIST;
204-
goto out_free;
205-
}
206-
p = to_pedit(*a);
207-
if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) {
208-
keys = kmalloc(ksize, GFP_KERNEL);
209-
if (!keys) {
210-
ret = -ENOMEM;
211-
goto out_free;
212-
}
196+
goto out_release;
213197
}
214198
} else {
215199
return err;
216200
}
217201

202+
p = to_pedit(*a);
218203
spin_lock_bh(&p->tcf_lock);
219-
p->tcfp_flags = parm->flags;
220-
p->tcf_action = parm->action;
221-
if (keys) {
204+
205+
if (ret == ACT_P_CREATED ||
206+
(p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys)) {
207+
keys = kmalloc(ksize, GFP_ATOMIC);
208+
if (!keys) {
209+
spin_unlock_bh(&p->tcf_lock);
210+
ret = -ENOMEM;
211+
goto out_release;
212+
}
222213
kfree(p->tcfp_keys);
223214
p->tcfp_keys = keys;
224215
p->tcfp_nkeys = parm->nkeys;
225216
}
226217
memcpy(p->tcfp_keys, parm->keys, ksize);
227218

219+
p->tcfp_flags = parm->flags;
220+
p->tcf_action = parm->action;
221+
228222
kfree(p->tcfp_keys_ex);
229223
p->tcfp_keys_ex = keys_ex;
230224

231225
spin_unlock_bh(&p->tcf_lock);
232226
if (ret == ACT_P_CREATED)
233227
tcf_idr_insert(tn, *a);
234228
return ret;
229+
230+
out_release:
231+
tcf_idr_release(*a, bind);
235232
out_free:
236233
kfree(keys_ex);
237234
return ret;
@@ -410,6 +407,7 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
410407
if (unlikely(!opt))
411408
return -ENOBUFS;
412409

410+
spin_lock_bh(&p->tcf_lock);
413411
memcpy(opt->keys, p->tcfp_keys,
414412
p->tcfp_nkeys * sizeof(struct tc_pedit_key));
415413
opt->index = p->tcf_index;
@@ -432,11 +430,13 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
432430
tcf_tm_dump(&t, &p->tcf_tm);
433431
if (nla_put_64bit(skb, TCA_PEDIT_TM, sizeof(t), &t, TCA_PEDIT_PAD))
434432
goto nla_put_failure;
433+
spin_unlock_bh(&p->tcf_lock);
435434

436435
kfree(opt);
437436
return skb->len;
438437

439438
nla_put_failure:
439+
spin_unlock_bh(&p->tcf_lock);
440440
nlmsg_trim(skb, b);
441441
kfree(opt);
442442
return -1;

0 commit comments

Comments
 (0)