Skip to content

Commit 3352e6c

Browse files
Subash Abhinov Kasiviswanathandavem330
authored andcommitted
net: qualcomm: rmnet: Convert the muxed endpoint to hlist
Rather than using a static array, use a hlist to store the muxed endpoints and use the mux id to query the rmnet_device. This is useful as usually very few mux ids are used. Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> Cc: Dan Williams <dcbw@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5451237 commit 3352e6c

File tree

6 files changed

+68
-53
lines changed

6 files changed

+68
-53
lines changed

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

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,6 @@ rmnet_get_port_rtnl(const struct net_device *real_dev)
6161
return rtnl_dereference(real_dev->rx_handler_data);
6262
}
6363

64-
static struct rmnet_endpoint*
65-
rmnet_get_endpoint(struct net_device *dev, int config_id)
66-
{
67-
struct rmnet_endpoint *ep;
68-
struct rmnet_port *port;
69-
70-
port = rmnet_get_port_rtnl(dev);
71-
ep = &port->muxed_ep[config_id];
72-
73-
return ep;
74-
}
75-
7664
static int rmnet_unregister_real_device(struct net_device *real_dev,
7765
struct rmnet_port *port)
7866
{
@@ -93,7 +81,7 @@ static int rmnet_unregister_real_device(struct net_device *real_dev,
9381
static int rmnet_register_real_device(struct net_device *real_dev)
9482
{
9583
struct rmnet_port *port;
96-
int rc;
84+
int rc, entry;
9785

9886
ASSERT_RTNL();
9987

@@ -114,26 +102,13 @@ static int rmnet_register_real_device(struct net_device *real_dev)
114102
/* hold on to real dev for MAP data */
115103
dev_hold(real_dev);
116104

105+
for (entry = 0; entry < RMNET_MAX_LOGICAL_EP; entry++)
106+
INIT_HLIST_HEAD(&port->muxed_ep[entry]);
107+
117108
netdev_dbg(real_dev, "registered with rmnet\n");
118109
return 0;
119110
}
120111

121-
static void rmnet_set_endpoint_config(struct net_device *dev,
122-
u8 mux_id, struct net_device *egress_dev)
123-
{
124-
struct rmnet_endpoint *ep;
125-
126-
netdev_dbg(dev, "id %d dev %s\n", mux_id, egress_dev->name);
127-
128-
ep = rmnet_get_endpoint(dev, mux_id);
129-
/* This config is cleared on every set, so its ok to not
130-
* clear it on a device delete.
131-
*/
132-
memset(ep, 0, sizeof(struct rmnet_endpoint));
133-
ep->egress_dev = egress_dev;
134-
ep->mux_id = mux_id;
135-
}
136-
137112
static int rmnet_newlink(struct net *src_net, struct net_device *dev,
138113
struct nlattr *tb[], struct nlattr *data[],
139114
struct netlink_ext_ack *extack)
@@ -145,6 +120,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
145120
RMNET_EGRESS_FORMAT_MAP;
146121
struct net_device *real_dev;
147122
int mode = RMNET_EPMODE_VND;
123+
struct rmnet_endpoint *ep;
148124
struct rmnet_port *port;
149125
int err = 0;
150126
u16 mux_id;
@@ -156,14 +132,18 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
156132
if (!data[IFLA_VLAN_ID])
157133
return -EINVAL;
158134

135+
ep = kzalloc(sizeof(*ep), GFP_ATOMIC);
136+
if (!ep)
137+
return -ENOMEM;
138+
159139
mux_id = nla_get_u16(data[IFLA_VLAN_ID]);
160140

161141
err = rmnet_register_real_device(real_dev);
162142
if (err)
163143
goto err0;
164144

165145
port = rmnet_get_port_rtnl(real_dev);
166-
err = rmnet_vnd_newlink(mux_id, dev, port, real_dev);
146+
err = rmnet_vnd_newlink(mux_id, dev, port, real_dev, ep);
167147
if (err)
168148
goto err1;
169149

@@ -177,11 +157,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
177157
port->ingress_data_format = ingress_format;
178158
port->rmnet_mode = mode;
179159

180-
rmnet_set_endpoint_config(real_dev, mux_id, dev);
160+
hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]);
181161
return 0;
182162

