@@ -31,6 +31,7 @@ static DEFINE_SPINLOCK(taprio_list_lock);
31
31
32
32
#define TXTIME_ASSIST_IS_ENABLED (flags ) ((flags) & TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST)
33
33
#define FULL_OFFLOAD_IS_ENABLED (flags ) ((flags) & TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD)
34
+ #define TAPRIO_FLAGS_INVALID U32_MAX
34
35
35
36
struct sched_entry {
36
37
struct list_head list ;
@@ -1367,6 +1368,33 @@ static int taprio_mqprio_cmp(const struct net_device *dev,
1367
1368
return 0 ;
1368
1369
}
1369
1370
1371
+ /* The semantics of the 'flags' argument in relation to 'change()'
1372
+ * requests, are interpreted following two rules (which are applied in
1373
+ * this order): (1) an omitted 'flags' argument is interpreted as
1374
+ * zero; (2) the 'flags' of a "running" taprio instance cannot be
1375
+ * changed.
1376
+ */
1377
+ static int taprio_new_flags (const struct nlattr * attr , u32 old ,
1378
+ struct netlink_ext_ack * extack )
1379
+ {
1380
+ u32 new = 0 ;
1381
+
1382
+ if (attr )
1383
+ new = nla_get_u32 (attr );
1384
+
1385
+ if (old != TAPRIO_FLAGS_INVALID && old != new ) {
1386
+ NL_SET_ERR_MSG_MOD (extack , "Changing 'flags' of a running schedule is not supported" );
1387
+ return - EOPNOTSUPP ;
1388
+ }
1389
+
1390
+ if (!taprio_flags_valid (new )) {
1391
+ NL_SET_ERR_MSG_MOD (extack , "Specified 'flags' are not valid" );
1392
+ return - EINVAL ;
1393
+ }
1394
+
1395
+ return new ;
1396
+ }
1397
+
1370
1398
static int taprio_change (struct Qdisc * sch , struct nlattr * opt ,
1371
1399
struct netlink_ext_ack * extack )
1372
1400
{
@@ -1375,7 +1403,6 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
1375
1403
struct taprio_sched * q = qdisc_priv (sch );
1376
1404
struct net_device * dev = qdisc_dev (sch );
1377
1405
struct tc_mqprio_qopt * mqprio = NULL ;
1378
- u32 taprio_flags = 0 ;
1379
1406
unsigned long flags ;
1380
1407
ktime_t start ;
1381
1408
int i , err ;
@@ -1388,21 +1415,14 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
1388
1415
if (tb [TCA_TAPRIO_ATTR_PRIOMAP ])
1389
1416
mqprio = nla_data (tb [TCA_TAPRIO_ATTR_PRIOMAP ]);
1390
1417
1391
- if (tb [TCA_TAPRIO_ATTR_FLAGS ]) {
1392
- taprio_flags = nla_get_u32 (tb [TCA_TAPRIO_ATTR_FLAGS ]);
1393
-
1394
- if (q -> flags != 0 && q -> flags != taprio_flags ) {
1395
- NL_SET_ERR_MSG_MOD (extack , "Changing 'flags' of a running schedule is not supported" );
1396
- return - EOPNOTSUPP ;
1397
- } else if (!taprio_flags_valid (taprio_flags )) {
1398
- NL_SET_ERR_MSG_MOD (extack , "Specified 'flags' are not valid" );
1399
- return - EINVAL ;
1400
- }
1418
+ err = taprio_new_flags (tb [TCA_TAPRIO_ATTR_FLAGS ],
1419
+ q -> flags , extack );
1420
+ if (err < 0 )
1421
+ return err ;
1401
1422
1402
- q -> flags = taprio_flags ;
1403
- }
1423
+ q -> flags = err ;
1404
1424
1405
- err = taprio_parse_mqprio_opt (dev , mqprio , extack , taprio_flags );
1425
+ err = taprio_parse_mqprio_opt (dev , mqprio , extack , q -> flags );
1406
1426
if (err < 0 )
1407
1427
return err ;
1408
1428
@@ -1457,7 +1477,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
1457
1477
mqprio -> prio_tc_map [i ]);
1458
1478
}
1459
1479
1460
- if (FULL_OFFLOAD_IS_ENABLED (taprio_flags ))
1480
+ if (FULL_OFFLOAD_IS_ENABLED (q -> flags ))
1461
1481
err = taprio_enable_offload (dev , mqprio , q , new_admin , extack );
1462
1482
else
1463
1483
err = taprio_disable_offload (dev , q , extack );
@@ -1477,14 +1497,14 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
1477
1497
q -> txtime_delay = nla_get_u32 (tb [TCA_TAPRIO_ATTR_TXTIME_DELAY ]);
1478
1498
}
1479
1499
1480
- if (!TXTIME_ASSIST_IS_ENABLED (taprio_flags ) &&
1481
- !FULL_OFFLOAD_IS_ENABLED (taprio_flags ) &&
1500
+ if (!TXTIME_ASSIST_IS_ENABLED (q -> flags ) &&
1501
+ !FULL_OFFLOAD_IS_ENABLED (q -> flags ) &&
1482
1502
!hrtimer_active (& q -> advance_timer )) {
1483
1503
hrtimer_init (& q -> advance_timer , q -> clockid , HRTIMER_MODE_ABS );
1484
1504
q -> advance_timer .function = advance_sched ;
1485
1505
}
1486
1506
1487
- if (FULL_OFFLOAD_IS_ENABLED (taprio_flags )) {
1507
+ if (FULL_OFFLOAD_IS_ENABLED (q -> flags )) {
1488
1508
q -> dequeue = taprio_dequeue_offload ;
1489
1509
q -> peek = taprio_peek_offload ;
1490
1510
} else {
@@ -1501,7 +1521,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
1501
1521
goto unlock ;
1502
1522
}
1503
1523
1504
- if (TXTIME_ASSIST_IS_ENABLED (taprio_flags )) {
1524
+ if (TXTIME_ASSIST_IS_ENABLED (q -> flags )) {
1505
1525
setup_txtime (q , new_admin , start );
1506
1526
1507
1527
if (!oper ) {
@@ -1528,7 +1548,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
1528
1548
1529
1549
spin_unlock_irqrestore (& q -> current_entry_lock , flags );
1530
1550
1531
- if (FULL_OFFLOAD_IS_ENABLED (taprio_flags ))
1551
+ if (FULL_OFFLOAD_IS_ENABLED (q -> flags ))
1532
1552
taprio_offload_config_changed (q );
1533
1553
}
1534
1554
@@ -1597,6 +1617,7 @@ static int taprio_init(struct Qdisc *sch, struct nlattr *opt,
1597
1617
* and get the valid one on taprio_change().
1598
1618
*/
1599
1619
q -> clockid = -1 ;
1620
+ q -> flags = TAPRIO_FLAGS_INVALID ;
1600
1621
1601
1622
spin_lock (& taprio_list_lock );
1602
1623
list_add (& q -> taprio_list , & taprio_list );
0 commit comments