From patchwork Wed Jan 17 23:06:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862640 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN78399Bz9s7v for ; Thu, 18 Jan 2018 10:08:36 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754602AbeAQXIc (ORCPT ); Wed, 17 Jan 2018 18:08:32 -0500 Received: from mga06.intel.com ([134.134.136.31]:63122 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754050AbeAQXHn (ORCPT ); Wed, 17 Jan 2018 18:07:43 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977766" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Richard Cochran , Jesus Sanchez-Palencia Subject: [RFC v2 net-next 01/10] net: Add a new socket option for a future transmit time. Date: Wed, 17 Jan 2018 15:06:12 -0800 Message-Id: <20180117230621.26074-2-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Richard Cochran This patch introduces SO_TXTIME. User space enables this option in order to pass a desired future transmit time in a CMSG when calling sendmsg(2). A new field is added to struct sockcm_cookie, and the tstamp from skbuffs will be used later on. Signed-off-by: Richard Cochran Signed-off-by: Jesus Sanchez-Palencia --- arch/alpha/include/uapi/asm/socket.h | 3 +++ arch/frv/include/uapi/asm/socket.h | 3 +++ arch/ia64/include/uapi/asm/socket.h | 3 +++ arch/m32r/include/uapi/asm/socket.h | 3 +++ arch/mips/include/uapi/asm/socket.h | 3 +++ arch/mn10300/include/uapi/asm/socket.h | 3 +++ arch/parisc/include/uapi/asm/socket.h | 3 +++ arch/s390/include/uapi/asm/socket.h | 3 +++ arch/sparc/include/uapi/asm/socket.h | 3 +++ arch/xtensa/include/uapi/asm/socket.h | 3 +++ include/net/sock.h | 2 ++ include/uapi/asm-generic/socket.h | 3 +++ net/core/sock.c | 16 ++++++++++++++++ 13 files changed, 51 insertions(+) diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index be14f16149d5..065fb372e355 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -112,4 +112,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index 9168e78fa32a..0e95f45cd058 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h @@ -105,5 +105,8 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _ASM_SOCKET_H */ diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 3efba40adc54..c872c4e6bafb 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h @@ -114,4 +114,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index cf5018e82c3d..65276c95b8df 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h @@ -105,4 +105,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _ASM_M32R_SOCKET_H */ diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 49c3d4795963..71370fb3ceef 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -123,4 +123,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index b35eee132142..d029a40b1b55 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h @@ -105,4 +105,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _ASM_SOCKET_H */ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 1d0fdc3b5d22..061b9cf2a779 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -104,4 +104,7 @@ #define SO_ZEROCOPY 0x4035 +#define SO_TXTIME 0x4036 +#define SCM_TXTIME SO_TXTIME + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 3510c0fd06f4..39d901476ee5 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h @@ -111,4 +111,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _ASM_SOCKET_H */ diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index d58520c2e6ff..7ea35e5601b6 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -101,6 +101,9 @@ #define SO_ZEROCOPY 0x003e +#define SO_TXTIME 0x003f +#define SCM_TXTIME SO_TXTIME + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index 75a07b8119a9..1de07a7f7680 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h @@ -116,4 +116,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* _XTENSA_SOCKET_H */ diff --git a/include/net/sock.h b/include/net/sock.h index 73b7830b0bb8..927af34f3e2c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -777,6 +777,7 @@ enum sock_flags { SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */ SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ + SOCK_TXTIME, }; #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) @@ -1567,6 +1568,7 @@ void sock_kzfree_s(struct sock *sk, void *mem, int size); void sk_send_sigurg(struct sock *sk); struct sockcm_cookie { + ktime_t transmit_time; u32 mark; u16 tsflags; }; diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 0ae758c90e54..a12692e5f7a8 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -107,4 +107,7 @@ #define SO_ZEROCOPY 60 +#define SO_TXTIME 61 +#define SCM_TXTIME SO_TXTIME + #endif /* __ASM_GENERIC_SOCKET_H */ diff --git a/net/core/sock.c b/net/core/sock.c index abf4cbff99b2..37ef4b33fd92 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1061,6 +1061,13 @@ int sock_setsockopt(struct socket *sock, int level, int optname, sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool); break; + case SO_TXTIME: + if (ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) + sock_valbool_flag(sk, SOCK_TXTIME, valbool); + else + ret = -EPERM; + break; + default: ret = -ENOPROTOOPT; break; @@ -2130,6 +2137,15 @@ int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg, sockc->tsflags &= ~SOF_TIMESTAMPING_TX_RECORD_MASK; sockc->tsflags |= tsflags; break; + case SO_TXTIME: + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) + return -EPERM; + if (!sock_flag(sk, SOCK_TXTIME)) + return -EINVAL; + if (cmsg->cmsg_len != CMSG_LEN(sizeof(ktime_t))) + return -EINVAL; + sockc->transmit_time = *(ktime_t *)CMSG_DATA(cmsg); + break; /* SCM_RIGHTS and SCM_CREDENTIALS are semantically in SOL_UNIX. */ case SCM_RIGHTS: case SCM_CREDENTIALS: From patchwork Wed Jan 17 23:06:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862641 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN7J2qmPz9s83 for ; Thu, 18 Jan 2018 10:08:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754618AbeAQXIm (ORCPT ); Wed, 17 Jan 2018 18:08:42 -0500 Received: from mga06.intel.com ([134.134.136.31]:63122 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754041AbeAQXHm (ORCPT ); Wed, 17 Jan 2018 18:07:42 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977769" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Richard Cochran , Jesus Sanchez-Palencia Subject: [RFC v2 net-next 02/10] net: ipv4: raw: Hook into time based transmission. Date: Wed, 17 Jan 2018 15:06:13 -0800 Message-Id: <20180117230621.26074-3-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Richard Cochran For raw packets, copy the desired future transmit time from the CMSG cookie into the skb. Signed-off-by: Richard Cochran Signed-off-by: Jesus Sanchez-Palencia --- net/ipv4/raw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 136544b36a46..e37ea8ab6a78 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -381,6 +381,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; + skb->tstamp = sockc->transmit_time; skb_dst_set(skb, &rt->dst); *rtp = NULL; @@ -562,6 +563,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) } ipc.sockc.tsflags = sk->sk_tsflags; + ipc.sockc.transmit_time = 0; ipc.addr = inet->inet_saddr; ipc.opt = NULL; ipc.tx_flags = 0; From patchwork Wed Jan 17 23:06:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862634 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN6g16mhz9s7v for ; Thu, 18 Jan 2018 10:08:11 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754268AbeAQXHo (ORCPT ); Wed, 17 Jan 2018 18:07:44 -0500 Received: from mga06.intel.com ([134.134.136.31]:63115 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753762AbeAQXHm (ORCPT ); Wed, 17 Jan 2018 18:07:42 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977773" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Richard Cochran , Jesus Sanchez-Palencia Subject: [RFC v2 net-next 03/10] net: ipv4: udp: Hook into time based transmission. Date: Wed, 17 Jan 2018 15:06:14 -0800 Message-Id: <20180117230621.26074-4-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Richard Cochran For udp packets, copy the desired future transmit time from the CMSG cookie into the skb. Signed-off-by: Richard Cochran Signed-off-by: Jesus Sanchez-Palencia --- net/ipv4/udp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 853321555a4e..89257422503a 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -926,6 +926,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) } ipc.sockc.tsflags = sk->sk_tsflags; + ipc.sockc.transmit_time = 0; ipc.addr = inet->inet_saddr; ipc.oif = sk->sk_bound_dev_if; @@ -1027,8 +1028,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) sizeof(struct udphdr), &ipc, &rt, msg->msg_flags); err = PTR_ERR(skb); - if (!IS_ERR_OR_NULL(skb)) + if (!IS_ERR_OR_NULL(skb)) { + skb->tstamp = ipc.sockc.transmit_time; err = udp_send_skb(skb, fl4); + } goto out; } From patchwork Wed Jan 17 23:06:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862637 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN6t10zBz9s7v for ; Thu, 18 Jan 2018 10:08:22 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754185AbeAQXHn (ORCPT ); Wed, 17 Jan 2018 18:07:43 -0500 Received: from mga06.intel.com ([134.134.136.31]:63115 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753268AbeAQXHk (ORCPT ); Wed, 17 Jan 2018 18:07:40 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977777" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Richard Cochran , Jesus Sanchez-Palencia Subject: [RFC v2 net-next 04/10] net: packet: Hook into time based transmission. Date: Wed, 17 Jan 2018 15:06:15 -0800 Message-Id: <20180117230621.26074-5-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Richard Cochran For raw layer-2 packets, copy the desired future transmit time from the CMSG cookie into the skb. Signed-off-by: Richard Cochran Signed-off-by: Jesus Sanchez-Palencia --- net/packet/af_packet.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 05d31864a34e..6af129a65e85 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1976,6 +1976,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg, goto out_unlock; } + sockc.transmit_time = 0; sockc.tsflags = sk->sk_tsflags; if (msg->msg_controllen) { err = sock_cmsg_send(sk, msg, &sockc); @@ -1987,6 +1988,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg, skb->dev = dev; skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; + skb->tstamp = sockc.transmit_time; sock_tx_timestamp(sk, sockc.tsflags, &skb_shinfo(skb)->tx_flags); @@ -2484,6 +2486,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, skb->dev = dev; skb->priority = po->sk.sk_priority; skb->mark = po->sk.sk_mark; + skb->tstamp = sockc->transmit_time; sock_tx_timestamp(&po->sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags); skb_shinfo(skb)->destructor_arg = ph.raw; @@ -2660,6 +2663,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) if (unlikely(!(dev->flags & IFF_UP))) goto out_put; + sockc.transmit_time = 0; sockc.tsflags = po->sk.sk_tsflags; if (msg->msg_controllen) { err = sock_cmsg_send(&po->sk, msg, &sockc); @@ -2856,6 +2860,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) if (unlikely(!(dev->flags & IFF_UP))) goto out_unlock; + sockc.transmit_time = 0; sockc.tsflags = sk->sk_tsflags; sockc.mark = sk->sk_mark; if (msg->msg_controllen) { @@ -2928,6 +2933,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) skb->dev = dev; skb->priority = sk->sk_priority; skb->mark = sockc.mark; + skb->tstamp = sockc.transmit_time; if (has_vnet_hdr) { err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le()); From patchwork Wed Jan 17 23:06:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862642 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN7N1dGcz9sDB for ; Thu, 18 Jan 2018 10:08:48 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754603AbeAQXIl (ORCPT ); Wed, 17 Jan 2018 18:08:41 -0500 Received: from mga06.intel.com ([134.134.136.31]:63115 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754045AbeAQXHm (ORCPT ); Wed, 17 Jan 2018 18:07:42 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977780" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com Subject: [RFC v2 net-next 05/10] net/sched: Allow creating a Qdisc watchdog with other clocks Date: Wed, 17 Jan 2018 15:06:16 -0800 Message-Id: <20180117230621.26074-6-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vinicius Costa Gomes This adds 'qdisc_watchdog_init_clockid()' that allows a clockid to be passed, this allows other time references to be used when scheduling the Qdisc to run. Signed-off-by: Vinicius Costa Gomes --- include/net/pkt_sched.h | 2 ++ net/sched/sch_api.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 815b92a23936..2466ea143d01 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -72,6 +72,8 @@ struct qdisc_watchdog { struct Qdisc *qdisc; }; +void qdisc_watchdog_init_clockid(struct qdisc_watchdog *wd, struct Qdisc *qdisc, + clockid_t clockid); void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc); void qdisc_watchdog_schedule_ns(struct qdisc_watchdog *wd, u64 expires); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index d512f49ee83c..d6136920b5c1 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -596,12 +596,19 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer) return HRTIMER_NORESTART; } -void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc) +void qdisc_watchdog_init_clockid(struct qdisc_watchdog *wd, struct Qdisc *qdisc, + clockid_t clockid) { - hrtimer_init(&wd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); + hrtimer_init(&wd->timer, clockid, HRTIMER_MODE_ABS_PINNED); wd->timer.function = qdisc_watchdog; wd->qdisc = qdisc; } +EXPORT_SYMBOL(qdisc_watchdog_init_clockid); + +void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc) +{ + qdisc_watchdog_init_clockid(wd, qdisc, CLOCK_MONOTONIC); +} EXPORT_SYMBOL(qdisc_watchdog_init); void qdisc_watchdog_schedule_ns(struct qdisc_watchdog *wd, u64 expires) From patchwork Wed Jan 17 23:06:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862638 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN6x3cGzz9s7v for ; Thu, 18 Jan 2018 10:08:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754575AbeAQXIX (ORCPT ); Wed, 17 Jan 2018 18:08:23 -0500 Received: from mga06.intel.com ([134.134.136.31]:63115 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754087AbeAQXHn (ORCPT ); Wed, 17 Jan 2018 18:07:43 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977783" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Jesus Sanchez-Palencia Subject: [RFC v2 net-next 06/10] net/sched: Introduce the TBS Qdisc Date: Wed, 17 Jan 2018 15:06:17 -0800 Message-Id: <20180117230621.26074-7-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vinicius Costa Gomes TBS (Time Based Scheduler) uses the information added earlier in this series (the socket option SO_TXTIME and the new role of sk_buff->tstamp) to schedule traffic transmission based on absolute time. For some workloads, just bandwidth enforcement is not enough, and precise control of the transmission of packets is necessary. Example: $ tc qdisc replace dev enp2s0 parent root handle 100 mqprio num_tc 3 \ map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 1@0 1@1 2@2 hw 0 $ tc qdisc add dev enp2s0 parent 100:1 tbs delta 60000 clockid 11 offload 1 In this example, the Qdisc will try to enable offloading (offload 1) the control of the transmission time to the network adapter, the time stamp in socket are in reference to the clockid '11' (CLOCK_TAI) and packets leave the Qdisc "delta" (60000) nanoseconds before its transmission time. When offloading is disabled, the network adapter will ignore the sk_buff time stamp, and so, the transmission time will be only "best effort" from the Qdisc. Signed-off-by: Vinicius Costa Gomes Signed-off-by: Jesus Sanchez-Palencia --- include/linux/netdevice.h | 1 + include/net/pkt_sched.h | 5 + include/uapi/linux/pkt_sched.h | 17 ++ net/sched/Kconfig | 11 ++ net/sched/Makefile | 1 + net/sched/sch_tbs.c | 392 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 427 insertions(+) create mode 100644 net/sched/sch_tbs.c diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ed0799a12bf2..e87031bd108e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -781,6 +781,7 @@ enum tc_setup_type { TC_SETUP_QDISC_CBS, TC_SETUP_QDISC_RED, TC_SETUP_QDISC_PRIO, + TC_SETUP_QDISC_TBS, }; /* These structures hold the attributes of bpf state that are being passed diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 2466ea143d01..d042ffda7f21 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -155,4 +155,9 @@ struct tc_cbs_qopt_offload { s32 sendslope; }; +struct tc_tbs_qopt_offload { + u8 enable; + s32 queue; +}; + #endif diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h index 37b5096ae97b..6bb39944ba32 100644 --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h @@ -934,4 +934,21 @@ enum { #define TCA_CBS_MAX (__TCA_CBS_MAX - 1) + +/* TBS */ +struct tc_tbs_qopt { + __u8 offload; + __u8 _pad[3]; + __s32 delta; + __s32 clockid; +}; + +enum { + TCA_TBS_UNSPEC, + TCA_TBS_PARMS, + __TCA_TBS_MAX, +}; + +#define TCA_TBS_MAX (__TCA_TBS_MAX - 1) + #endif diff --git a/net/sched/Kconfig b/net/sched/Kconfig index c03d86a7775e..7d54045995a3 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -183,6 +183,17 @@ config NET_SCH_CBS To compile this code as a module, choose M here: the module will be called sch_cbs. +config NET_SCH_TBS + tristate "Time Based Scheduler (TBS)" + ---help--- + Say Y here if you want to use the Time Based Scheduler (TBS) packet + scheduling algorithm. + + See the top of for more details. + + To compile this code as a module, choose M here: the + module will be called sch_tbs. + config NET_SCH_GRED tristate "Generic Random Early Detection (GRED)" ---help--- diff --git a/net/sched/Makefile b/net/sched/Makefile index 5b635447e3f8..0f7f29505c89 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_NET_SCH_FQ) += sch_fq.o obj-$(CONFIG_NET_SCH_HHF) += sch_hhf.o obj-$(CONFIG_NET_SCH_PIE) += sch_pie.o obj-$(CONFIG_NET_SCH_CBS) += sch_cbs.o +obj-$(CONFIG_NET_SCH_TBS) += sch_tbs.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o diff --git a/net/sched/sch_tbs.c b/net/sched/sch_tbs.c new file mode 100644 index 000000000000..300456063ac9 --- /dev/null +++ b/net/sched/sch_tbs.c @@ -0,0 +1,392 @@ +/* + * net/sched/sch_tbs.c Time Based Shaper + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Vinicius Costa Gomes + * Jesus Sanchez-Palencia + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct tbs_sched_data { + bool offload; + int clockid; + int queue; + s32 delta; /* in ns */ + ktime_t last; /* The txtime of the last skb sent to the netdevice. */ + struct rb_root head; + struct qdisc_watchdog watchdog; + struct Qdisc *qdisc; +}; + +static const struct nla_policy tbs_policy[TCA_TBS_MAX + 1] = { + [TCA_TBS_PARMS] = { .len = sizeof(struct tc_tbs_qopt) }, +}; + +typedef ktime_t (*get_time_func_t)(void); + +static const get_time_func_t clockid_to_get_time[MAX_CLOCKS] = { + [CLOCK_MONOTONIC] = ktime_get, + [CLOCK_REALTIME] = ktime_get_real, + [CLOCK_BOOTTIME] = ktime_get_boottime, + [CLOCK_TAI] = ktime_get_clocktai, +}; + +static ktime_t get_time_by_clockid(clockid_t clockid) +{ + get_time_func_t func = clockid_to_get_time[clockid]; + + if (!func) + return 0; + + return func(); +} + +static struct sk_buff *tbs_peek(struct Qdisc *sch) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct rb_node *p; + + p = rb_first(&q->head); + if (!p) + return NULL; + + return rb_to_skb(p); +} + +static void reset_watchdog(struct Qdisc *sch) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct sk_buff *skb = tbs_peek(sch); + ktime_t next; + + if (!skb) + return; + + next = ktime_sub_ns(skb->tstamp, q->delta); + qdisc_watchdog_schedule_ns(&q->watchdog, ktime_to_ns(next)); +} + +static int tbs_enqueue(struct sk_buff *nskb, struct Qdisc *sch, + struct sk_buff **to_free) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct rb_node **p = &q->head.rb_node, *parent = NULL; + ktime_t txtime = nskb->tstamp; + struct sock *sk = nskb->sk; + ktime_t now; + + if (sk && !sock_flag(sk, SOCK_TXTIME)) + goto drop; + + now = get_time_by_clockid(q->clockid); + + if (ktime_before(txtime, now) || ktime_before(txtime, q->last)) + goto drop; + + while (*p) { + struct sk_buff *skb; + + parent = *p; + skb = rb_to_skb(parent); + if (ktime_after(txtime, skb->tstamp)) + p = &parent->rb_right; + else + p = &parent->rb_left; + } + rb_link_node(&nskb->rbnode, parent, p); + rb_insert_color(&nskb->rbnode, &q->head); + + qdisc_qstats_backlog_inc(sch, nskb); + sch->q.qlen++; + + /* Now we may need to re-arm the qdisc watchdog for the next packet. */ + reset_watchdog(sch); + + return NET_XMIT_SUCCESS; + +drop: + return qdisc_drop(nskb, sch, to_free); +} + +static struct sk_buff *timerqueue_erase(struct Qdisc *sch, + struct sk_buff *skb, bool drop) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + + rb_erase(&skb->rbnode, &q->head); + + if (drop) { + struct sk_buff *to_free = NULL; + + qdisc_drop(skb, sch, &to_free); + kfree_skb_list(to_free); + } else { + qdisc_qstats_backlog_dec(sch, skb); + qdisc_bstats_update(sch, skb); + + q->last = skb->tstamp; + } + + sch->q.qlen--; + + /* The rbnode field in the skb re-uses these fields, now that + * we are done with the rbnode, reset them. + */ + skb->next = NULL; + skb->prev = NULL; + skb->dev = qdisc_dev(sch); + + return skb; +} + +static struct sk_buff *tbs_dequeue(struct Qdisc *sch) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct sk_buff *skb; + ktime_t now, next; + + skb = tbs_peek(sch); + if (!skb) + return NULL; + + now = get_time_by_clockid(q->clockid); + + /* If packet has expired while in queue, drop it. */ + if (ktime_before(skb->tstamp, now)) { + timerqueue_erase(sch, skb, true); + skb = NULL; + goto out; + } + + next = ktime_sub_ns(skb->tstamp, q->delta); + + /* Dequeue only if now is within the [txtime - delta, txtime] range. */ + if (ktime_after(now, next)) + timerqueue_erase(sch, skb, false); + else + skb = NULL; + +out: + /* Now we may need to re-arm the qdisc watchdog for the next packet. */ + reset_watchdog(sch); + + return skb; +} + +static void tbs_disable_offload(struct net_device *dev, + struct tbs_sched_data *q) +{ + struct tc_tbs_qopt_offload tbs = { }; + const struct net_device_ops *ops; + int err; + + if (!q->offload) + return; + + ops = dev->netdev_ops; + if (!ops->ndo_setup_tc) + return; + + tbs.queue = q->queue; + tbs.enable = 0; + + err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TBS, &tbs); + if (err < 0) + pr_warn("Couldn't disable TBS offload for queue %d\n", + tbs.queue); +} + +static int tbs_enable_offload(struct net_device *dev, struct tbs_sched_data *q, + struct netlink_ext_ack *extack) +{ + const struct net_device_ops *ops = dev->netdev_ops; + struct tc_tbs_qopt_offload tbs = { }; + int err; + + if (q->offload) + return 0; + + if (!ops->ndo_setup_tc) { + NL_SET_ERR_MSG(extack, "Specified device does not support TBS offload"); + return -EOPNOTSUPP; + } + + tbs.queue = q->queue; + tbs.enable = 1; + + err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_TBS, &tbs); + if (err < 0) { + NL_SET_ERR_MSG(extack, "Specified device failed to setup TBS hardware offload"); + return err; + } + + return 0; +} + +static int tbs_change(struct Qdisc *sch, struct nlattr *opt, + struct netlink_ext_ack *extack) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct net_device *dev = qdisc_dev(sch); + struct nlattr *tb[TCA_CBS_MAX + 1]; + struct tc_tbs_qopt *qopt; + int err; + + err = nla_parse_nested(tb, TCA_TBS_MAX, opt, tbs_policy, extack); + if (err < 0) + return err; + + if (!tb[TCA_TBS_PARMS]) { + NL_SET_ERR_MSG(extack, "Missing mandatory TBS parameters"); + return -EINVAL; + } + + qopt = nla_data(tb[TCA_TBS_PARMS]); + + if (qopt->clockid < 0 || qopt->clockid >= MAX_CLOCKS || + !clockid_to_get_time[qopt->clockid]) { + NL_SET_ERR_MSG(extack, "Invalid clockid"); + return -EINVAL; + } + + pr_debug("delta %d clockid %d offload %d\n", + qopt->delta, qopt->clockid, qopt->offload); + + if (!qopt->offload) { + tbs_disable_offload(dev, q); + } else { + err = tbs_enable_offload(dev, q, extack); + if (err < 0) + return err; + } + + /* Everything went OK, save the parameters used. */ + q->delta = qopt->delta; + q->clockid = qopt->clockid; + q->offload = qopt->offload; + + qdisc_watchdog_init_clockid(&q->watchdog, sch, q->clockid); + + return 0; +} + +static int tbs_init(struct Qdisc *sch, struct nlattr *opt, + struct netlink_ext_ack *extack) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct net_device *dev = qdisc_dev(sch); + + if (!opt) { + NL_SET_ERR_MSG(extack, "Missing TBS qdisc options which are mandatory"); + return -EINVAL; + } + + q->queue = sch->dev_queue - netdev_get_tx_queue(dev, 0); + + return tbs_change(sch, opt, extack); +} + +static void timerqueue_clear(struct Qdisc *sch) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct rb_node *p = rb_first(&q->head); + + while (p) { + struct sk_buff *skb = rb_to_skb(p); + + p = rb_next(p); + rb_erase(&skb->rbnode, &q->head); + rtnl_kfree_skbs(skb, skb); + } +} + +static void tbs_reset(struct Qdisc *sch) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + + qdisc_watchdog_cancel(&q->watchdog); + timerqueue_clear(sch); + + sch->qstats.backlog = 0; + sch->q.qlen = 0; + + q->last = 0; +} + +static void tbs_destroy(struct Qdisc *sch) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct net_device *dev = qdisc_dev(sch); + + qdisc_watchdog_cancel(&q->watchdog); + timerqueue_clear(sch); + tbs_disable_offload(dev, q); +} + +static int tbs_dump(struct Qdisc *sch, struct sk_buff *skb) +{ + struct tbs_sched_data *q = qdisc_priv(sch); + struct tc_tbs_qopt opt = { }; + struct nlattr *nest; + + nest = nla_nest_start(skb, TCA_OPTIONS); + if (!nest) + goto nla_put_failure; + + opt.delta = q->delta; + opt.clockid = q->clockid; + opt.offload = q->offload; + + if (nla_put(skb, TCA_TBS_PARMS, sizeof(opt), &opt)) + goto nla_put_failure; + + return nla_nest_end(skb, nest); + +nla_put_failure: + nla_nest_cancel(skb, nest); + return -1; +} + +static struct Qdisc_ops tbs_qdisc_ops __read_mostly = { + .id = "tbs", + .priv_size = sizeof(struct tbs_sched_data), + .enqueue = tbs_enqueue, + .dequeue = tbs_dequeue, + .peek = tbs_peek, + .init = tbs_init, + .reset = tbs_reset, + .destroy = tbs_destroy, + .change = tbs_change, + .dump = tbs_dump, + .owner = THIS_MODULE, +}; + +static int __init tbs_module_init(void) +{ + return register_qdisc(&tbs_qdisc_ops); +} + +static void __exit tbs_module_exit(void) +{ + unregister_qdisc(&tbs_qdisc_ops); +} +module_init(tbs_module_init) +module_exit(tbs_module_exit) +MODULE_LICENSE("GPL"); From patchwork Wed Jan 17 23:06:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862631 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN6F2f7hz9sNw for ; Thu, 18 Jan 2018 10:07:49 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754389AbeAQXHq (ORCPT ); Wed, 17 Jan 2018 18:07:46 -0500 Received: from mga06.intel.com ([134.134.136.31]:63122 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754023AbeAQXHn (ORCPT ); Wed, 17 Jan 2018 18:07:43 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977785" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Jesus Sanchez-Palencia Subject: [RFC v2 net-next 07/10] igb: Refactor igb_configure_cbs() Date: Wed, 17 Jan 2018 15:06:18 -0800 Message-Id: <20180117230621.26074-8-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Make this function retrieve what it needs from the Tx ring being addressed since it already relies on what had been saved on it before. Also, since this function will be used by the upcoming Launchtime patches rename it to better reflect its intention. Note that Launchtime is not part of what 802.1Qav specifies, but the i210 datasheet refers to this set of functionality as "Qav Transmission Mode". Here we also perform a tiny refactor at is_any_cbs_enabled(), and add further documentation to igb_setup_tx_mode(). Signed-off-by: Jesus Sanchez-Palencia --- drivers/net/ethernet/intel/igb/igb_main.c | 54 ++++++++++++++----------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index c208753ff5b7..dd19c325a85c 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1673,23 +1673,17 @@ static void set_queue_mode(struct e1000_hw *hw, int queue, enum queue_mode mode) } /** - * igb_configure_cbs - Configure Credit-Based Shaper (CBS) + * igb_config_tx_modes - Configure "Qav Tx mode" features on igb * @adapter: pointer to adapter struct * @queue: queue number - * @enable: true = enable CBS, false = disable CBS - * @idleslope: idleSlope in kbps - * @sendslope: sendSlope in kbps - * @hicredit: hiCredit in bytes - * @locredit: loCredit in bytes * - * Configure CBS for a given hardware queue. When disabling, idleslope, - * sendslope, hicredit, locredit arguments are ignored. Returns 0 if - * success. Negative otherwise. + * Configure CBS for a given hardware queue. Parameters are retrieved + * from the correct Tx ring, so igb_save_cbs_params() should be used + * for setting those correctly prior to this function being called. **/ -static void igb_configure_cbs(struct igb_adapter *adapter, int queue, - bool enable, int idleslope, int sendslope, - int hicredit, int locredit) +static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) { + struct igb_ring *ring = adapter->tx_ring[queue]; struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; u32 tqavcc; @@ -1698,7 +1692,7 @@ static void igb_configure_cbs(struct igb_adapter *adapter, int queue, WARN_ON(hw->mac.type != e1000_i210); WARN_ON(queue < 0 || queue > 1); - if (enable) { + if (ring->cbs_enable) { set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_HIGH); set_queue_mode(hw, queue, QUEUE_MODE_STREAM_RESERVATION); @@ -1745,14 +1739,15 @@ static void igb_configure_cbs(struct igb_adapter *adapter, int queue, * ----------------- (E6) * 1000000 */ - value = DIV_ROUND_UP_ULL(idleslope * 61034ULL, 1000000); + value = DIV_ROUND_UP_ULL(ring->idleslope * 61034ULL, 1000000); tqavcc = rd32(E1000_I210_TQAVCC(queue)); tqavcc &= ~E1000_TQAVCC_IDLESLOPE_MASK; tqavcc |= value; wr32(E1000_I210_TQAVCC(queue), tqavcc); - wr32(E1000_I210_TQAVHC(queue), 0x80000000 + hicredit * 0x7735); + wr32(E1000_I210_TQAVHC(queue), + 0x80000000 + ring->hicredit * 0x7735); } else { set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_LOW); set_queue_mode(hw, queue, QUEUE_MODE_STRICT_PRIORITY); @@ -1772,8 +1767,9 @@ static void igb_configure_cbs(struct igb_adapter *adapter, int queue, */ netdev_dbg(netdev, "CBS %s: queue %d idleslope %d sendslope %d hiCredit %d locredit %d\n", - (enable) ? "enabled" : "disabled", queue, - idleslope, sendslope, hicredit, locredit); + (ring->cbs_enable) ? "enabled" : "disabled", queue, + ring->idleslope, ring->sendslope, ring->hicredit, + ring->locredit); } static int igb_save_cbs_params(struct igb_adapter *adapter, int queue, @@ -1798,19 +1794,25 @@ static int igb_save_cbs_params(struct igb_adapter *adapter, int queue, static bool is_any_cbs_enabled(struct igb_adapter *adapter) { - struct igb_ring *ring; int i; for (i = 0; i < adapter->num_tx_queues; i++) { - ring = adapter->tx_ring[i]; - - if (ring->cbs_enable) + if (adapter->tx_ring[i]->cbs_enable) return true; } return false; } +/** + * igb_setup_tx_mode - Switch to/from Qav Tx mode when applicable + * @adapter: pointer to adapter struct + * + * Configure TQAVCTRL register switching the controller's Tx mode + * if FQTSS mode is enabled or disabled. Additionally, will issue + * a call to igb_config_tx_modes() per queue so any previously saved + * Tx parameters are applied. + **/ static void igb_setup_tx_mode(struct igb_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -1870,11 +1872,7 @@ static void igb_setup_tx_mode(struct igb_adapter *adapter) adapter->num_tx_queues : I210_SR_QUEUES_NUM; for (i = 0; i < max_queue; i++) { - struct igb_ring *ring = adapter->tx_ring[i]; - - igb_configure_cbs(adapter, i, ring->cbs_enable, - ring->idleslope, ring->sendslope, - ring->hicredit, ring->locredit); + igb_config_tx_modes(adapter, i); } } else { wr32(E1000_RXPBS, I210_RXPBSIZE_DEFAULT); @@ -2468,9 +2466,7 @@ static int igb_offload_cbs(struct igb_adapter *adapter, return err; if (is_fqtss_enabled(adapter)) { - igb_configure_cbs(adapter, qopt->queue, qopt->enable, - qopt->idleslope, qopt->sendslope, - qopt->hicredit, qopt->locredit); + igb_config_tx_modes(adapter, qopt->queue); if (!is_any_cbs_enabled(adapter)) enable_fqtss(adapter, false); From patchwork Wed Jan 17 23:06:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862633 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN6T1qMnz9s7v for ; Thu, 18 Jan 2018 10:08:01 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754317AbeAQXHp (ORCPT ); Wed, 17 Jan 2018 18:07:45 -0500 Received: from mga06.intel.com ([134.134.136.31]:63131 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754130AbeAQXHn (ORCPT ); Wed, 17 Jan 2018 18:07:43 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977789" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Jesus Sanchez-Palencia Subject: [RFC v2 net-next 08/10] igb: Only change Tx arbitration when CBS is on Date: Wed, 17 Jan 2018 15:06:19 -0800 Message-Id: <20180117230621.26074-9-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently the data transmission arbitration algorithm - DataTranARB field on TQAVCTRL reg - is always set to CBS when the Tx mode is changed from legacy to 'Qav' mode. Make that configuration a bit more granular in preparation for the upcoming Launchtime enabling patches, since CBS and Launchtime can be enabled separately. That is achieved by moving the DataTranARB setup to igb_config_tx_modes() instead. Similarly, when disabling CBS we must check if it has been disabled for all queues, and clear the DataTranARB accordingly. Signed-off-by: Jesus Sanchez-Palencia --- drivers/net/ethernet/intel/igb/igb_main.c | 49 +++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index dd19c325a85c..a955e1723ed5 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1672,6 +1672,18 @@ static void set_queue_mode(struct e1000_hw *hw, int queue, enum queue_mode mode) wr32(E1000_I210_TQAVCC(queue), val); } +static bool is_any_cbs_enabled(struct igb_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) { + if (adapter->tx_ring[i]->cbs_enable) + return true; + } + + return false; +} + /** * igb_config_tx_modes - Configure "Qav Tx mode" features on igb * @adapter: pointer to adapter struct @@ -1686,7 +1698,7 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) struct igb_ring *ring = adapter->tx_ring[queue]; struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; - u32 tqavcc; + u32 tqavcc, tqavctrl; u16 value; WARN_ON(hw->mac.type != e1000_i210); @@ -1696,6 +1708,14 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_HIGH); set_queue_mode(hw, queue, QUEUE_MODE_STREAM_RESERVATION); + /* Always set data transfer arbitration to credit-based + * shaper algorithm on TQAVCTRL if CBS is enabled for any of + * the queues. + */ + tqavctrl = rd32(E1000_I210_TQAVCTRL); + tqavctrl |= E1000_TQAVCTRL_DATATRANARB; + wr32(E1000_I210_TQAVCTRL, tqavctrl); + /* According to i210 datasheet section 7.2.7.7, we should set * the 'idleSlope' field from TQAVCC register following the * equation: @@ -1759,6 +1779,16 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) /* Set hiCredit to zero. */ wr32(E1000_I210_TQAVHC(queue), 0); + + /* If CBS is not enabled for any queues anymore, then return to + * the default state of Data Transmission Arbitration on + * TQAVCTRL. + */ + if (!is_any_cbs_enabled(adapter)) { + tqavctrl = rd32(E1000_I210_TQAVCTRL); + tqavctrl &= ~E1000_TQAVCTRL_DATATRANARB; + wr32(E1000_I210_TQAVCTRL, tqavctrl); + } } /* XXX: In i210 controller the sendSlope and loCredit parameters from @@ -1792,18 +1822,6 @@ static int igb_save_cbs_params(struct igb_adapter *adapter, int queue, return 0; } -static bool is_any_cbs_enabled(struct igb_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_tx_queues; i++) { - if (adapter->tx_ring[i]->cbs_enable) - return true; - } - - return false; -} - /** * igb_setup_tx_mode - Switch to/from Qav Tx mode when applicable * @adapter: pointer to adapter struct @@ -1827,11 +1845,10 @@ static void igb_setup_tx_mode(struct igb_adapter *adapter) int i, max_queue; /* Configure TQAVCTRL register: set transmit mode to 'Qav', - * set data fetch arbitration to 'round robin' and set data - * transfer arbitration to 'credit shaper algorithm. + * set data fetch arbitration to 'round robin'. */ val = rd32(E1000_I210_TQAVCTRL); - val |= E1000_TQAVCTRL_XMIT_MODE | E1000_TQAVCTRL_DATATRANARB; + val |= E1000_TQAVCTRL_XMIT_MODE; val &= ~E1000_TQAVCTRL_DATAFETCHARB; wr32(E1000_I210_TQAVCTRL, val); From patchwork Wed Jan 17 23:06:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862636 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN6p0kJyz9s7v for ; Thu, 18 Jan 2018 10:08:18 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754570AbeAQXIQ (ORCPT ); Wed, 17 Jan 2018 18:08:16 -0500 Received: from mga06.intel.com ([134.134.136.31]:63115 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754190AbeAQXHo (ORCPT ); Wed, 17 Jan 2018 18:07:44 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977792" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Jesus Sanchez-Palencia Subject: [RFC v2 net-next 09/10] igb: Refactor igb_offload_cbs() Date: Wed, 17 Jan 2018 15:06:20 -0800 Message-Id: <20180117230621.26074-10-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Split code into a separate function (igb_offload_apply()) that will be used by TBS offload implementation. Signed-off-by: Jesus Sanchez-Palencia --- drivers/net/ethernet/intel/igb/igb_main.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index a955e1723ed5..fc2fc571b87b 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -2462,6 +2462,19 @@ igb_features_check(struct sk_buff *skb, struct net_device *dev, return features; } +static void igb_offload_apply(struct igb_adapter *adapter, s32 queue) +{ + if (!is_fqtss_enabled(adapter)) { + enable_fqtss(adapter, true); + return; + } + + igb_config_tx_modes(adapter, queue); + + if (!is_any_cbs_enabled(adapter)) + enable_fqtss(adapter, false); +} + static int igb_offload_cbs(struct igb_adapter *adapter, struct tc_cbs_qopt_offload *qopt) { @@ -2482,15 +2495,7 @@ static int igb_offload_cbs(struct igb_adapter *adapter, if (err) return err; - if (is_fqtss_enabled(adapter)) { - igb_config_tx_modes(adapter, qopt->queue); - - if (!is_any_cbs_enabled(adapter)) - enable_fqtss(adapter, false); - - } else { - enable_fqtss(adapter, true); - } + igb_offload_apply(adapter, qopt->queue); return 0; } From patchwork Wed Jan 17 23:06:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesus Sanchez-Palencia X-Patchwork-Id: 862635 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=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zMN6j33ssz9s7v for ; Thu, 18 Jan 2018 10:08:13 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754527AbeAQXIK (ORCPT ); Wed, 17 Jan 2018 18:08:10 -0500 Received: from mga06.intel.com ([134.134.136.31]:63122 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754196AbeAQXHo (ORCPT ); Wed, 17 Jan 2018 18:07:44 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2018 15:07:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,374,1511856000"; d="scan'208";a="166977794" Received: from darjeeling.jf.intel.com ([10.7.159.64]) by orsmga004.jf.intel.com with ESMTP; 17 Jan 2018 15:07:40 -0800 From: Jesus Sanchez-Palencia To: netdev@vger.kernel.org Cc: jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, vinicius.gomes@intel.com, richardcochran@gmail.com, intel-wired-lan@lists.osuosl.org, anna-maria@linutronix.de, henrik@austad.us, tglx@linutronix.de, john.stultz@linaro.org, andre.guedes@intel.com, ivan.briano@intel.com, levi.pearson@harman.com, Jesus Sanchez-Palencia Subject: [RFC v2 net-next 10/10] igb: Add support for TBS offload Date: Wed, 17 Jan 2018 15:06:21 -0800 Message-Id: <20180117230621.26074-11-jesus.sanchez-palencia@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> References: <20180117230621.26074-1-jesus.sanchez-palencia@intel.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement HW offload support for SO_TXTIME through igb's Launchtime feature. This is done by extending igb_setup_tc() so it supports TC_SETUP_QDISC_TBS and configuring i210 so time based transmit arbitration is enabled. The FQTSS transmission mode added before is extended so strict priority (SP) queues wait for stream reservation (SR) ones. igb_config_tx_modes() is extended so it can support enabling/disabling Launchtime following the previous approach used for the credit-based shaper (CBS). As the previous flow, FQTSS transmission mode is enabled automatically by the driver once Launchtime (or CBS, as before) is enabled. Similarly, it's automatically disabled when the feature is disabled for the last queue that had it setup on. The driver just consumes the transmit times from the skbuffs directly, so no special handling is done in case an 'invalid' time is provided. We assume this has been handled by the TBS qdisc already. Signed-off-by: Jesus Sanchez-Palencia --- drivers/net/ethernet/intel/igb/e1000_defines.h | 16 +++ drivers/net/ethernet/intel/igb/igb.h | 1 + drivers/net/ethernet/intel/igb/igb_main.c | 135 ++++++++++++++++++++++--- 3 files changed, 137 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h index 83cabff1e0ab..9e357848c550 100644 --- a/drivers/net/ethernet/intel/igb/e1000_defines.h +++ b/drivers/net/ethernet/intel/igb/e1000_defines.h @@ -1066,6 +1066,22 @@ #define E1000_TQAVCTRL_XMIT_MODE BIT(0) #define E1000_TQAVCTRL_DATAFETCHARB BIT(4) #define E1000_TQAVCTRL_DATATRANARB BIT(8) +#define E1000_TQAVCTRL_DATATRANTIM BIT(9) +#define E1000_TQAVCTRL_SP_WAIT_SR BIT(10) +/* Fetch Time Delta - bits 31:16 + * + * This field holds the value to be reduced from the launch time for + * fetch time decision. The FetchTimeDelta value is defined in 32 ns + * granularity. + * + * This field is 16 bits wide, and so the maximum value is: + * + * 65535 * 32 = 2097120 ~= 2.1 msec + * + * XXX: We are configuring the max value here since we couldn't come up + * with a reason for not doing so. + */ +#define E1000_TQAVCTRL_FETCHTIME_DELTA (0xFFFF << 16) /* TX Qav Credit Control fields */ #define E1000_TQAVCC_IDLESLOPE_MASK 0xFFFF diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 92845692087a..ef2bbef054e8 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -281,6 +281,7 @@ struct igb_ring { u16 count; /* number of desc. in the ring */ u8 queue_index; /* logical index of the ring*/ u8 reg_idx; /* physical index of the ring */ + bool launchtime_enable; /* true if LaunchTime is enabled */ bool cbs_enable; /* indicates if CBS is enabled */ s32 idleslope; /* idleSlope in kbps */ s32 sendslope; /* sendSlope in kbps */ diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index fc2fc571b87b..30243b3250e4 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1684,13 +1684,26 @@ static bool is_any_cbs_enabled(struct igb_adapter *adapter) return false; } +static bool is_any_txtime_enabled(struct igb_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) { + if (adapter->tx_ring[i]->launchtime_enable) + return true; + } + + return false; +} + /** * igb_config_tx_modes - Configure "Qav Tx mode" features on igb * @adapter: pointer to adapter struct * @queue: queue number * - * Configure CBS for a given hardware queue. Parameters are retrieved - * from the correct Tx ring, so igb_save_cbs_params() should be used + * Configure CBS and Launchtime for a given hardware queue. + * Parameters are retrieved from the correct Tx ring, so + * igb_save_cbs_params() and igb_save_txtime_params() should be used * for setting those correctly prior to this function being called. **/ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) @@ -1704,10 +1717,20 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) WARN_ON(hw->mac.type != e1000_i210); WARN_ON(queue < 0 || queue > 1); - if (ring->cbs_enable) { + /* If any of the Qav features is enabled, configure queues as SR and + * with HIGH PRIO. If none is, then configure them with LOW PRIO and + * as SP. + */ + if (ring->cbs_enable || ring->launchtime_enable) { set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_HIGH); set_queue_mode(hw, queue, QUEUE_MODE_STREAM_RESERVATION); + } else { + set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_LOW); + set_queue_mode(hw, queue, QUEUE_MODE_STRICT_PRIORITY); + } + /* If CBS is enabled, set DataTranARB and config its parameters. */ + if (ring->cbs_enable) { /* Always set data transfer arbitration to credit-based * shaper algorithm on TQAVCTRL if CBS is enabled for any of * the queues. @@ -1769,8 +1792,6 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) wr32(E1000_I210_TQAVHC(queue), 0x80000000 + ring->hicredit * 0x7735); } else { - set_tx_desc_fetch_prio(hw, queue, TX_QUEUE_PRIO_LOW); - set_queue_mode(hw, queue, QUEUE_MODE_STRICT_PRIORITY); /* Set idleSlope to zero. */ tqavcc = rd32(E1000_I210_TQAVCC(queue)); @@ -1791,17 +1812,61 @@ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) } } + /* If LaunchTime is enabled, set DataTranTIM. */ + if (ring->launchtime_enable) { + /* Always set DataTranTIM on TQAVCTRL if LaunchTime is enabled + * for any of the SR queues, and configure fetchtime delta. + * XXX NOTE: + * - LaunchTime will be enabled for all SR queues. + * - A fixed offset can be added relative to the launch + * time of all packets if configured at reg LAUNCH_OS0. + * We are keeping it as 0 for now (default value). + */ + tqavctrl = rd32(E1000_I210_TQAVCTRL); + tqavctrl |= E1000_TQAVCTRL_DATATRANTIM | + E1000_TQAVCTRL_FETCHTIME_DELTA; + wr32(E1000_I210_TQAVCTRL, tqavctrl); + } else { + /* If Launchtime is not enabled for any SR queues anymore, + * then clear DataTranTIM on TQAVCTRL and clear fetchtime delta, + * effectively disabling Launchtime. + */ + if (!is_any_txtime_enabled(adapter)) { + tqavctrl = rd32(E1000_I210_TQAVCTRL); + tqavctrl &= ~E1000_TQAVCTRL_DATATRANTIM; + tqavctrl &= ~E1000_TQAVCTRL_FETCHTIME_DELTA; + wr32(E1000_I210_TQAVCTRL, tqavctrl); + } + } + /* XXX: In i210 controller the sendSlope and loCredit parameters from * CBS are not configurable by software so we don't do any 'controller * configuration' in respect to these parameters. */ - netdev_dbg(netdev, "CBS %s: queue %d idleslope %d sendslope %d hiCredit %d locredit %d\n", - (ring->cbs_enable) ? "enabled" : "disabled", queue, + netdev_dbg(netdev, "Qav Tx mode: cbs %s, launchtime %s, queue %d \ + idleslope %d sendslope %d hiCredit %d \ + locredit %d\n", + (ring->cbs_enable) ? "enabled" : "disabled", + (ring->launchtime_enable) ? "enabled" : "disabled", queue, ring->idleslope, ring->sendslope, ring->hicredit, ring->locredit); } +static int igb_save_txtime_params(struct igb_adapter *adapter, int queue, + bool enable) +{ + struct igb_ring *ring; + + if (queue < 0 || queue > adapter->num_tx_queues) + return -EINVAL; + + ring = adapter->tx_ring[queue]; + ring->launchtime_enable = enable; + + return 0; +} + static int igb_save_cbs_params(struct igb_adapter *adapter, int queue, bool enable, int idleslope, int sendslope, int hicredit, int locredit) @@ -1845,10 +1910,11 @@ static void igb_setup_tx_mode(struct igb_adapter *adapter) int i, max_queue; /* Configure TQAVCTRL register: set transmit mode to 'Qav', - * set data fetch arbitration to 'round robin'. + * set data fetch arbitration to 'round robin', set SP_WAIT_SR + * so SP queues wait for SR ones. */ val = rd32(E1000_I210_TQAVCTRL); - val |= E1000_TQAVCTRL_XMIT_MODE; + val |= E1000_TQAVCTRL_XMIT_MODE | E1000_TQAVCTRL_SP_WAIT_SR; val &= ~E1000_TQAVCTRL_DATAFETCHARB; wr32(E1000_I210_TQAVCTRL, val); @@ -2471,7 +2537,7 @@ static void igb_offload_apply(struct igb_adapter *adapter, s32 queue) igb_config_tx_modes(adapter, queue); - if (!is_any_cbs_enabled(adapter)) + if (!is_any_cbs_enabled(adapter) && !is_any_txtime_enabled(adapter)) enable_fqtss(adapter, false); } @@ -2500,6 +2566,30 @@ static int igb_offload_cbs(struct igb_adapter *adapter, return 0; } +static int igb_offload_txtime(struct igb_adapter *adapter, + struct tc_tbs_qopt_offload *qopt) +{ + struct e1000_hw *hw = &adapter->hw; + int err; + + /* Launchtime offloading is only supported by i210 controller. */ + if (hw->mac.type != e1000_i210) + return -EOPNOTSUPP; + + /* Launchtime offloading is only supported by queues 0 and 1. */ + if (qopt->queue < 0 || qopt->queue > 1) + return -EINVAL; + + err = igb_save_txtime_params(adapter, qopt->queue, qopt->enable); + + if (err) + return err; + + igb_offload_apply(adapter, qopt->queue); + + return 0; +} + static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) { @@ -2508,6 +2598,8 @@ static int igb_setup_tc(struct net_device *dev, enum tc_setup_type type, switch (type) { case TC_SETUP_QDISC_CBS: return igb_offload_cbs(adapter, type_data); + case TC_SETUP_QDISC_TBS: + return igb_offload_txtime(adapter, type_data); default: return -EOPNOTSUPP; @@ -5313,11 +5405,14 @@ static void igb_set_itr(struct igb_q_vector *q_vector) } } -static void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens, - u32 type_tucmd, u32 mss_l4len_idx) +static void igb_tx_ctxtdesc(struct igb_ring *tx_ring, + struct igb_tx_buffer *first, + u32 vlan_macip_lens, u32 type_tucmd, + u32 mss_l4len_idx) { struct e1000_adv_tx_context_desc *context_desc; u16 i = tx_ring->next_to_use; + struct timespec64 ts; context_desc = IGB_TX_CTXTDESC(tx_ring, i); @@ -5332,9 +5427,18 @@ static void igb_tx_ctxtdesc(struct igb_ring *tx_ring, u32 vlan_macip_lens, mss_l4len_idx |= tx_ring->reg_idx << 4; context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); - context_desc->seqnum_seed = 0; context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd); context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx); + + /* We assume there is always a valid tx time available. Invalid times + * should have been handled by the upper layers. + */ + if (tx_ring->launchtime_enable) { + ts = ns_to_timespec64(first->skb->tstamp); + context_desc->seqnum_seed = cpu_to_le32(ts.tv_nsec / 32); + } else { + context_desc->seqnum_seed = 0; + } } static int igb_tso(struct igb_ring *tx_ring, @@ -5417,7 +5521,8 @@ static int igb_tso(struct igb_ring *tx_ring, vlan_macip_lens |= (ip.hdr - skb->data) << E1000_ADVTXD_MACLEN_SHIFT; vlan_macip_lens |= first->tx_flags & IGB_TX_FLAGS_VLAN_MASK; - igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx); + igb_tx_ctxtdesc(tx_ring, first, vlan_macip_lens, + type_tucmd, mss_l4len_idx); return 1; } @@ -5472,7 +5577,7 @@ static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first) vlan_macip_lens |= skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT; vlan_macip_lens |= first->tx_flags & IGB_TX_FLAGS_VLAN_MASK; - igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, 0); + igb_tx_ctxtdesc(tx_ring, first, vlan_macip_lens, type_tucmd, 0); } #define IGB_SET_FLAG(_input, _flag, _result) \