All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed
@ 2019-03-15 21:16 Leandro Dorileo
  2019-03-15 21:16 ` [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation Leandro Dorileo
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Leandro Dorileo @ 2019-03-15 21:16 UTC (permalink / raw)
  To: netdev
  Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S . Miller,
	Vinicius Costa Gomes

This set fixes miscalculations based on invalid link speed values.

Changes in v3:
 + yep pr_info() format warnings;

Changes in v2:
 + fixed pr_info() format both on cbs and taprio patches;

Leandro Dorileo (2):
  net/sched: taprio: fix picos_per_byte miscalculation
  net/sched: cbs: fix port_rate miscalculation

 net/sched/sch_cbs.c    | 91 +++++++++++++++++++++++++++++++++++-------
 net/sched/sch_taprio.c | 90 +++++++++++++++++++++++++++++++++--------
 2 files changed, 151 insertions(+), 30 deletions(-)

-- 
2.21.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation
  2019-03-15 21:16 [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed Leandro Dorileo
@ 2019-03-15 21:16 ` Leandro Dorileo
  2019-03-15 21:36   ` Florian Fainelli
  2019-03-16  9:00   ` kbuild test robot
  2019-03-15 21:16 ` [PATCH net V3 2/2] net/sched: cbs: fix port_rate miscalculation Leandro Dorileo
  2019-03-19  0:07 ` [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed Patel, Vedang
  2 siblings, 2 replies; 7+ messages in thread
From: Leandro Dorileo @ 2019-03-15 21:16 UTC (permalink / raw)
  To: netdev
  Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S . Miller,
	Vinicius Costa Gomes

The Time Aware Priority Scheduler is heavily dependent to link speed,
it relies on it to calculate transmission bytes per cycle, we can't
properly calculate the so called budget if the device has failed
to report the link speed.

In that case we can't dequeue packets assuming a wrong budget.
This patch makes sure we fail to dequeue case:

1) __ethtool_get_link_ksettings() reports error or 2) the ethernet
driver failed to set the ksettings' speed value (setting link speed
to SPEED_UNKNOWN).

Additionally we re calculate the budget whenever the link speed is
changed.

Fixes: 5a781ccbd19e4 ("tc: Add support for configuring the taprio scheduler")
Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
---
 net/sched/sch_taprio.c | 90 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 74 insertions(+), 16 deletions(-)

diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 206e4dbed12f..fa237908ba09 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -20,6 +20,9 @@
 #include <net/pkt_cls.h>
 #include <net/sch_generic.h>
 
