From patchwork Sun Jan 14 11:33:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 860434 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="xiQ+4P6a"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zKDrz0wxfz9s83 for ; Sun, 14 Jan 2018 22:33:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751822AbeANLdw (ORCPT ); Sun, 14 Jan 2018 06:33:52 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:39233 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751441AbeANLdZ (ORCPT ); Sun, 14 Jan 2018 06:33:25 -0500 Received: by mail-wm0-f66.google.com with SMTP id i11so19385879wmf.4 for ; Sun, 14 Jan 2018 03:33:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4rX+hloTOiv2tple1KgBXH5AlV9RjtBdnC3xO/b3Ukw=; b=xiQ+4P6aVymO9tTNOaULfNAWlWcUxC1FSrFpY6sENm0xpLYbhiIKmL2MHB+JzuhXzE R0HvaMi2rHWDkz6vnuC7cJ8NH08vCZT7zA/ImXd5JlDoXdCzdDrDnfjxdZ7oHkMkhDbG 0gaN0W0z5gB7uhzq/fQGH2dd7Zl1TmMqqGPFgoFMWV4tnTryWHjrzmrwodvNxICYn72I xNUI/arRw5L3rAxdE8AjgPQvmT8ESR+YR7kOGsqbxp3KSRx6BebG5EZuZyXrRCR0f0bg nC7ug8wlGqdTKjgpayehbxEhuPrewgrFfna2Uf7iUayDdiMY9U/Tj/nFek4uzQdRDj4V RNyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4rX+hloTOiv2tple1KgBXH5AlV9RjtBdnC3xO/b3Ukw=; b=MX/a2XEM7+F4d1eEmeyMnzmuA3rBkOGxIuMZ/wMCvYNeo5+s1+n8bXHchv1u9J011t iKKIS1dfL3wY3H7OxVqhKd5GdAbaulDoGDFtg8QAZ5Hk1V21pYAjxK0vAx0CQxYPh9E4 DkS83izyqDfojUSLKk6SBDWgC5+egRFlehWiAQhwZ6rbBDwt84BJvcSddGaxa/keOmf8 1kuYMkI8L4JNgwW/9RlDiHNaX+qkGyWIhOLwAa2wkZPTkBJt65uaQWHyFQdOQeZYF/Wq Dhs4eg+7UfNAv141drgZTCBkcSwBJ4UxVw9TwX0V/q2ds7YPrLRPjRRQ5Xzk5C7ZN2Yl uI6w== X-Gm-Message-State: AKwxytcGORS0mht0C+JekQgI0/OpaSmEm3FhjUERLoV4TvR8mYgxX1xU SVIhxpgEWWn43MqY6s7gMtGF4IqVYco6EA== X-Google-Smtp-Source: ACJfBoul1Nf1yxYlUrE5Mw3LXPyMtdDXhctMPmoFvTqRh6px48wuuh/CKUppsqJmAIoL4sARSnnxtQ== X-Received: by 10.28.146.16 with SMTP id u16mr8410499wmd.124.1515929604370; Sun, 14 Jan 2018 03:33:24 -0800 (PST) Received: from localhost (ip-160-218-244-106.eurotel.cz. [160.218.244.106]) by smtp.gmail.com with ESMTPSA id w133sm3277276wmg.5.2018.01.14.03.33.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 14 Jan 2018 03:33:24 -0800 (PST) From: Jiri Pirko To: netdev@vger.kernel.org Cc: nogahf@mellanox.com, yuvalm@mellanox.com, davem@davemloft.net, idosch@mellanox.com, mlxsw@mellanox.com, jhs@mojatatu.com, xiyou.wangcong@gmail.com, kubakici@wp.pl Subject: [patch net-next v2 3/5] net: sch: prio: Add offload ability to PRIO qdisc Date: Sun, 14 Jan 2018 12:33:15 +0100 Message-Id: <20180114113317.4706-4-jiri@resnulli.us> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180114113317.4706-1-jiri@resnulli.us> References: <20180114113317.4706-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Nogah Frankel Add the ability to offload PRIO qdisc by using ndo_setup_tc. There are three commands for PRIO offloading: * TC_PRIO_REPLACE: handles set and tune * TC_PRIO_DESTROY: handles qdisc destroy * TC_PRIO_STATS: updates the qdiscs counters (given as reference) Like RED qdisc, the indication of whether PRIO is being offloaded is being set and updated as part of the dump function. It is so because the driver could decide to offload or not based on the qdisc parent, which could change without notifying the qdisc. Signed-off-by: Nogah Frankel Reviewed-by: Yuval Mintz Signed-off-by: Jiri Pirko --- include/linux/netdevice.h | 1 + include/net/pkt_cls.h | 25 ++++++++++++++++++++ net/sched/sch_prio.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ef7b348e8498..6d95477b962c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -780,6 +780,7 @@ enum tc_setup_type { TC_SETUP_BLOCK, TC_SETUP_QDISC_CBS, TC_SETUP_QDISC_RED, + TC_SETUP_QDISC_PRIO, }; /* These structures hold the attributes of bpf state that are being passed diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 0d1343cba84c..9c341f003091 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -761,4 +761,29 @@ struct tc_red_qopt_offload { }; }; +enum tc_prio_command { + TC_PRIO_REPLACE, + TC_PRIO_DESTROY, + TC_PRIO_STATS, +}; + +struct tc_prio_qopt_offload_params { + int bands; + u8 priomap[TC_PRIO_MAX + 1]; + /* In case that a prio qdisc is offloaded and now is changed to a + * non-offloadedable config, it needs to update the backlog & qlen + * values to negate the HW backlog & qlen values (and only them). + */ + struct gnet_stats_queue *qstats; +}; + +struct tc_prio_qopt_offload { + enum tc_prio_command command; + u32 handle; + u32 parent; + union { + struct tc_prio_qopt_offload_params replace_params; + struct tc_qopt_offload_stats stats; + }; +}; #endif diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index fe1510eb111f..a398502899a9 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -142,6 +142,31 @@ prio_reset(struct Qdisc *sch) sch->q.qlen = 0; } +static int prio_offload(struct Qdisc *sch, bool enable) +{ + struct prio_sched_data *q = qdisc_priv(sch); + struct net_device *dev = qdisc_dev(sch); + struct tc_prio_qopt_offload opt = { + .handle = sch->handle, + .parent = sch->parent, + }; + + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) + return -EOPNOTSUPP; + + if (enable) { + opt.command = TC_PRIO_REPLACE; + opt.replace_params.bands = q->bands; + memcpy(&opt.replace_params.priomap, q->prio2band, + TC_PRIO_MAX + 1); + opt.replace_params.qstats = &sch->qstats; + } else { + opt.command = TC_PRIO_DESTROY; + } + + return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO, &opt); +} + static void prio_destroy(struct Qdisc *sch) { @@ -149,6 +174,7 @@ prio_destroy(struct Qdisc *sch) struct prio_sched_data *q = qdisc_priv(sch); tcf_block_put(q->block); + prio_offload(sch, false); for (prio = 0; prio < q->bands; prio++) qdisc_destroy(q->queues[prio]); } @@ -204,6 +230,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt, } sch_tree_unlock(sch); + prio_offload(sch, true); return 0; } @@ -223,15 +250,47 @@ static int prio_init(struct Qdisc *sch, struct nlattr *opt, return prio_tune(sch, opt, extack); } +static int prio_dump_offload(struct Qdisc *sch) +{ + struct net_device *dev = qdisc_dev(sch); + struct tc_prio_qopt_offload hw_stats = { + .handle = sch->handle, + .parent = sch->parent, + .command = TC_PRIO_STATS, + .stats.bstats = &sch->bstats, + .stats.qstats = &sch->qstats, + }; + int err; + + sch->flags &= ~TCQ_F_OFFLOADED; + if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) + return 0; + + err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_PRIO, + &hw_stats); + if (err == -EOPNOTSUPP) + return 0; + + if (!err) + sch->flags |= TCQ_F_OFFLOADED; + + return err; +} + static int prio_dump(struct Qdisc *sch, struct sk_buff *skb) { struct prio_sched_data *q = qdisc_priv(sch); unsigned char *b = skb_tail_pointer(skb); struct tc_prio_qopt opt; + int err; opt.bands = q->bands; memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX + 1); + err = prio_dump_offload(sch); + if (err) + goto nla_put_failure; + if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt)) goto nla_put_failure;