183163
err2:
184-
rmnet_vnd_dellink(mux_id, port);
164+
rmnet_vnd_dellink(mux_id, port, ep);
185165
err1:
186166
rmnet_unregister_real_device(real_dev, port);
187167
err0:
@@ -191,6 +171,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
191171
static void rmnet_dellink(struct net_device *dev, struct list_head *head)
192172
{
193173
struct net_device *real_dev;
174+
struct rmnet_endpoint *ep;
194175
struct rmnet_port *port;
195176
u8 mux_id;
196177

@@ -204,8 +185,15 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head)
204185
port = rmnet_get_port_rtnl(real_dev);
205186

206187
mux_id = rmnet_vnd_get_mux(dev);
207-
rmnet_vnd_dellink(mux_id, port);
208188
netdev_upper_dev_unlink(dev, real_dev);
189+
190+
ep = rmnet_get_endpoint(port, mux_id);
191+
if (ep) {
192+
hlist_del_init_rcu(&ep->hlnode);
193+
rmnet_vnd_dellink(mux_id, port, ep);
194+
kfree(ep);
195+
}
196+
209197
rmnet_unregister_real_device(real_dev, port);
210198

211199
unregister_netdevice_queue(dev, head);
@@ -214,11 +202,16 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head)
214202
static int rmnet_dev_walk_unreg(struct net_device *rmnet_dev, void *data)
215203
{
216204
struct rmnet_walk_data *d = data;
205+
struct rmnet_endpoint *ep;
217206
u8 mux_id;
218207

219208
mux_id = rmnet_vnd_get_mux(rmnet_dev);
220-
221-
rmnet_vnd_dellink(mux_id, d->port);
209+
ep = rmnet_get_endpoint(d->port, mux_id);
210+
if (ep) {
211+
hlist_del_init_rcu(&ep->hlnode);
212+
rmnet_vnd_dellink(mux_id, d->port, ep);
213+
kfree(ep);
214+
}
222215
netdev_upper_dev_unlink(rmnet_dev, d->real_dev);
223216
unregister_netdevice_queue(rmnet_dev, d->head);
224217

@@ -316,6 +309,18 @@ struct rmnet_port *rmnet_get_port(struct net_device *real_dev)
316309
return NULL;
317310
}
318311

312+
struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id)
313+
{
314+
struct rmnet_endpoint *ep;
315+
316+
hlist_for_each_entry_rcu(ep, &port->muxed_ep[mux_id], hlnode) {
317+
if (ep->mux_id == mux_id)
318+
return ep;
319+
}
320+
321+
return NULL;
322+
}
323+
319324
/* Startup/Shutdown */
320325

321326
static int __init rmnet_init(void)

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,19 @@
2323
struct rmnet_endpoint {
2424
u8 mux_id;
2525
struct net_device *egress_dev;
26+
struct hlist_node hlnode;
2627
};
2728

2829
/* One instance of this structure is instantiated for each real_dev associated
2930
* with rmnet.
3031
*/
3132
struct rmnet_port {
3233
struct net_device *dev;
33-
struct rmnet_endpoint muxed_ep[RMNET_MAX_LOGICAL_EP];
3434
u32 ingress_data_format;
3535
u32 egress_data_format;
3636
u8 nr_rmnet_devs;
3737
u8 rmnet_mode;
38+
struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP];
3839
};
3940

4041
extern struct rtnl_link_ops rmnet_link_ops;
@@ -45,5 +46,6 @@ struct rmnet_priv {
4546
};
4647

4748
struct rmnet_port *rmnet_get_port(struct net_device *real_dev);
49+
struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id);
4850

4951
#endif /* _RMNET_CONFIG_H_ */

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,18 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
7171
& RMNET_INGRESS_FORMAT_MAP_COMMANDS)
7272
return rmnet_map_command(skb, port);
7373

74-
kfree_skb(skb);
75-
return RX_HANDLER_CONSUMED;
74+
goto free_skb;
7675
}
7776