+static LIST_HEAD(taprio_list);
+static DEFINE_SPINLOCK(taprio_list_lock);
+
 #define TAPRIO_ALL_GATES_OPEN -1
 
 struct sched_entry {
@@ -42,9 +45,9 @@ struct taprio_sched {
 	struct Qdisc *root;
 	s64 base_time;
 	int clockid;
-	int picos_per_byte; /* Using picoseconds because for 10Gbps+
-			     * speeds it's sub-nanoseconds per byte
-			     */
+	atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+
+				    * speeds it's sub-nanoseconds per byte
+				    */
 	size_t num_entries;
 
 	/* Protects the update side of the RCU protected current_entry */
@@ -53,6 +56,7 @@ struct taprio_sched {
 	struct list_head entries;
 	ktime_t (*get_time)(void);
 	struct hrtimer advance_timer;
+	struct list_head taprio_list;
 };
 
 static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
@@ -117,7 +121,7 @@ static struct sk_buff *taprio_peek(struct Qdisc *sch)
 
 static inline int length_to_duration(struct taprio_sched *q, int len)
 {
-	return (len * q->picos_per_byte) / 1000;
+	return (len * atomic64_read(&q->picos_per_byte)) / 1000;
 }
 
 static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
@@ -129,6 +133,11 @@ static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
 	u32 gate_mask;
 	int i;
 
+	if (atomic64_read(&q->picos_per_byte) == -1) {
+		WARN_ONCE(1, "taprio: dequeue() called with unknown picos per byte.");
+		return NULL;
+	}
+
 	rcu_read_lock();
 	entry = rcu_dereference(q->current_entry);
 	/* if there's no entry, it means that the schedule didn't
@@ -233,7 +242,7 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
 
 	next->close_time = close_time;
 	atomic_set(&next->budget,
-		   (next->interval * 1000) / q->picos_per_byte);
+		   (next->interval * 1000) / atomic64_read(&q->picos_per_byte));
 
 first_run:
 	rcu_assign_pointer(q->current_entry, next);
@@ -567,7 +576,8 @@ static void taprio_start_sched(struct Qdisc *sch, ktime_t start)
 
 	first->close_time = ktime_add_ns(start, first->interval);
 	atomic_set(&first->budget,
-		   (first->interval * 1000) / q->picos_per_byte);
+		   (first->interval * 1000) /
+		   atomic64_read(&q->picos_per_byte));
 	rcu_assign_pointer(q->current_entry, NULL);
 
 	spin_unlock_irqrestore(&q->current_entry_lock, flags);
@@ -575,6 +585,45 @@ static void taprio_start_sched(struct Qdisc *sch, ktime_t start)
 	hrtimer_start(&q->advance_timer, start, HRTIMER_MODE_ABS);
 }
 
+static void taprio_set_picos_per_byte(struct net_device *dev,
+				      struct taprio_sched *q)
+{
+	struct ethtool_link_ksettings ecmd;
+	int picos_per_byte = -1;
+
+	if (!__ethtool_get_link_ksettings(dev, &ecmd) &&
+	    ecmd.base.speed != SPEED_UNKNOWN)
+		picos_per_byte = div64_s64(NSEC_PER_SEC * 1000LL * 8,
+					   ecmd.base.speed * 1000 * 1000);
+
+	atomic64_set(&q->picos_per_byte, picos_per_byte);
+	pr_info("taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
+		dev->name, atomic64_read(&q->picos_per_byte), ecmd.base.speed);
+}
+
+static int taprio_dev_notifier(struct notifier_block *nb, unsigned long event,
+			       void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct taprio_sched *q;
+	struct net_device *qdev;
+
+	ASSERT_RTNL();
+
+	if (event != NETDEV_UP && event != NETDEV_CHANGE)
+		return NOTIFY_DONE;
+
+	spin_lock(&taprio_list_lock);
+	list_for_each_entry(q, &taprio_list, taprio_list) {
+		qdev = qdisc_dev(q->root);
+		if (qdev == dev)
+			taprio_set_picos_per_byte(dev, q);
+	}
+	spin_unlock(&taprio_list_lock);
+
+	return NOTIFY_DONE;
+}
+
 static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 			 struct netlink_ext_ack *extack)
 {
@@ -582,9 +631,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 	struct taprio_sched *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
 	struct tc_mqprio_qopt *mqprio = NULL;
-	struct ethtool_link_ksettings ecmd;
 	int i, err, size;
-	s64 link_speed;
 	ktime_t start;
 
 	err = nla_parse_nested(tb, TCA_TAPRIO_ATTR_MAX, opt,
@@ -657,14 +704,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 					       mqprio->prio_tc_map[i]);
 	}
 
-	if (!__ethtool_get_link_ksettings(dev, &ecmd))
-		link_speed = ecmd.base.speed;
-	else
-		link_speed = SPEED_1000;
-
-	q->picos_per_byte = div64_s64(NSEC_PER_SEC * 1000LL * 8,
-				      link_speed * 1000 * 1000);
-
+	taprio_set_picos_per_byte(dev, q);
 	start = taprio_get_start_time(sch);
 	if (!start)
 		return 0;
@@ -681,6 +721,10 @@ static void taprio_destroy(struct Qdisc *sch)
 	struct sched_entry *entry, *n;
 	unsigned int i;
 
+	spin_lock(&taprio_list_lock);
+	list_del(&q->taprio_list);
+	spin_unlock(&taprio_list_lock);
+
 	hrtimer_cancel(&q->advance_timer);
 
 	if (q->qdiscs) {
@@ -735,6 +779,10 @@ static int taprio_init(struct Qdisc *sch, struct nlattr *opt,
 	if (!opt)
 		return -EINVAL;
 
+	spin_lock(&taprio_list_lock);
+	list_add(&q->taprio_list, &taprio_list);
+	spin_unlock(&taprio_list_lock);
+
 	return taprio_change(sch, opt, extack);
 }
 
@@ -947,14 +995,24 @@ static struct Qdisc_ops taprio_qdisc_ops __read_mostly = {
 	.owner		= THIS_MODULE,
 };
 
+static struct notifier_block taprio_device_notifier = {
+	.notifier_call = taprio_dev_notifier,
+};
+
 static int __init taprio_module_init(void)
 {
+	int err = register_netdevice_notifier(&taprio_device_notifier);
+
+	if (err)
+		return err;
+
 	return register_qdisc(&taprio_qdisc_ops);
 }
 
 static void __exit taprio_module_exit(void)
 {
 	unregister_qdisc(&taprio_qdisc_ops);
+	unregister_netdevice_notifier(&taprio_device_notifier);
 }
 
 module_init(taprio_module_init);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net V3 2/2] net/sched: cbs: fix port_rate miscalculation
  2019-03-15 21:16 [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed Leandro Dorileo
  2019-03-15 21:16 ` [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation Leandro Dorileo
@ 2019-03-15 21:16 ` Leandro Dorileo
  2019-03-19  0:07 ` [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed Patel, Vedang
  2 siblings, 0 replies; 7+ messages in thread
From: Leandro Dorileo @ 2019-03-15 21:16 UTC (permalink / raw)
  To: netdev
  Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S . Miller,
	Vinicius Costa Gomes

The Credit Based Shaper heavily depends on link speed to calculate
the scheduling credits, we can't properly calculate the credits if the
device has failed to report the link speed.

In that case we can't dequeue packets assuming a wrong port rate that will
result into an inconsistent credit distribution.

This patch makes sure we fail to dequeue case:

1) __ethtool_get_link_ksettings() reports error or 2) the ethernet driver
failed to set the ksettings' speed value (setting link speed to
SPEED_UNKNOWN).

Additionally we properly re calculate the port rate whenever the link speed
is changed.

Fixes: 3d0bd028ffb4a ("net/sched: Add support for HW offloading for CBS")
Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
---
 net/sched/sch_cbs.c | 91 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 77 insertions(+), 14 deletions(-)

diff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c
index c6a502933fe7..cf43f113eafb 100644
--- a/net/sched/sch_cbs.c
+++ b/net/sched/sch_cbs.c
@@ -61,16 +61,20 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
+#include <net/netevent.h>
 #include <net/netlink.h>
 #include <net/sch_generic.h>
 #include <net/pkt_sched.h>
 
+static LIST_HEAD(cbs_list);
+static DEFINE_SPINLOCK(cbs_list_lock);
+
 #define BYTES_PER_KBIT (1000LL / 8)
 
 struct cbs_sched_data {
 	bool offload;
 	int queue;
-	s64 port_rate; /* in bytes/s */
+	atomic64_t port_rate; /* in bytes/s */
 	s64 last; /* timestamp in ns */
 	s64 credits; /* in bytes */
 	s32 locredit; /* in bytes */
@@ -82,6 +86,7 @@ struct cbs_sched_data {
 		       struct sk_buff **to_free);
 	struct sk_buff *(*dequeue)(struct Qdisc *sch);
 	struct Qdisc *qdisc;
+	struct list_head cbs_list;
 };
 
 static int cbs_child_enqueue(struct sk_buff *skb, struct Qdisc *sch,
@@ -181,6 +186,11 @@ static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch)
 	s64 credits;
 	int len;
 
+	if (atomic64_read(&q->port_rate) == -1) {
+		WARN_ONCE(1, "cbs: dequeue() called with unknown port rate.");
+		return NULL;
+	}
+
 	if (q->credits < 0) {
 		credits = timediff_to_credits(now - q->last, q->idleslope);
 
@@ -207,7 +217,8 @@ static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch)
 	/* As sendslope is a negative number, this will decrease the
 	 * amount of q->credits.
 	 */
-	credits = credits_from_len(len, q->sendslope, q->port_rate);
+	credits = credits_from_len(len, q->sendslope,
+				   atomic64_read(&q->port_rate));
 	credits += q->credits;
 
 	q->credits = max_t(s64, credits, q->locredit);
@@ -294,6 +305,43 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
 	return 0;
 }
 
