Skip to content

Commit 48bfd55

Browse files
congwangdavem330
authored andcommitted
net_sched: plug in qdisc ops change_tx_queue_len
Introduce a new qdisc ops ->change_tx_queue_len() so that each qdisc could decide how to implement this if it wants. Previously we simply read dev->tx_queue_len, after pfifo_fast switches to skb array, we need this API to resize the skb array when we change dev->tx_queue_len. To avoid handling race conditions with TX BH, we need to deactivate all TX queues before change the value and bring them back after we are done, this also makes implementation easier. Cc: John Fastabend <[email protected]> Signed-off-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6a643dd commit 48bfd55

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

include/net/sch_generic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ struct Qdisc_ops {
200200
struct nlattr *arg,
201201
struct netlink_ext_ack *extack);
202202
void (*attach)(struct Qdisc *sch);
203+
int (*change_tx_queue_len)(struct Qdisc *, unsigned int);
203204

204205
int (*dump)(struct Qdisc *, struct sk_buff *);
205206
int (*dump_stats)(struct Qdisc *, struct gnet_dump *);
@@ -489,6 +490,7 @@ void qdisc_class_hash_remove(struct Qdisc_class_hash *,
489490
void qdisc_class_hash_grow(struct Qdisc *, struct Qdisc_class_hash *);
490491
void qdisc_class_hash_destroy(struct Qdisc_class_hash *);
491492

493+
int dev_qdisc_change_tx_queue_len(struct net_device *dev);
492494
void dev_init_scheduler(struct net_device *dev);
493495
void dev_shutdown(struct net_device *dev);
494496
void dev_activate(struct net_device *dev);

net/core/dev.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7070,6 +7070,7 @@ int dev_change_tx_queue_len(struct net_device *dev, unsigned long new_len)
70707070
dev->tx_queue_len = orig_len;
70717071
return res;
70727072
}
7073+
return dev_qdisc_change_tx_queue_len(dev);
70737074
}
70747075

70757076
return 0;

net/sched/sch_generic.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,39 @@ void dev_deactivate(struct net_device *dev)
11781178
}
11791179
EXPORT_SYMBOL(dev_deactivate);
11801180

1181+
static int qdisc_change_tx_queue_len(struct net_device *dev,
1182+
struct netdev_queue *dev_queue)
1183+
{
1184+
struct Qdisc *qdisc = dev_queue->qdisc_sleeping;
1185+
const struct Qdisc_ops *ops = qdisc->ops;
1186+
1187+
if (ops->change_tx_queue_len)
1188+
return ops->change_tx_queue_len(qdisc, dev->tx_queue_len);
1189+
return 0;
1190+
}
1191+
1192+
int dev_qdisc_change_tx_queue_len(struct net_device *dev)
1193+
{
1194+
bool up = dev->flags & IFF_UP;
1195+
unsigned int i;
1196+
int ret = 0;
1197+
1198+
if (up)
1199+
dev_deactivate(dev);
1200+
1201+
for (i = 0; i < dev->num_tx_queues; i++) {
1202+
ret = qdisc_change_tx_queue_len(dev, &dev->_tx[i]);
1203+
1204+
/* TODO: revert changes on a partial failure */
1205+
if (ret)
1206+
break;
1207+
}
1208+
1209+
if (up)
1210+
dev_activate(dev);
1211+
return ret;
1212+
}
1213+
11811214
static void dev_init_scheduler_queue(struct net_device *dev,
11821215
struct netdev_queue *dev_queue,
11831216
void *_qdisc)

0 commit comments

Comments
 (0)