@@ -80,11 +80,13 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
80
80
}
81
81
s = to_sample (* a );
82
82
83
+ spin_lock (& s -> tcf_lock );
83
84
s -> tcf_action = parm -> action ;
84
85
s -> rate = nla_get_u32 (tb [TCA_SAMPLE_RATE ]);
85
86
s -> psample_group_num = nla_get_u32 (tb [TCA_SAMPLE_PSAMPLE_GROUP ]);
86
87
psample_group = psample_group_get (net , s -> psample_group_num );
87
88
if (!psample_group ) {
89
+ spin_unlock (& s -> tcf_lock );
88
90
tcf_idr_release (* a , bind );
89
91
return - ENOMEM ;
90
92
}
@@ -94,6 +96,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
94
96
s -> truncate = true;
95
97
s -> trunc_size = nla_get_u32 (tb [TCA_SAMPLE_TRUNC_SIZE ]);
96
98
}
99
+ spin_unlock (& s -> tcf_lock );
97
100
98
101
if (ret == ACT_P_CREATED )
99
102
tcf_idr_insert (tn , * a );
@@ -105,7 +108,8 @@ static void tcf_sample_cleanup(struct tc_action *a)
105
108
struct tcf_sample * s = to_sample (a );
106
109
struct psample_group * psample_group ;
107
110
108
- psample_group = rtnl_dereference (s -> psample_group );
111
+ /* last reference to action, no need to lock */
112
+ psample_group = rcu_dereference_protected (s -> psample_group , 1 );
109
113
RCU_INIT_POINTER (s -> psample_group , NULL );
110
114
if (psample_group )
111
115
psample_group_put (psample_group );
@@ -174,12 +178,13 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
174
178
struct tcf_sample * s = to_sample (a );
175
179
struct tc_sample opt = {
176
180
.index = s -> tcf_index ,
177
- .action = s -> tcf_action ,
178
181
.refcnt = refcount_read (& s -> tcf_refcnt ) - ref ,
179
182
.bindcnt = atomic_read (& s -> tcf_bindcnt ) - bind ,
180
183
};
181
184
struct tcf_t t ;
182
185
186
+ spin_lock (& s -> tcf_lock );
187
+ opt .action = s -> tcf_action ;
183
188
if (nla_put (skb , TCA_SAMPLE_PARMS , sizeof (opt ), & opt ))
184
189
goto nla_put_failure ;
185
190
@@ -196,9 +201,12 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
196
201
197
202
if (nla_put_u32 (skb , TCA_SAMPLE_PSAMPLE_GROUP , s -> psample_group_num ))
198
203
goto nla_put_failure ;
204
+ spin_unlock (& s -> tcf_lock );
205
+
199
206
return skb -> len ;
200
207
201
208
nla_put_failure :
209
+ spin_unlock (& s -> tcf_lock );
202
210
nlmsg_trim (skb , b );
203
211
return -1 ;
204
212
}
0 commit comments