7877
mux_id = RMNET_MAP_GET_MUX_ID(skb);
7978
len = RMNET_MAP_GET_LENGTH(skb) - RMNET_MAP_GET_PAD(skb);
8079

81-
if (mux_id >= RMNET_MAX_LOGICAL_EP) {
82-
kfree_skb(skb);
83-
return RX_HANDLER_CONSUMED;
84-
}
80+
if (mux_id >= RMNET_MAX_LOGICAL_EP)
81+
goto free_skb;
8582

86-
ep = &port->muxed_ep[mux_id];
83+
ep = rmnet_get_endpoint(port, mux_id);
84+
if (!ep)
85+
goto free_skb;
8786

8887
if (port->ingress_data_format & RMNET_INGRESS_FORMAT_DEMUXING)
8988
skb->dev = ep->egress_dev;
@@ -93,6 +92,10 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
9392
skb_trim(skb, len);
9493
rmnet_set_skb_proto(skb);
9594
return rmnet_deliver_skb(skb);
95+
96+
free_skb:
97+
kfree_skb(skb);
98+
return RX_HANDLER_CONSUMED;
9699
}
97100

98101
static rx_handler_result_t

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "rmnet_vnd.h"
1818

1919
static u8 rmnet_map_do_flow_control(struct sk_buff *skb,
20-
struct rmnet_port *rdinfo,
20+
struct rmnet_port *port,
2121
int enable)
2222
{
2323
struct rmnet_map_control_command *cmd;
@@ -37,7 +37,7 @@ static u8 rmnet_map_do_flow_control(struct sk_buff *skb,
3737
return RX_HANDLER_CONSUMED;
3838
}
3939

40-
ep = &rdinfo->muxed_ep[mux_id];
40+
ep = rmnet_get_endpoint(port, mux_id);
4141
vnd = ep->egress_dev;
4242

4343
ip_family = cmd->flow_control.ip_family;

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,19 @@ void rmnet_vnd_setup(struct net_device *rmnet_dev)
100100

101101
int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
102102
struct rmnet_port *port,
103-
struct net_device *real_dev)
103+
struct net_device *real_dev,
104+
struct rmnet_endpoint *ep)
104105
{
105106
struct rmnet_priv *priv;
106107
int rc;
107108

108-
if (port->muxed_ep[id].egress_dev)
109+
if (ep->egress_dev)
109110
return -EINVAL;
110111

111112
rc = register_netdevice(rmnet_dev);
112113
if (!rc) {
113-
port->muxed_ep[id].egress_dev = rmnet_dev;
114+
ep->egress_dev = rmnet_dev;
115+
ep->mux_id = id;
114116
port->nr_rmnet_devs++;
115117

116118
rmnet_dev->rtnl_link_ops = &rmnet_link_ops;
@@ -125,12 +127,13 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
125127
return rc;
126128
}
127129

128-
int rmnet_vnd_dellink(u8 id, struct rmnet_port *port)
130+
int rmnet_vnd_dellink(u8 id, struct rmnet_port *port,
131+
struct rmnet_endpoint *ep)
129132
{
130-
if (id >= RMNET_MAX_LOGICAL_EP || !port->muxed_ep[id].egress_dev)
133+
if (id >= RMNET_MAX_LOGICAL_EP || !ep->egress_dev)
131134
return -EINVAL;
132135

133-
port->muxed_ep[id].egress_dev = NULL;
136+
ep->egress_dev = NULL;
134137
port->nr_rmnet_devs--;
135138
return 0;
136139
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
int rmnet_vnd_do_flow_control(struct net_device *dev, int enable);
2020
int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
2121
struct rmnet_port *port,
22-
struct net_device *real_dev);
23-
int rmnet_vnd_dellink(u8 id, struct rmnet_port *port);
22+
struct net_device *real_dev,
23+
struct rmnet_endpoint *ep);
24+
int rmnet_vnd_dellink(u8 id, struct rmnet_port *port,
25+
struct rmnet_endpoint *ep);
2426
void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev);
2527
void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev);
2628
u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev);

0 commit comments

Comments
 (0)