Skip to content

Commit cae6925

Browse files
committed
Merge branch 'qualcomm-rmnet-Fix-issues-with-CONFIG_DEBUG_PREEMPT-enabled'
Subash Abhinov Kasiviswanathan says: ==================== net: qualcomm: rmnet: Fix issues with CONFIG_DEBUG_PREEMPT enabled Patch 1 and 2 fixes issues identified when CONFIG_DEBUG_PREEMPT was enabled. These involve APIs which were called in invalid contexts. Patch 3 is a null derefence fix identified by code inspection. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 9ab2323 + f57bbaa commit cae6925

File tree

3 files changed

+20
-55
lines changed

3 files changed

+20
-55
lines changed

drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c

Lines changed: 14 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@
4343

4444
/* Local Definitions and Declarations */
4545

46-
struct rmnet_walk_data {
47-
struct net_device *real_dev;
48-
struct list_head *head;
49-
struct rmnet_port *port;
50-
};
51-
5246
static int rmnet_is_real_dev_registered(const struct net_device *real_dev)
5347
{
5448
return rcu_access_pointer(real_dev->rx_handler) == rmnet_rx_handler;
@@ -112,17 +106,14 @@ static int rmnet_register_real_device(struct net_device *real_dev)
112106
static void rmnet_unregister_bridge(struct net_device *dev,
113107
struct rmnet_port *port)
114108
{
115-
struct net_device *rmnet_dev, *bridge_dev;
116109
struct rmnet_port *bridge_port;
110+
struct net_device *bridge_dev;
117111

118112
if (port->rmnet_mode != RMNET_EPMODE_BRIDGE)
119113
return;
120114

121115
/* bridge slave handling */
122116
if (!port->nr_rmnet_devs) {
123-
rmnet_dev = netdev_master_upper_dev_get_rcu(dev);
124-
netdev_upper_dev_unlink(dev, rmnet_dev);
125-
126117
bridge_dev = port->bridge_ep;
127118

128119
bridge_port = rmnet_get_port_rtnl(bridge_dev);
@@ -132,9 +123,6 @@ static void rmnet_unregister_bridge(struct net_device *dev,
132123
bridge_dev = port->bridge_ep;
133124

134125
bridge_port = rmnet_get_port_rtnl(bridge_dev);
135-
rmnet_dev = netdev_master_upper_dev_get_rcu(bridge_dev);
136-
netdev_upper_dev_unlink(bridge_dev, rmnet_dev);
137-
138126
rmnet_unregister_real_device(bridge_dev, bridge_port);
139127
}
140128
}
@@ -173,10 +161,6 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
173161
if (err)
174162
goto err1;
175163

176-
err = netdev_master_upper_dev_link(dev, real_dev, NULL, NULL, extack);
177-
if (err)
178-
goto err2;
179-
180164
port->rmnet_mode = mode;
181165

182166
hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
@@ -193,8 +177,6 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
193177

194178
return 0;
195179

196-
err2:
197-
rmnet_vnd_dellink(mux_id, port, ep);
198180
err1:
199181
rmnet_unregister_real_device(real_dev, port);
200182
err0:
@@ -204,22 +186,20 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
204186

205187
static void rmnet_dellink(struct net_device *dev, struct list_head *head)
206188
{
189+
struct rmnet_priv *priv = netdev_priv(dev);
207190
struct net_device *real_dev;
208191
struct rmnet_endpoint *ep;
209192
struct rmnet_port *port;
210193
u8 mux_id;
211194

212-
rcu_read_lock();
213-
real_dev = netdev_master_upper_dev_get_rcu(dev);
214-
rcu_read_unlock();
195+
real_dev = priv->real_dev;
215196

216197
if (!real_dev || !rmnet_is_real_dev_registered(real_dev))
217198
return;
218199

219200
port = rmnet_get_port_rtnl(real_dev);
220201

221202
mux_id = rmnet_vnd_get_mux(dev);
222-
netdev_upper_dev_unlink(dev, real_dev);
223203

224204
ep = rmnet_get_endpoint(port, mux_id);
225205
if (ep) {
@@ -233,47 +213,33 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head)
233213
unregister_netdevice_queue(dev, head);
234214
}
235215

236-
static int rmnet_dev_walk_unreg(struct net_device *rmnet_dev, void *data)
237-
{
238-
struct rmnet_walk_data *d = data;
239-
struct rmnet_endpoint *ep;
240-
u8 mux_id;
241-
242-
mux_id = rmnet_vnd_get_mux(rmnet_dev);
243-
ep = rmnet_get_endpoint(d->port, mux_id);
244-
if (ep) {
245-
hlist_del_init_rcu(&ep->hlnode);
246-
rmnet_vnd_dellink(mux_id, d->port, ep);
247-
kfree(ep);
248-
}
249-
netdev_upper_dev_unlink(rmnet_dev, d->real_dev);
250-
unregister_netdevice_queue(rmnet_dev, d->head);
251-
252-
return 0;
253-
}
254-
255216
static void rmnet_force_unassociate_device(struct net_device *dev)
256217
{
257218
struct net_device *real_dev = dev;
258-
struct rmnet_walk_data d;
219+
struct hlist_node *tmp_ep;
220+
struct rmnet_endpoint *ep;
259221
struct rmnet_port *port;
222+
unsigned long bkt_ep;
260223
LIST_HEAD(list);
261224

262225
if (!rmnet_is_real_dev_registered(real_dev))
263226
return;
264227

265228
ASSERT_RTNL();
266229

267-
d.real_dev = real_dev;
268-
d.head = &list;
269-
270230
port = rmnet_get_port_rtnl(dev);
271-
d.port = port;
272231

273232
rcu_read_lock();
274233
rmnet_unregister_bridge(dev, port);
275234

276-
netdev_walk_all_lower_dev_rcu(real_dev, rmnet_dev_walk_unreg, &d);
235+
hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
236+
unregister_netdevice_queue(ep->egress_dev, &list);
237+
rmnet_vnd_dellink(ep->mux_id, port, ep);
238+
239+
hlist_del_init_rcu(&ep->hlnode);
240+
kfree(ep);
241+
}
242+
277243
rcu_read_unlock();
278244
unregister_netdevice_many(&list);
279245

@@ -422,11 +388,6 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,
422388
if (err)
423389
return -EBUSY;
424390

425-
err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL,
426-
extack);
427-
if (err)
428-
return -EINVAL;
429-
430391
slave_port = rmnet_get_port(slave_dev);
431392
slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE;
432393
slave_port->bridge_ep = real_dev;
@@ -449,7 +410,6 @@ int rmnet_del_bridge(struct net_device *rmnet_dev,
449410
port->rmnet_mode = RMNET_EPMODE_VND;
450411
port->bridge_ep = NULL;
451412

452-
netdev_upper_dev_unlink(slave_dev, rmnet_dev);
453413
slave_port = rmnet_get_port(slave_dev);
454414
rmnet_unregister_real_device(slave_dev, slave_port);
455415

drivers/net/ethernet/qualcomm/rmnet/rmnet_map_command.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ static u8 rmnet_map_do_flow_control(struct sk_buff *skb,
3838
}
3939

4040
ep = rmnet_get_endpoint(port, mux_id);
41+
if (!ep) {
42+
kfree_skb(skb);
43+
return RX_HANDLER_CONSUMED;
44+
}
45+
4146
vnd = ep->egress_dev;
4247

4348
ip_family = cmd->flow_control.ip_family;

drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static void rmnet_get_stats64(struct net_device *dev,
121121
memset(&total_stats, 0, sizeof(struct rmnet_vnd_stats));
122122

123123
for_each_possible_cpu(cpu) {
124-
pcpu_ptr = this_cpu_ptr(priv->pcpu_stats);
124+
pcpu_ptr = per_cpu_ptr(priv->pcpu_stats, cpu);
125125

126126
do {
127127
start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp);

0 commit comments

Comments
 (0)