+static void cbs_set_port_rate(struct net_device *dev, struct cbs_sched_data *q)
+{
+	struct ethtool_link_ksettings ecmd;
+	int port_rate = -1;
+
+	if (!__ethtool_get_link_ksettings(dev, &ecmd) &&
+	    ecmd.base.speed != SPEED_UNKNOWN)
+		port_rate = ecmd.base.speed * 1000 * BYTES_PER_KBIT;
+
+	atomic64_set(&q->port_rate, port_rate);
+	pr_info("cbs: set %s's port_rate to: %lld, linkspeed: %d\n",
+		dev->name, atomic64_read(&q->port_rate), ecmd.base.speed);
+}
+
+static int cbs_dev_notifier(struct notifier_block *nb, unsigned long event,
+			    void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct cbs_sched_data *q;
+	struct net_device *qdev;
+
+	ASSERT_RTNL();
+
+	if (event != NETDEV_UP && event != NETDEV_CHANGE)
+		return NOTIFY_DONE;
+
+	spin_lock(&cbs_list_lock);
+	list_for_each_entry(q, &cbs_list, cbs_list) {
+		qdev = qdisc_dev(q->qdisc);
+		if (qdev == dev)
+			cbs_set_port_rate(dev, q);
+	}
+	spin_unlock(&cbs_list_lock);
+
+	return NOTIFY_DONE;
+}
+
 static int cbs_change(struct Qdisc *sch, struct nlattr *opt,
 		      struct netlink_ext_ack *extack)
 {
@@ -315,16 +363,7 @@ static int cbs_change(struct Qdisc *sch, struct nlattr *opt,
 	qopt = nla_data(tb[TCA_CBS_PARMS]);
 
 	if (!qopt->offload) {
-		struct ethtool_link_ksettings ecmd;
-		s64 link_speed;
-
-		if (!__ethtool_get_link_ksettings(dev, &ecmd))
-			link_speed = ecmd.base.speed;
-		else
-			link_speed = SPEED_1000;
-
-		q->port_rate = link_speed * 1000 * BYTES_PER_KBIT;
-
+		cbs_set_port_rate(dev, q);
 		cbs_disable_offload(dev, q);
 	} else {
 		err = cbs_enable_offload(dev, q, qopt, extack);
@@ -347,6 +386,7 @@ static int cbs_init(struct Qdisc *sch, struct nlattr *opt,
 {
 	struct cbs_sched_data *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
+	int err;
 
 	if (!opt) {
 		NL_SET_ERR_MSG(extack, "Missing CBS qdisc options  which are mandatory");
@@ -367,7 +407,17 @@ static int cbs_init(struct Qdisc *sch, struct nlattr *opt,
 
 	qdisc_watchdog_init(&q->watchdog, sch);
 
-	return cbs_change(sch, opt, extack);
+	err = cbs_change(sch, opt, extack);
+	if (err)
+		return err;
+
+	if (!q->offload) {
+		spin_lock(&cbs_list_lock);
+		list_add(&q->cbs_list, &cbs_list);
+		spin_unlock(&cbs_list_lock);
+	}
+
+	return 0;
 }
 
 static void cbs_destroy(struct Qdisc *sch)
@@ -375,8 +425,11 @@ static void cbs_destroy(struct Qdisc *sch)
 	struct cbs_sched_data *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
 
-	qdisc_watchdog_cancel(&q->watchdog);
+	spin_lock(&cbs_list_lock);
+	list_del(&q->cbs_list);
+	spin_unlock(&cbs_list_lock);
 
+	qdisc_watchdog_cancel(&q->watchdog);
 	cbs_disable_offload(dev, q);
 
 	if (q->qdisc)
@@ -487,14 +540,24 @@ static struct Qdisc_ops cbs_qdisc_ops __read_mostly = {
 	.owner		=	THIS_MODULE,
 };
 
+static struct notifier_block cbs_device_notifier = {
+	.notifier_call = cbs_dev_notifier,
+};
+
 static int __init cbs_module_init(void)
 {
+	int err = register_netdevice_notifier(&cbs_device_notifier);
+
+	if (err)
+		return err;
+
 	return register_qdisc(&cbs_qdisc_ops);
 }
 
 static void __exit cbs_module_exit(void)
 {
 	unregister_qdisc(&cbs_qdisc_ops);
+	unregister_netdevice_notifier(&cbs_device_notifier);
 }
 module_init(cbs_module_init)
 module_exit(cbs_module_exit)
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation
  2019-03-15 21:16 ` [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation Leandro Dorileo
@ 2019-03-15 21:36   ` Florian Fainelli
  2019-03-18 21:13     ` Leandro Dorileo
  2019-03-16  9:00   ` kbuild test robot
  1 sibling, 1 reply; 7+ messages in thread
From: Florian Fainelli @ 2019-03-15 21:36 UTC (permalink / raw)
  To: Leandro Dorileo, netdev
  Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S . Miller,
	Vinicius Costa Gomes

On 3/15/19 2:16 PM, Leandro Dorileo wrote:
> The Time Aware Priority Scheduler is heavily dependent to link speed,
> it relies on it to calculate transmission bytes per cycle, we can't
> properly calculate the so called budget if the device has failed
> to report the link speed.
> 
> In that case we can't dequeue packets assuming a wrong budget.
> This patch makes sure we fail to dequeue case:
> 
> 1) __ethtool_get_link_ksettings() reports error or 2) the ethernet
> driver failed to set the ksettings' speed value (setting link speed
> to SPEED_UNKNOWN).
> 
> Additionally we re calculate the budget whenever the link speed is
> changed.
> 
> Fixes: 5a781ccbd19e4 ("tc: Add support for configuring the taprio scheduler")
> Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
> ---
>  net/sched/sch_taprio.c | 90 ++++++++++++++++++++++++++++++++++--------
>  1 file changed, 74 insertions(+), 16 deletions(-)
> 
> diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
> index 206e4dbed12f..fa237908ba09 100644
> --- a/net/sched/sch_taprio.c
> +++ b/net/sched/sch_taprio.c
> @@ -20,6 +20,9 @@
>  #include <net/pkt_cls.h>
>  #include <net/sch_generic.h>
>  
> +static LIST_HEAD(taprio_list);
> +static DEFINE_SPINLOCK(taprio_list_lock);
> +
>  #define TAPRIO_ALL_GATES_OPEN -1
>  
>  struct sched_entry {
> @@ -42,9 +45,9 @@ struct taprio_sched {
>  	struct Qdisc *root;
>  	s64 base_time;
>  	int clockid;
> -	int picos_per_byte; /* Using picoseconds because for 10Gbps+
> -			     * speeds it's sub-nanoseconds per byte
> -			     */
> +	atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+
> +				    * speeds it's sub-nanoseconds per byte
> +				    */
>  	size_t num_entries;
>  
>  	/* Protects the update side of the RCU protected current_entry */
> @@ -53,6 +56,7 @@ struct taprio_sched {
>  	struct list_head entries;
>  	ktime_t (*get_time)(void);
>  	struct hrtimer advance_timer;
> +	struct list_head taprio_list;
>  };
>  
>  static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
> @@ -117,7 +121,7 @@ static struct sk_buff *taprio_peek(struct Qdisc *sch)
>  
>  static inline int length_to_duration(struct taprio_sched *q, int len)
>  {
> -	return (len * q->picos_per_byte) / 1000;
> +	return (len * atomic64_read(&q->picos_per_byte)) / 1000;
>  }
>  
>  static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
> @@ -129,6 +133,11 @@ static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
>  	u32 gate_mask;
>  	int i;
>  
> +	if (atomic64_read(&q->picos_per_byte) == -1) {
> +		WARN_ONCE(1, "taprio: dequeue() called with unknown picos per byte.");
> +		return NULL;
> +	}
> +
>  	rcu_read_lock();
>  	entry = rcu_dereference(q->current_entry);
>  	/* if there's no entry, it means that the schedule didn't
> @@ -233,7 +242,7 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
>  
>  	next->close_time = close_time;
>  	atomic_set(&next->budget,
> -		   (next->interval * 1000) / q->picos_per_byte);
> +		   (next->interval * 1000) / atomic64_read(&q->picos_per_byte));
>  
>  first_run:
>  	rcu_assign_pointer(q->current_entry, next);
> @@ -567,7 +576,8 @@ static void taprio_start_sched(struct Qdisc *sch, ktime_t start)
>  
>  	first->close_time = ktime_add_ns(start, first->interval);
>  	atomic_set(&first->budget,
> -		   (first->interval * 1000) / q->picos_per_byte);
> +		   (first->interval * 1000) /
> +		   atomic64_read(&q->picos_per_byte));
>  	rcu_assign_pointer(q->current_entry, NULL);
>  
>  	spin_unlock_irqrestore(&q->current_entry_lock, flags);
> @@ -575,6 +585,45 @@ static void taprio_start_sched(struct Qdisc *sch, ktime_t start)
>  	hrtimer_start(&q->advance_timer, start, HRTIMER_MODE_ABS);
>  }
>  
> +static void taprio_set_picos_per_byte(struct net_device *dev,
> +				      struct taprio_sched *q)
> +{
> +	struct ethtool_link_ksettings ecmd;
> +	int picos_per_byte = -1;
> +
> +	if (!__ethtool_get_link_ksettings(dev, &ecmd) &&
> +	    ecmd.base.speed != SPEED_UNKNOWN)
> +		picos_per_byte = div64_s64(NSEC_PER_SEC * 1000LL * 8,
> +					   ecmd.base.speed * 1000 * 1000);
> +
> +	atomic64_set(&q->picos_per_byte, picos_per_byte);
> +	pr_info("taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
> +		dev->name, atomic64_read(&q->picos_per_byte), ecmd.base.speed);

It does not seem appropriate to use pr_info() here whenever the link
speed changes and the taprio scheduler is reconfigured to match the
network device's link speed. netdev_dbg() might be more appropriate, or
no message at all to avoid spamming the kernel log. Same thing for your
second patch.
-- 
Florian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation
  2019-03-15 21:16 ` [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation Leandro Dorileo
  2019-03-15 21:36   ` Florian Fainelli
@ 2019-03-16  9:00   ` kbuild test robot
  1 sibling, 0 replies; 7+ messages in thread
From: kbuild test robot @ 2019-03-16  9:00 UTC (permalink / raw)
  To: Leandro Dorileo
  Cc: kbuild-all, netdev, Jamal Hadi Salim, Cong Wang, Jiri Pirko,
	David S . Miller, Vinicius Costa Gomes

[-- Attachment #1: Type: text/plain, Size: 4306 bytes --]

Hi Leandro,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net/master]

url:    https://github.com/0day-ci/linux/commits/Leandro-Dorileo/net-sched-taprio-cbs-Fix-using-invalid-link-speed/20190316-161006
config: riscv-allyesconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=riscv 

All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:7,
                    from include/linux/kernel.h:15,
                    from include/asm-generic/bug.h:18,
                    from arch/riscv/include/asm/bug.h:75,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/gfp.h:5,
                    from include/linux/slab.h:15,
                    from net/sched/sch_taprio.c:10:
   net/sched/sch_taprio.c: In function 'taprio_set_picos_per_byte':
>> include/linux/kern_levels.h:5:18: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^~~~~~
   include/linux/kern_levels.h:14:19: note: in expansion of macro 'KERN_SOH'
    #define KERN_INFO KERN_SOH "6" /* informational */
                      ^~~~~~~~
   include/linux/printk.h:309:9: note: in expansion of macro 'KERN_INFO'
     printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
            ^~~~~~~~~
   net/sched/sch_taprio.c:600:2: note: in expansion of macro 'pr_info'
     pr_info("taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
     ^~~~~~~
   net/sched/sch_taprio.c:600:50: note: format string is defined here
     pr_info("taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
                                                  ~~~^
                                                  %ld
--
   In file included from include/linux/printk.h:7,
                    from include/linux/kernel.h:15,
                    from include/asm-generic/bug.h:18,
                    from arch/riscv/include/asm/bug.h:75,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/gfp.h:5,
                    from include/linux/slab.h:15,
                    from net//sched/sch_taprio.c:10:
   net//sched/sch_taprio.c: In function 'taprio_set_picos_per_byte':
>> include/linux/kern_levels.h:5:18: warning: format '%lld' expects argument of type 'long long int', but argument 3 has type 'long int' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^~~~~~
   include/linux/kern_levels.h:14:19: note: in expansion of macro 'KERN_SOH'
    #define KERN_INFO KERN_SOH "6" /* informational */
                      ^~~~~~~~
   include/linux/printk.h:309:9: note: in expansion of macro 'KERN_INFO'
     printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
            ^~~~~~~~~
   net//sched/sch_taprio.c:600:2: note: in expansion of macro 'pr_info'
     pr_info("taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
     ^~~~~~~
   net//sched/sch_taprio.c:600:50: note: format string is defined here
     pr_info("taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
                                                  ~~~^
                                                  %ld

vim +5 include/linux/kern_levels.h

314ba352 Joe Perches 2012-07-30  4  
04d2c8c8 Joe Perches 2012-07-30 @5  #define KERN_SOH	"\001"		/* ASCII Start Of Header */
04d2c8c8 Joe Perches 2012-07-30  6  #define KERN_SOH_ASCII	'\001'
04d2c8c8 Joe Perches 2012-07-30  7  

:::::: The code at line 5 was first introduced by commit
:::::: 04d2c8c83d0e3ac5f78aeede51babb3236200112 printk: convert the format for KERN_<LEVEL> to a 2 byte pattern

:::::: TO: Joe Perches <joe@perches.com>
:::::: CC: Linus Torvalds <torvalds@linux-foundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 56851 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation
  2019-03-15 21:36   ` Florian Fainelli
@ 2019-03-18 21:13     ` Leandro Dorileo
  0 siblings, 0 replies; 7+ messages in thread
From: Leandro Dorileo @ 2019-03-18 21:13 UTC (permalink / raw)
  To: Florian Fainelli, Leandro Dorileo, netdev
  Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S . Miller,
	Vinicius Costa Gomes


Hi Florian,

Florian Fainelli <f.fainelli@gmail.com> writes:

> On 3/15/19 2:16 PM, Leandro Dorileo wrote:
>> The Time Aware Priority Scheduler is heavily dependent to link speed,
>> it relies on it to calculate transmission bytes per cycle, we can't
>> properly calculate the so called budget if the device has failed
>> to report the link speed.
>> 
>> In that case we can't dequeue packets assuming a wrong budget.
>> This patch makes sure we fail to dequeue case:
>> 
>> 1) __ethtool_get_link_ksettings() reports error or 2) the ethernet
>> driver failed to set the ksettings' speed value (setting link speed
>> to SPEED_UNKNOWN).
>> 
>> Additionally we re calculate the budget whenever the link speed is
>> changed.
>> 
>> Fixes: 5a781ccbd19e4 ("tc: Add support for configuring the taprio scheduler")
>> Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
>> ---
>>  net/sched/sch_taprio.c | 90 ++++++++++++++++++++++++++++++++++--------
>>  1 file changed, 74 insertions(+), 16 deletions(-)
>> 
>> diff --git a/net/sched/sch_taprio.c b/net/sche
> d/sch_taprio.c
>> index 206e4dbed12f..fa237908ba09 100644
>> --- a/net/sched/sch_taprio.c
>> +++ b/net/sched/sch_taprio.c
>> @@ -20,6 +20,9 @@
>>  #include <net/pkt_cls.h>
>>  #include <net/sch_generic.h>
>>  
>> +static LIST_HEAD(taprio_list);
>> +static DEFINE_SPINLOCK(taprio_list_lock);
>> +
>>  #define TAPRIO_ALL_GATES_OPEN -1
>>  
>>  struct sched_entry {
>> @@ -42,9 +45,9 @@ struct taprio_sched {
>>  	struct Qdisc *root;
>>  	s64 base_time;
>>  	int clockid;
>> -	int picos_per_byte; /* Using picoseconds because for 10Gbps+
>> -			     * speeds it's sub-nanoseconds per byte
>> -			     */
>> +	atomic64_t picos_per_byte; /* Using picoseconds because for 10Gbps+
>> +				    * speeds it's sub-nanoseconds per byte
>> +				    */
>>  	size_t num_entries;
>>  
>>  	/* Protects the update side of the RCU protected current_entry */
>> @@ -53,6 +56,7 @@ struct taprio_sched {
>>  	struct list_head entries;
>>  	ktime_t (*get_time)(void);
>>  	struct hrtimer advance_timer;
>> +	struct list_h
> ead taprio_list;
>>  };
>>  
>>  static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
>> @@ -117,7 +121,7 @@ static struct sk_buff *taprio_peek(struct Qdisc *sch)
>>  
>>  static inline int length_to_duration(struct taprio_sched *q, int len)
>>  {
>> -	return (len * q->picos_per_byte) / 1000;
>> +	return (len * atomic64_read(&q->picos_per_byte)) / 1000;
>>  }
>>  
>>  static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
>> @@ -129,6 +133,11 @@ static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
>>  	u32 gate_mask;
>>  	int i;
>>  
>> +	if (atomic64_read(&q->picos_per_byte) == -1) {
>> +		WARN_ONCE(1, "taprio: dequeue() called with unknown picos per byte.");
>> +		return NULL;
>> +	}
>> +
>>  	rcu_read_lock();
>>  	entry = rcu_dereference(q->current_entry);
>>  	/* if there's no entry, it means that the schedule didn't
>> @@ -233,7 +242,7 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
>>  
>>  	next->close_time = close_time;
>>  	atomic_set(&ne
> xt->budget,
>> -		   (next->interval * 1000) / q->picos_per_byte);
>> +		   (next->interval * 1000) / atomic64_read(&q->picos_per_byte));
>>  
>>  first_run:
>>  	rcu_assign_pointer(q->current_entry, next);
>> @@ -567,7 +576,8 @@ static void taprio_start_sched(struct Qdisc *sch, ktime_t start)
>>  
>>  	first->close_time = ktime_add_ns(start, first->interval);
>>  	atomic_set(&first->budget,
>> -		   (first->interval * 1000) / q->picos_per_byte);
>> +		   (first->interval * 1000) /
>> +		   atomic64_read(&q->picos_per_byte));
>>  	rcu_assign_pointer(q->current_entry, NULL);
>>  
>>  	spin_unlock_irqrestore(&q->current_entry_lock, flags);
>> @@ -575,6 +585,45 @@ static void taprio_start_sched(struct Qdisc *sch, ktime_t start)
>>  	hrtimer_start(&q->advance_timer, start, HRTIMER_MODE_ABS);
>>  }
>>  
>> +static void taprio_set_picos_per_byte(struct net_device *dev,
>> +				      struct taprio_sched *q)
>> +{
>> +	struct ethtool_link_ksettings ecmd;
>> +	int picos_per_byte = -1;
>> +
>> +
> 	if (!__ethtool_get_link_ksettings(dev, &ecmd) &&
>> +	    ecmd.base.speed != SPEED_UNKNOWN)
>> +		picos_per_byte = div64_s64(NSEC_PER_SEC * 1000LL * 8,
>> +					   ecmd.base.speed * 1000 * 1000);
>> +
>> +	atomic64_set(&q->picos_per_byte, picos_per_byte);
>> +	pr_info("taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
>> +		dev->name, atomic64_read(&q->picos_per_byte), ecmd.base.speed);
>
> It does not seem appropriate to use pr_info() here whenever the link
> speed changes and the taprio scheduler is reconfigured to match the
> network device's link speed. netdev_dbg() might be more appropriate, or
> no message at all to avoid spamming the kernel log. Same thing for your
> second patch.

It's being useful to me on debugging it, however I agree users will not be much
interested on it.

Thanks...

--
Dorileo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed
  2019-03-15 21:16 [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed Leandro Dorileo
  2019-03-15 21:16 ` [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation Leandro Dorileo
  2019-03-15 21:16 ` [PATCH net V3 2/2] net/sched: cbs: fix port_rate miscalculation Leandro Dorileo
@ 2019-03-19  0:07 ` Patel, Vedang
  2 siblings, 0 replies; 7+ messages in thread
From: Patel, Vedang @ 2019-03-19  0:07 UTC (permalink / raw)
  To: Dorileo, Leandro, netdev
  Cc: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S . Miller, Gomes,
	Vinicius

I agree with Florian's minor comment regarding pr_info->netdev_dgb change. 

But, apart from that, I reviewed both the patches look good to me:

Reviewed-By: Vedang Patel <vedang.patel@intel.com>

On 3/15/19, 2:17 PM, "netdev-owner@vger.kernel.org on behalf of Leandro Dorileo" <netdev-owner@vger.kernel.org on behalf of leandro.maciel.dorileo@intel.com> wrote:

    This set fixes miscalculations based on invalid link speed values.
    
    Changes in v3:
     + yep pr_info() format warnings;
    
    Changes in v2:
     + fixed pr_info() format both on cbs and taprio patches;
    
    Leandro Dorileo (2):
      net/sched: taprio: fix picos_per_byte miscalculation
      net/sched: cbs: fix port_rate miscalculation
    
     net/sched/sch_cbs.c    | 91 +++++++++++++++++++++++++++++++++++-------
     net/sched/sch_taprio.c | 90 +++++++++++++++++++++++++++++++++--------
     2 files changed, 151 insertions(+), 30 deletions(-)
    
    -- 
    2.21.0
    
    


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-03-19  0:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-15 21:16 [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed Leandro Dorileo
2019-03-15 21:16 ` [PATCH net V3 1/2] net/sched: taprio: fix picos_per_byte miscalculation Leandro Dorileo
2019-03-15 21:36   ` Florian Fainelli
2019-03-18 21:13     ` Leandro Dorileo
2019-03-16  9:00   ` kbuild test robot
2019-03-15 21:16 ` [PATCH net V3 2/2] net/sched: cbs: fix port_rate miscalculation Leandro Dorileo
2019-03-19  0:07 ` [PATCH net V3 0/2] net/sched: taprio: cbs: Fix using invalid link speed Patel, Vedang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.