* [PATCH RFC V1 net-next 0/6] Time based packet transmission
From: Richard Cochran @ 2017-09-18 7:41 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, intel-wired-lan, Andre Guedes, Anna-Maria Gleixner,
David Miller, Henrik Austad, Jesus Sanchez-Palencia, John Stultz,
Thomas Gleixner, Vinicius Costa Gomes
This series is an early RFC that introduces a new socket option
allowing time based transmission of packets. This option will be
useful in implementing various real time protocols over Ethernet,
including but not limited to P802.1Qbv, which is currently finding
its way into 802.1Q.
* Open questions about SO_TXTIME semantics
- What should the kernel do if the dialed Tx time is in the past?
Should the packet be sent ASAP, or should we throw an error?
- Should the kernel inform the user if it detects a missed deadline,
via the error queue for example?
- What should the timescale be for the dialed Tx time? Should the
kernel select UTC when using the SW Qdisc and the HW time
otherwise? Or should the socket option include a clockid_t?
* Things todo
- Design a Qdisc for purpose of configuring SO_TXTIME. There should
be one option to dial HW offloading or SW best effort.
- Implement the SW best effort variant. Here is my back of the
napkin sketch. Each interface has its own timerqueue keeping the
TXTIME packets in order and a FIFO for all other traffic. A guard
window starts at the earliest deadline minus the maximum MTU minus
a configurable fudge factor. The Qdisc uses a hrtimer to transmit
the next packet in the timerqueue. During the guard window, all
other traffic is defered unless the next packet can be transmitted
before the guard window expires.
* Current limitations
- The driver does not handle out of order packets. If user space
sends a packet with an earlier Tx time, then the code should stop
the queue, reshuffle the descriptors accordingly, and then
restart the queue.
- The driver does not correctly queue up packets in the distant
future. The i210 has a limited time window of +/- 0.5 seconds.
Packets with a Tx time greater than that should be deferred in
order to enqueue them later on.
* Performance measurements
1. Prepared a PC and the Device Under Test (DUT) each with an Intel
i210 card connected with a crossover cable.
2. The DUT was a Pentium(R) D CPU 2.80GHz running PREEMPT_RT
4.9.40-rt30 with about 50 usec maximum latency under cyclictest.
3. Synchronized the DUT's PHC to the PC's PHC using ptp4l.
4. Synchronized the DUT's system clock to its PHC using phc2sys.
5. Started netperf to produce some network load.
6. Measured the arrival time of the packets at the PC's PHC using
hardware time stamping.
I ran ten minute tests both with and without using the so_txtime
option, with a period was 1 millisecond. I then repeated the
so_txtime case but with a 250 microsecond period. The measured
offset from the expected period (in nanoseconds) is shown in the
following table.
| | plain preempt_rt | so_txtime | txtime @ 250 us |
|---------+------------------+---------------+-----------------|
| min: | +1.940800e+04 | +4.720000e+02 | +4.720000e+02 |
| max: | +7.556000e+04 | +5.680000e+02 | +5.760000e+02 |
| pk-pk: | +5.615200e+04 | +9.600000e+01 | +1.040000e+02 |
| mean: | +3.292776e+04 | +5.072274e+02 | +5.073602e+02 |
| stddev: | +6.514709e+03 | +1.310849e+01 | +1.507144e+01 |
| count: | 600000 | 600000 | 2400000 |
Using so_txtime, the peak to peak jitter is about 100 nanoseconds,
independent of the period. In contrast, plain preempt_rt shows a
jitter of of 56 microseconds. The average delay of 507 nanoseconds
when using so_txtime is explained by the documented input and output
delays on the i210 cards.
The test program is appended, below. If anyone is interested in
reproducing this test, I can provide helper scripts.
Thanks,
Richard
Richard Cochran (6):
net: Add a new socket option for a future transmit time.
net: skbuff: Add a field to support time based transmission.
net: ipv4: raw: Hook into time based transmission.
net: ipv4: udp: Hook into time based transmission.
net: packet: Hook into time based transmission.
net: igb: Implement time based transmission.
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/powerpc/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 ++
drivers/net/ethernet/intel/igb/e1000_82575.h | 1 +
drivers/net/ethernet/intel/igb/e1000_defines.h | 68 +++++++++++++++++++++++++-
drivers/net/ethernet/intel/igb/e1000_regs.h | 5 ++
drivers/net/ethernet/intel/igb/igb.h | 3 +-
drivers/net/ethernet/intel/igb/igb_main.c | 68 +++++++++++++++++++++++---
include/linux/skbuff.h | 2 +
include/net/sock.h | 2 +
include/uapi/asm-generic/socket.h | 3 ++
net/core/sock.c | 12 +++++
net/ipv4/raw.c | 2 +
net/ipv4/udp.c | 5 +-
net/packet/af_packet.c | 6 +++
23 files changed, 200 insertions(+), 10 deletions(-)
--
2.11.0
---8<---
/*
* This program demonstrates transmission of UDP packets using the
* system TAI timer.
*
* Copyright (C) 2017 linutronix GmbH
*
* Large portions taken from the linuxptp stack.
* Copyright (C) 2011, 2012 Richard Cochran <richardcochran@gmail.com>
*
* Some portions taken from the sgd test program.
* Copyright (C) 2015 linutronix GmbH
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _GNU_SOURCE /*for CPU_SET*/
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <linux/ethtool.h>
#include <linux/net_tstamp.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <netinet/in.h>
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define DEFAULT_PERIOD 1000000
#define DEFAULT_DELAY 500000
#define MCAST_IPADDR "239.1.1.1"
#define UDP_PORT 7788
#ifndef SO_TXTIME
#define SO_TXTIME 61
#endif
#define pr_err(s) fprintf(stderr, s "\n")
#define pr_info(s) fprintf(stdout, s "\n")
static int running = 1, use_so_txtime = 1;
static int period_nsec = DEFAULT_PERIOD;
static int waketx_delay = DEFAULT_DELAY;
static struct in_addr mcast_addr;
static int mcast_bind(int fd, int index)
{
int err;
struct ip_mreqn req;
memset(&req, 0, sizeof(req));
req.imr_ifindex = index;
err = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &req, sizeof(req));
if (err) {
pr_err("setsockopt IP_MULTICAST_IF failed: %m");
return -1;
}
return 0;
}
static int mcast_join(int fd, int index, const struct sockaddr *grp,
socklen_t grplen)
{
int err, off = 0;
struct ip_mreqn req;
struct sockaddr_in *sa = (struct sockaddr_in *) grp;
memset(&req, 0, sizeof(req));
memcpy(&req.imr_multiaddr, &sa->sin_addr, sizeof(struct in_addr));
req.imr_ifindex = index;
err = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req));
if (err) {
pr_err("setsockopt IP_ADD_MEMBERSHIP failed: %m");
return -1;
}
err = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &off, sizeof(off));
if (err) {
pr_err("setsockopt IP_MULTICAST_LOOP failed: %m");
return -1;
}
return 0;
}
static void normalize(struct timespec *ts)
{
while (ts->tv_nsec > 999999999) {
ts->tv_sec += 1;
ts->tv_nsec -= 1000000000;
}
}
static int sk_interface_index(int fd, const char *name)
{
struct ifreq ifreq;
int err;
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name) - 1);
err = ioctl(fd, SIOCGIFINDEX, &ifreq);
if (err < 0) {
pr_err("ioctl SIOCGIFINDEX failed: %m");
return err;
}
return ifreq.ifr_ifindex;
}
static int open_socket(const char *name, struct in_addr mc_addr, short port)
{
struct sockaddr_in addr;
int fd, index, on = 1;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
pr_err("socket failed: %m");
goto no_socket;
}
index = sk_interface_index(fd, name);
if (index < 0)
goto no_option;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
pr_err("setsockopt SO_REUSEADDR failed: %m");
goto no_option;
}
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr))) {
pr_err("bind failed: %m");
goto no_option;
}
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name))) {
pr_err("setsockopt SO_BINDTODEVICE failed: %m");
goto no_option;
}
addr.sin_addr = mc_addr;
if (mcast_join(fd, index, (struct sockaddr *) &addr, sizeof(addr))) {
pr_err("mcast_join failed");
goto no_option;
}
if (mcast_bind(fd, index)) {
goto no_option;
}
if (use_so_txtime && setsockopt(fd, SOL_SOCKET, SO_TXTIME, &on, sizeof(on))) {
pr_err("setsockopt SO_TXTIME failed: %m");
goto no_option;
}
return fd;
no_option:
close(fd);
no_socket:
return -1;
}
static int udp_open(const char *name)
{
int fd;
if (!inet_aton(MCAST_IPADDR, &mcast_addr))
return -1;
fd = open_socket(name, mcast_addr, UDP_PORT);
return fd;
}
static int udp_send(int fd, void *buf, int len, __u64 txtime)
{
union {
char buf[CMSG_SPACE(sizeof(__u64))];
struct cmsghdr align;
} u;
struct sockaddr_in sin;
struct cmsghdr *cmsg;
struct msghdr msg;
struct iovec iov;
ssize_t cnt;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr = mcast_addr;
sin.sin_port = htons(UDP_PORT);
iov.iov_base = buf;
iov.iov_len = len;
memset(&msg, 0, sizeof(msg));
msg.msg_name = &sin;
msg.msg_namelen = sizeof(sin);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
/*
* We specify the transmission time in the CMSG.
*/
if (use_so_txtime) {
msg.msg_control = u.buf;
msg.msg_controllen = sizeof(u.buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SO_TXTIME;
cmsg->cmsg_len = CMSG_LEN(sizeof(__u64));
*((__u64 *) CMSG_DATA(cmsg)) = txtime;
}
cnt = sendmsg(fd, &msg, 0);
if (cnt < 1) {
pr_err("sendmsg failed: %m");
return cnt;
}
return cnt;
}
static unsigned char tx_buffer[256];
static int marker;
static int run_nanosleep(clockid_t clkid, int fd)
{
struct timespec ts;
int cnt, err;
__u64 txtime;
clock_gettime(clkid, &ts);
/* Start one to two seconds in the future. */
ts.tv_sec += 1;
ts.tv_nsec = 1000000000 - waketx_delay;
normalize(&ts);
txtime = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
txtime += waketx_delay;
while (running) {
err = clock_nanosleep(clkid, TIMER_ABSTIME, &ts, NULL);
switch (err) {
case 0:
cnt = udp_send(fd, tx_buffer, sizeof(tx_buffer), txtime);
if (cnt != sizeof(tx_buffer)) {
pr_err("udp_send failed");
}
memset(tx_buffer, marker++, sizeof(tx_buffer));
ts.tv_nsec += period_nsec;
normalize(&ts);
txtime += period_nsec;
break;
case EINTR:
continue;
default:
fprintf(stderr, "clock_nanosleep returned %d: %s",
err, strerror(err));
return err;
}
}
return 0;
}
static int set_realtime(pthread_t thread, int priority, int cpu)
{
cpu_set_t cpuset;
struct sched_param sp;
int err, policy;
int min = sched_get_priority_min(SCHED_FIFO);
int max = sched_get_priority_max(SCHED_FIFO);
fprintf(stderr, "min %d max %d\n", min, max);
if (priority < 0) {
return 0;
}
err = pthread_getschedparam(thread, &policy, &sp);
if (err) {
fprintf(stderr, "pthread_getschedparam: %s\n", strerror(err));
return -1;
}
sp.sched_priority = priority;
err = pthread_setschedparam(thread, SCHED_FIFO, &sp);
if (err) {
fprintf(stderr, "pthread_setschedparam: %s\n", strerror(err));
return -1;
}
if (cpu < 0) {
return 0;
}
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
err = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
if (err) {
fprintf(stderr, "pthread_setaffinity_np: %s\n", strerror(err));
return -1;
}
return 0;
}
static void usage(char *progname)
{
fprintf(stderr,
"\n"
"usage: %s [options]\n"
"\n"
" -c [num] run on CPU 'num'\n"
" -d [num] delay from wake up to transmission in nanoseconds (default %d)\n"
" -h prints this message and exits\n"
" -i [name] use network interface 'name'\n"
" -p [num] run with RT priorty 'num'\n"
" -P [num] period in nanoseconds (default %d)\n"
" -u do not use SO_TXTIME\n"
"\n",
progname, DEFAULT_DELAY, DEFAULT_PERIOD);
}
int main(int argc, char *argv[])
{
int c, cpu = -1, err, fd, priority = -1;
clockid_t clkid = CLOCK_TAI;
char *iface = NULL, *progname;
/* Process the command line arguments. */
progname = strrchr(argv[0], '/');
progname = progname ? 1 + progname : argv[0];
while (EOF != (c = getopt(argc, argv, "c:d:hi:p:P:u"))) {
switch (c) {
case 'c':
cpu = atoi(optarg);
break;
case 'd':
waketx_delay = atoi(optarg);
break;
case 'h':
usage(progname);
return 0;
case 'i':
iface = optarg;
break;
case 'p':
priority = atoi(optarg);
break;
case 'P':
period_nsec = atoi(optarg);
break;
case 'u':
use_so_txtime = 0;
break;
case '?':
usage(progname);
return -1;
}
}
if (waketx_delay > 999999999 || waketx_delay < 0) {
pr_err("Bad wake up to transmission delay.");
usage(progname);
return -1;
}
if (period_nsec < 1000) {
pr_err("Bad period.");
usage(progname);
return -1;
}
if (!iface) {
pr_err("Need a network interface.");
usage(progname);
return -1;
}
if (set_realtime(pthread_self(), priority, cpu)) {
return -1;
}
fd = udp_open(iface);
if (fd < 0) {
return -1;
}
err = run_nanosleep(clkid, fd);
close(fd);
return err;
}
^ permalink raw reply
* [PATCH RFC V1 net-next 2/6] net: skbuff: Add a field to support time based transmission.
From: Richard Cochran @ 2017-09-18 7:41 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, intel-wired-lan, Andre Guedes, Anna-Maria Gleixner,
David Miller, Henrik Austad, Jesus Sanchez-Palencia, John Stultz,
Thomas Gleixner, Vinicius Costa Gomes
In-Reply-To: <cover.1505719061.git.rcochran@linutronix.de>
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
---
include/linux/skbuff.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 72299ef00061..bc7f7dcbb413 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -635,6 +635,7 @@ typedef unsigned char *sk_buff_data_t;
* @dst_pending_confirm: need to confirm neighbour
* @napi_id: id of the NAPI struct this skb came from
* @secmark: security marking
+ * @transmit_time: desired future transmission time in nanoseconds
* @mark: Generic packet mark
* @vlan_proto: vlan encapsulation protocol
* @vlan_tci: vlan tag control information
@@ -804,6 +805,7 @@ struct sk_buff {
#ifdef CONFIG_NETWORK_SECMARK
__u32 secmark;
#endif
+ __u64 transmit_time;
union {
__u32 mark;
--
2.11.0
^ permalink raw reply related
* [PATCH RFC V1 net-next 3/6] net: ipv4: raw: Hook into time based transmission.
From: Richard Cochran @ 2017-09-18 7:41 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, intel-wired-lan, Andre Guedes, Anna-Maria Gleixner,
David Miller, Henrik Austad, Jesus Sanchez-Palencia, John Stultz,
Thomas Gleixner, Vinicius Costa Gomes
In-Reply-To: <cover.1505719061.git.rcochran@linutronix.de>
For raw packets, copy the desired future transmit time from the CMSG
cookie into the skb.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
---
net/ipv4/raw.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 33b70bfd1122..f6805973629b 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->transmit_time = sockc->transmit_time;
skb_dst_set(skb, &rt->dst);
*rtp = NULL;
@@ -555,6 +556,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;
--
2.11.0
^ permalink raw reply related
* [PATCH RFC V1 net-next 5/6] net: packet: Hook into time based transmission.
From: Richard Cochran @ 2017-09-18 7:41 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, intel-wired-lan, Andre Guedes, Anna-Maria Gleixner,
David Miller, Henrik Austad, Jesus Sanchez-Palencia, John Stultz,
Thomas Gleixner, Vinicius Costa Gomes
In-Reply-To: <cover.1505719061.git.rcochran@linutronix.de>
For raw layer-2 packets, copy the desired future transmit time from
the CMSG cookie into the skb.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
---
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 c26172995511..342c6cc81a42 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1984,6 +1984,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);
@@ -1995,6 +1996,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->transmit_time = sockc.transmit_time;
sock_tx_timestamp(sk, sockc.tsflags, &skb_shinfo(skb)->tx_flags);
@@ -2492,6 +2494,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->transmit_time = sockc->transmit_time;
sock_tx_timestamp(&po->sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags);
skb_shinfo(skb)->destructor_arg = ph.raw;
@@ -2668,6 +2671,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);
@@ -2863,6 +2867,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) {
@@ -2934,6 +2939,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->transmit_time = sockc.transmit_time;
if (po->has_vnet_hdr) {
err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
--
2.11.0
^ permalink raw reply related
* [PATCH RFC V1 net-next 6/6] net: igb: Implement time based transmission.
From: Richard Cochran @ 2017-09-18 7:41 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, intel-wired-lan, Andre Guedes, Anna-Maria Gleixner,
David Miller, Henrik Austad, Jesus Sanchez-Palencia, John Stultz,
Thomas Gleixner, Vinicius Costa Gomes
In-Reply-To: <cover.1505719061.git.rcochran@linutronix.de>
This patch configures the i210 transmit queues to reserve the first queue
for time based transmit arbitration, placing all other traffic into the
second queue. This configuration is hard coded and does not make use of
the two spare queues.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
---
drivers/net/ethernet/intel/igb/e1000_82575.h | 1 +
drivers/net/ethernet/intel/igb/e1000_defines.h | 68 +++++++++++++++++++++++++-
drivers/net/ethernet/intel/igb/e1000_regs.h | 5 ++
drivers/net/ethernet/intel/igb/igb.h | 3 +-
drivers/net/ethernet/intel/igb/igb_main.c | 68 +++++++++++++++++++++++---
5 files changed, 136 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h
index acf06051e111..4c107377540d 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.h
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.h
@@ -159,6 +159,7 @@ struct e1000_adv_tx_context_desc {
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
/* Tx Queue Arbitration Priority 0=low, 1=high */
+#define E1000_TXDCTL_HIGH_PRIORITY 0x08000000
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 1de82f247312..51ab8d0b3dd6 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -352,8 +352,35 @@
/* Timestamp in Rx buffer */
#define E1000_RXPBS_CFG_TS_EN 0x80000000
-#define I210_RXPBSIZE_DEFAULT 0x000000A2 /* RXPBSIZE default */
-#define I210_TXPBSIZE_DEFAULT 0x04000014 /* TXPBSIZE default */
+/*
+ * Internal Packet Buffer Size Registers
+ * For transmit, Section 7.2.7.7 on page 312 recommends 8, 8, 4, and 4 KB.
+ * TXPB[0-3]SIZE are in KB for TxQ[0-3].
+ */
+#define RXPBSIZE 0x22
+#define BMC2OSPBSIZE 0x02
+#define TXPB0SIZE 8
+#define TXPB1SIZE 12
+#define TXPB2SIZE 0
+#define TXPB3SIZE 0
+#define OS2BMCPBSIZE 4
+
+#define TOTAL_RXTX_PBSIZE \
+ (RXPBSIZE + BMC2OSPBSIZE + \
+ TXPB0SIZE + TXPB1SIZE + TXPB2SIZE + TXPB3SIZE + OS2BMCPBSIZE)
+
+#if TOTAL_RXTX_PBSIZE > 60
+#error RX TX PBSIZE exceeds 60 KB.
+#elif TOTAL_RXTX_PBSIZE < 60
+#error RX TX PBSIZE too small.
+#endif
+
+#define I210_TXPBSIZE_DEFAULT \
+ (TXPB0SIZE | (TXPB1SIZE << 6) | (TXPB2SIZE << 12) | \
+ (TXPB3SIZE << 18) | (OS2BMCPBSIZE << 24))
+
+#define I210_RXPBSIZE_DEFAULT \
+ (RXPBSIZE | (BMC2OSPBSIZE << 6))
/* SerDes Control */
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
@@ -1051,4 +1078,41 @@
#define E1000_VLAPQF_P_VALID(_n) (0x1 << (3 + (_n) * 4))
#define E1000_VLAPQF_QUEUE_MASK 0x03
+/* DMA TX Maximum Packet Size */
+#define E1000_DMA_TX_MAXIMUM_PACKET_SIZE (1536 >> 6) /* Units of 64 bytes. */
+
+/* TX Qav Credit Control fields */
+#define E1000_TQAVCC_QUEUEMODE_STREAM_RESERVATION BIT(31)
+
+/* Tx Qav Control */
+#define E1000_TQAVCTRL_TRANSMITMODE_QAV BIT(0)
+#define E1000_TQAVCTRL_1588_STAT_EN BIT(2)
+#define E1000_TQAVCTRL_DATA_FETCH_ARB_MOSTEMPTY BIT(4)
+#define E1000_TQAVCTRL_DATA_TRAN_ARB_CREDITSHAPER BIT(8)
+#define E1000_TQAVCTRL_DATA_TRAN_TIM BIT(9)
+#define E1000_TQAVCTRL_SP_WAIT_SR BIT(10)
+#define E1000_TQAVCTRL_FETCH_TIM_DELTA_SHIFT 16
+/*
+ * 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 msec
+ *
+ * Is there any reason not to dial max here?
+ */
+#define E1000_FETCH_TIME_DELTA 0xffff
+
+#define E1000_DEFAULT_TQAVCTRL ( \
+ E1000_TQAVCTRL_TRANSMITMODE_QAV | \
+ E1000_TQAVCTRL_DATA_FETCH_ARB_MOSTEMPTY | \
+ E1000_TQAVCTRL_DATA_TRAN_TIM | \
+ E1000_TQAVCTRL_SP_WAIT_SR | \
+ (E1000_FETCH_TIME_DELTA << E1000_TQAVCTRL_FETCH_TIM_DELTA_SHIFT) \
+)
+
#endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 58adbf234e07..a2ac3331877c 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -421,6 +421,11 @@ do { \
#define E1000_I210_FLA 0x1201C
+#define E1000_I210_TQAVCC0 0x3004
+#define E1000_I210_TQAVCC1 0x3044
+#define E1000_I210_DTXMXPKTSZ 0x355C /* DMA TX Maximum Packet Size */
+#define E1000_I210_TQAVCTRL 0x3570 /* Tx Qav Control */
+
#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 06ffb2bc713e..95f20eee8194 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -328,7 +328,8 @@ enum e1000_ring_flags_t {
IGB_RING_FLAG_RX_SCTP_CSUM,
IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
IGB_RING_FLAG_TX_CTX_IDX,
- IGB_RING_FLAG_TX_DETECT_HANG
+ IGB_RING_FLAG_TX_DETECT_HANG,
+ IGB_RING_FLAG_HIGH_PRIORITY
};
#define ring_uses_large_buffer(ring) \
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index fd4a46b03cc8..69c877290d52 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1598,6 +1598,40 @@ static void igb_get_hw_control(struct igb_adapter *adapter)
ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
}
+static void igb_qav_config(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ /*
+ * Global Qav configuration (see 7.2.7.7 on page 312)
+ */
+ wr32(E1000_I210_DTXMXPKTSZ, 1536 >> 6);
+ wr32(E1000_I210_TQAVCTRL, (u32) E1000_DEFAULT_TQAVCTRL);
+
+ /*
+ * Per Queue (0/1) Qav configuration
+ *
+ * Note: Queue0 QueueMode must be set to 1
+ * when TransmitMode is set to Qav.
+ */
+ wr32(E1000_I210_TQAVCC0, E1000_TQAVCC_QUEUEMODE_STREAM_RESERVATION);
+}
+
+static u16 igb_select_queue(struct net_device *netdev, struct sk_buff *skb,
+ void *accel, select_queue_fallback_t fallback)
+{
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (hw->mac.type != e1000_i210)
+ return fallback(netdev, skb);
+
+ if (skb->transmit_time)
+ return 0;
+ else
+ return 1;
+}
+
/**
* igb_configure - configure the hardware for RX and TX
* @adapter: private board structure
@@ -1616,6 +1650,8 @@ static void igb_configure(struct igb_adapter *adapter)
igb_setup_mrqc(adapter);
igb_setup_rctl(adapter);
+ igb_qav_config(adapter);
+
igb_nfc_filter_restore(adapter);
igb_configure_tx(adapter);
igb_configure_rx(adapter);
@@ -2175,6 +2211,7 @@ static const struct net_device_ops igb_netdev_ops = {
.ndo_set_features = igb_set_features,
.ndo_fdb_add = igb_ndo_fdb_add,
.ndo_features_check = igb_features_check,
+ .ndo_select_queue = igb_select_queue,
};
/**
@@ -3062,7 +3099,11 @@ static void igb_init_queue_configuration(struct igb_adapter *adapter)
break;
}
- adapter->rss_queues = min_t(u32, max_rss_queues, num_online_cpus());
+ /*
+ * For time based Tx, we must configure four Tx queues.
+ */
+ adapter->rss_queues = hw->mac.type == e1000_i210 ?
+ max_rss_queues : min_t(u32, max_rss_queues, num_online_cpus());
igb_set_flag_queue_pairs(adapter, max_rss_queues);
}
@@ -3462,6 +3503,9 @@ void igb_configure_tx_ring(struct igb_adapter *adapter,
memset(ring->tx_buffer_info, 0,
sizeof(struct igb_tx_buffer) * ring->count);
+ if (ring->flags & IGB_RING_FLAG_HIGH_PRIORITY)
+ txdctl |= E1000_TXDCTL_HIGH_PRIORITY;
+
txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
wr32(E1000_TXDCTL(reg_idx), txdctl);
}
@@ -3476,6 +3520,11 @@ static void igb_configure_tx(struct igb_adapter *adapter)
{
int i;
+ /*
+ * Reserve the first queue for time based Tx.
+ */
+ adapter->tx_ring[0]->flags |= IGB_RING_FLAG_HIGH_PRIORITY;
+
for (i = 0; i < adapter->num_tx_queues; i++)
igb_configure_tx_ring(adapter, adapter->tx_ring[i]);
}
@@ -4948,11 +4997,12 @@ 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);
@@ -4967,9 +5017,15 @@ 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);
+
+ if (tx_ring->flags & IGB_RING_FLAG_HIGH_PRIORITY && tx_ring->reg_idx == 0) {
+ ts = ns_to_timespec64(first->skb->transmit_time);
+ 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,
@@ -5052,7 +5108,7 @@ 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;
}
@@ -5107,7 +5163,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) \
--
2.11.0
^ permalink raw reply related
* [PATCH RFC V1 net-next 1/6] net: Add a new socket option for a future transmit time.
From: Richard Cochran @ 2017-09-18 7:41 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, intel-wired-lan, Andre Guedes, Anna-Maria Gleixner,
David Miller, Henrik Austad, Jesus Sanchez-Palencia, John Stultz,
Thomas Gleixner, Vinicius Costa Gomes
In-Reply-To: <cover.1505719061.git.rcochran@linutronix.de>
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).
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
---
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/powerpc/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 | 12 ++++++++++++
14 files changed, 50 insertions(+)
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index c6133a045352..4dfacba7820e 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -111,4 +111,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 9abf02d6855a..ccf79fe9f35a 100644
--- a/arch/frv/include/uapi/asm/socket.h
+++ b/arch/frv/include/uapi/asm/socket.h
@@ -104,5 +104,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 002eb85a6941..2da305fa85ee 100644
--- a/arch/ia64/include/uapi/asm/socket.h
+++ b/arch/ia64/include/uapi/asm/socket.h
@@ -113,4 +113,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 e268e51a38d1..4d4cde60c520 100644
--- a/arch/m32r/include/uapi/asm/socket.h
+++ b/arch/m32r/include/uapi/asm/socket.h
@@ -104,4 +104,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 6c755bc07975..b6e13bbf970c 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -122,4 +122,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 ac82a3f26dbf..0234496dc969 100644
--- a/arch/mn10300/include/uapi/asm/socket.h
+++ b/arch/mn10300/include/uapi/asm/socket.h
@@ -104,4 +104,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 3b2bf7ae703b..e2a282fefcd6 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -103,4 +103,7 @@
#define SO_ZEROCOPY 0x4035
+#define SO_TXTIME 0x4036
+#define SCM_TXTIME SO_TXTIME
+
#endif /* _UAPI_ASM_SOCKET_H */
diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h
index 3c590c7c42c0..55718129ab06 100644
--- a/arch/powerpc/include/uapi/asm/socket.h
+++ b/arch/powerpc/include/uapi/asm/socket.h
@@ -17,4 +17,7 @@
#include <asm-generic/socket.h>
+#define SO_TXTIME 54
+#define SCM_TXTIME SO_TXTIME
+
#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h
index a56916c83565..bfcb29ccf33a 100644
--- a/arch/s390/include/uapi/asm/socket.h
+++ b/arch/s390/include/uapi/asm/socket.h
@@ -110,4 +110,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 b2f5c50d0947..2217187f80f2 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -100,6 +100,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 220059999e74..36bdbd8bd6ca 100644
--- a/arch/xtensa/include/uapi/asm/socket.h
+++ b/arch/xtensa/include/uapi/asm/socket.h
@@ -115,4 +115,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 03a362568357..1c378db1060f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -778,6 +778,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))
@@ -1558,6 +1559,7 @@ void sock_kzfree_s(struct sock *sk, void *mem, int size);
void sk_send_sigurg(struct sock *sk);
struct sockcm_cookie {
+ u64 transmit_time;
u32 mark;
u16 tsflags;
};
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index e47c9e436221..d32e3e1bf4b6 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -106,4 +106,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 9b7b6bbb2a23..d916a4c238dd 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1059,6 +1059,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;
@@ -2115,6 +2122,11 @@ 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 (!sock_flag(sk, SOCK_TXTIME))
+ return -EINVAL;
+ sockc->transmit_time = *(u64 *)CMSG_DATA(cmsg);
+ break;
/* SCM_RIGHTS and SCM_CREDENTIALS are semantically in SOL_UNIX. */
case SCM_RIGHTS:
case SCM_CREDENTIALS:
--
2.11.0
^ permalink raw reply related
* [PATCH RFC V1 net-next 4/6] net: ipv4: udp: Hook into time based transmission.
From: Richard Cochran @ 2017-09-18 7:41 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, intel-wired-lan, Andre Guedes, Anna-Maria Gleixner,
David Miller, Henrik Austad, Jesus Sanchez-Palencia, John Stultz,
Thomas Gleixner, Vinicius Costa Gomes
In-Reply-To: <cover.1505719061.git.rcochran@linutronix.de>
For udp packets, copy the desired future transmit time from the CMSG
cookie into the skb.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
---
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 ef29df8648e4..669f63495877 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -949,6 +949,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;
@@ -1050,8 +1051,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->transmit_time = ipc.sockc.transmit_time;
err = udp_send_skb(skb, fl4);
+ }
goto out;
}
--
2.11.0
^ permalink raw reply related
* Re: Page allocator bottleneck
From: Aaron Lu @ 2017-09-18 7:44 UTC (permalink / raw)
To: Tariq Toukan
Cc: Jesper Dangaard Brouer, David Miller, Mel Gorman, Eric Dumazet,
Alexei Starovoitov, Saeed Mahameed, Eran Ben Elisha,
Linux Kernel Network Developers, Andrew Morton, Michal Hocko,
linux-mm, Dave Hansen
In-Reply-To: <20170918073447.GB4107@intel.com>
On Mon, Sep 18, 2017 at 03:34:47PM +0800, Aaron Lu wrote:
> On Sun, Sep 17, 2017 at 07:16:15PM +0300, Tariq Toukan wrote:
> >
> > It's nice to have the option to dynamically play with the parameter.
> > But maybe we should also think of changing the default fraction guaranteed
> > to the PCP, so that unaware admins of networking servers would also benefit.
>
> I collected some performance data with will-it-scale/page_fault1 process
> mode on different machines with different pcp->batch sizes, starting
> from the default 31(calculated by zone_batchsize(), 31 is the standard
> value for any zone that has more than 1/2MiB memory), then incremented
> by 31 upwards till 527. PCP's upper limit is 6*batch.
>
> An image is plotted and attached: batch_full.png(full here means the
> number of process started equals to CPU number).
To be clear: X-axis is the value of batch size(31, 62, 93, ..., 527),
Y-axis is the value of per_process_ops, generated by will-it-scale,
higher is better.
>
> From the image:
> - For EX machines, they all see throughput increase with increased batch
> size and peaked at around batch_size=310, then fall;
> - For EP machines, Haswell-EP and Broadwell-EP also see throughput
> increase with increased batch size and peaked at batch_size=279, then
> fall, batch_size=310 also delivers pretty good result. Skylake-EP is
> quite different in that it doesn't see any obvious throughput increase
> after batch_size=93, though the trend is still increasing, but in a very
> small way and finally peaked at batch_size=403, then fall.
> Ivybridge EP behaves much like desktop ones.
> - For Desktop machines, they do not see any obvious changes with
> increased batch_size.
>
> So the default batch size(31) doesn't deliver good enough result, we
> probbaly should change the default value.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCHv2 iproute2 1/2] lib/libnetlink: re malloc buff if size is not enough
From: Michal Kubecek @ 2017-09-18 7:55 UTC (permalink / raw)
To: Hangbin Liu; +Cc: netdev, Stephen Hemminger, Phil Sutter
In-Reply-To: <1505296780-8444-2-git-send-email-liuhangbin@gmail.com>
On Wed, Sep 13, 2017 at 05:59:39PM +0800, Hangbin Liu wrote:
> With commit 72b365e8e0fd ("libnetlink: Double the dump buffer size")
> we doubled the buffer size to support more VFs. But the VFs number is
> increasing all the time. Some customers even use more than 200 VFs now.
>
> We could not double it everytime when the buffer is not enough. Let's just
> not hard code the buffer size and malloc the correct number when running.
>
> Introduce function rtnl_recvmsg() to always return a newly allocated buffer.
> The caller need to free it after using.
>
> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
> Signed-off-by: Phil Sutter <phil@nwl.cc>
> ---
> lib/libnetlink.c | 112 ++++++++++++++++++++++++++++++++++++++-----------------
> 1 file changed, 78 insertions(+), 34 deletions(-)
>
> diff --git a/lib/libnetlink.c b/lib/libnetlink.c
> index be7ac86..e3fa7cf 100644
> --- a/lib/libnetlink.c
> +++ b/lib/libnetlink.c
> @@ -402,6 +402,62 @@ static void rtnl_dump_error(const struct rtnl_handle *rth,
> }
> }
>
> +static int rtnl_recvmsg(int fd, struct msghdr *msg, char **answer)
> +{
> + struct iovec *iov;
> + int len = -1, buf_len = 32768;
> + char *bufp, *buf = NULL;
> +
> + int flag = MSG_PEEK | MSG_TRUNC;
> +
> +realloc:
> + bufp = realloc(buf, buf_len);
> +
> + if (bufp == NULL) {
> + fprintf(stderr, "malloc error: not enough buffer\n");
> + free(buf);
> + return -ENOMEM;
> + }
> + buf = bufp;
> + iov = msg->msg_iov;
> + iov->iov_base = buf;
> + iov->iov_len = buf_len;
> +
> +recv:
> + len = recvmsg(fd, msg, flag);
> +
> + if (len < 0) {
> + if (errno == EINTR || errno == EAGAIN)
> + goto recv;
> + fprintf(stderr, "netlink receive error %s (%d)\n",
> + strerror(errno), errno);
free(buf);
> + return len;
Maybe we should return -errno (saved before calling fprintf()) to be
consistent.
> + }
> +
> + if (len == 0) {
> + fprintf(stderr, "EOF on netlink\n");
free(buf);
> + return -ENODATA;
> + }
> +
> + if (len > buf_len) {
> + buf_len = len;
> + flag = 0;
> + goto realloc;
> + }
> +
> + if (flag != 0) {
> + flag = 0;
> + goto recv;
> + }
This means that even if the default buffer size is sufficient (which
should be most of the time) we make the kernel copy the message to
userspace again. Perhaps we could just call recvmsg() with zero length
to discard the message from the queue in this case. But it's not really
a big problem, I guess.
> +
> + if (answer)
> + *answer = buf;
> + else
> + free(buf);
> +
> + return len;
> +}
> +
> int rtnl_dump_filter_l(struct rtnl_handle *rth,
> const struct rtnl_dump_filter_arg *arg)
> {
> @@ -413,31 +469,18 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth,
> .msg_iov = &iov,
> .msg_iovlen = 1,
> };
> - char buf[32768];
> + char *buf;
> int dump_intr = 0;
>
> - iov.iov_base = buf;
> while (1) {
> int status;
> const struct rtnl_dump_filter_arg *a;
> int found_done = 0;
> int msglen = 0;
>
> - iov.iov_len = sizeof(buf);
> - status = recvmsg(rth->fd, &msg, 0);
> -
> - if (status < 0) {
> - if (errno == EINTR || errno == EAGAIN)
> - continue;
> - fprintf(stderr, "netlink receive error %s (%d)\n",
> - strerror(errno), errno);
> - return -1;
> - }
> -
> - if (status == 0) {
> - fprintf(stderr, "EOF on netlink\n");
> - return -1;
> - }
> + status = rtnl_recvmsg(rth->fd, &msg, &buf);
> + if (status < 0)
> + return status;
>
> if (rth->dump_fp)
> fwrite(buf, 1, NLMSG_ALIGN(status), rth->dump_fp);
> @@ -462,8 +505,10 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth,
>
> if (h->nlmsg_type == NLMSG_DONE) {
> err = rtnl_dump_done(h);
> - if (err < 0)
> + if (err < 0) {
> + free(buf);
> return -1;
> + }
>
> found_done = 1;
> break; /* process next filter */
> @@ -471,19 +516,23 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth,
>
> if (h->nlmsg_type == NLMSG_ERROR) {
> rtnl_dump_error(rth, h);
> + free(buf);
> return -1;
> }
>
> if (!rth->dump_fp) {
> err = a->filter(&nladdr, h, a->arg1);
> - if (err < 0)
> + if (err < 0) {
> + free(buf);
> return err;
> + }
> }
>
> skip_it:
> h = NLMSG_NEXT(h, msglen);
> }
> }
> + free(buf);
We only free the last buffer returned by rtnl_recvmsg() this way. IMHO
this free(buf) should be moved inside the loop.
>
> if (found_done) {
> if (dump_intr)
> @@ -543,7 +592,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
> .msg_iov = &iov,
> .msg_iovlen = 1,
> };
> - char buf[32768] = {};
> + char *buf;
>
> n->nlmsg_seq = seq = ++rtnl->seq;
>
> @@ -556,22 +605,12 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
> return -1;
> }
>
> - iov.iov_base = buf;
> while (1) {
> - iov.iov_len = sizeof(buf);
> - status = recvmsg(rtnl->fd, &msg, 0);
> + status = rtnl_recvmsg(rtnl->fd, &msg, &buf);
> +
> + if (status < 0)
> + return status;
>
> - if (status < 0) {
> - if (errno == EINTR || errno == EAGAIN)
> - continue;
> - fprintf(stderr, "netlink receive error %s (%d)\n",
> - strerror(errno), errno);
> - return -1;
> - }
> - if (status == 0) {
> - fprintf(stderr, "EOF on netlink\n");
> - return -1;
> - }
> if (msg.msg_namelen != sizeof(nladdr)) {
> fprintf(stderr,
> "sender address length == %d\n",
> @@ -585,6 +624,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
> if (l < 0 || len > status) {
> if (msg.msg_flags & MSG_TRUNC) {
> fprintf(stderr, "Truncated message\n");
> + free(buf);
> return -1;
> }
> fprintf(stderr,
> @@ -611,6 +651,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
> if (answer)
> memcpy(answer, h,
> MIN(maxlen, h->nlmsg_len));
> + free(buf);
> return 0;
> }
>
> @@ -619,12 +660,14 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
> rtnl_talk_error(h, err, errfn);
>
> errno = -err->error;
> + free(buf);
> return -1;
> }
>
> if (answer) {
> memcpy(answer, h,
> MIN(maxlen, h->nlmsg_len));
> + free(buf);
> return 0;
> }
>
> @@ -633,6 +676,7 @@ static int __rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
> status -= NLMSG_ALIGN(len);
> h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len));
> }
> + free(buf);
Same as above.
>
> if (msg.msg_flags & MSG_TRUNC) {
> fprintf(stderr, "Message truncated\n");
> --
> 2.5.5
>
^ permalink raw reply
* Re: [RFC net-next 0/5] TSN: Add qdisc-based config interfaces for traffic shapers
From: Richard Cochran @ 2017-09-18 8:02 UTC (permalink / raw)
To: Vinicius Costa Gomes
Cc: netdev, jhs, xiyou.wangcong, jiri, intel-wired-lan, andre.guedes,
ivan.briano, jesus.sanchez-palencia, boon.leong.ong
In-Reply-To: <20170901012625.14838-1-vinicius.gomes@intel.com>
On Thu, Aug 31, 2017 at 06:26:20PM -0700, Vinicius Costa Gomes wrote:
> * Time-aware shaper (802.1Qbv):
I just posted a working alternative showing how to handle 802.1Qbv and
many other Ethernet field buses.
> The idea we are currently exploring is to add a "time-aware", priority based
> qdisc, that also exposes the Tx queues available and provides a mechanism for
> mapping priority <-> traffic class <-> Tx queues in a similar fashion as
> mqprio. We are calling this qdisc 'taprio', and its 'tc' cmd line would be:
>
> $ $ tc qdisc add dev ens4 parent root handle 100 taprio num_tc 4 \
> map 2 2 1 0 3 3 3 3 3 3 3 3 3 3 3 3 \
> queues 0 1 2 3 \
> sched-file gates.sched [base-time <interval>] \
> [cycle-time <interval>] [extension-time <interval>]
>
> <file> is multi-line, with each line being of the following format:
> <cmd> <gate mask> <interval in nanoseconds>
>
> Qbv only defines one <cmd>: "S" for 'SetGates'
>
> For example:
>
> S 0x01 300
> S 0x03 500
>
> This means that there are two intervals, the first will have the gate
> for traffic class 0 open for 300 nanoseconds, the second will have
> both traffic classes open for 500 nanoseconds.
The idea of the schedule file will not work in practice. Consider the
fact that the application wants to deliver time critical data in a
particular slot. How can it find out a) what the time slots are and
b) when the next slot is scheduled? With this Qdisc, it cannot do
this, AFAICT. The admin might delete the file after configuring the
Qdisc!
Using the SO_TXTIME option, the application has total control over the
scheduling. The great advantages of this approach is that we can
support any possible combination of periodic or aperiodic scheduling
and we can support any priority scheme user space dreams up.
For example, one can imaging running two or more loops that only
occasionally collide. When they do collide, which packet should be
sent first? Just let user space decide.
Thanks,
Richard
^ permalink raw reply
* Re: 319554f284dd ("inet: don't use sk_v6_rcv_saddr directly") causes bind port regression
From: Marc Haber @ 2017-09-18 8:02 UTC (permalink / raw)
To: Cole Robinson
Cc: Josef Bacik, Laura Abbott, David S. Miller, Alexey Kuznetsov,
Hideaki YOSHIFUJI, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <10124256-647f-99a5-aa29-8073438a21df@redhat.com>
On Sun, Sep 17, 2017 at 09:17:13AM -0400, Cole Robinson wrote:
> On 09/15/2017 01:51 PM, Josef Bacik wrote:
> > Finally got access to a box to run this down myself. This patch on top of the other patches fixes the problem for me, could you verify it works for you? Thanks,
> >
>
> Yup I can confirm that patch fixes things when applied on top of the
> previous 3 patches. Thanks! Please tag those patches for stable releases
> if appropriate, this is affecting a decent amount of libvirt users
I can also confirm that these four patches fix things for me (on
Debian) as well. Thanks!
I would love to have this in one of Greg's next 4.13 releases.
Greetings
Marc
--
-----------------------------------------------------------------------------
Marc Haber | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany | lose things." Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature | How to make an American Quilt | Fax: *49 6224 1600421
^ permalink raw reply
* Re: [RFC net-next 0/5] TSN: Add qdisc-based config interfaces for traffic shapers
From: Richard Cochran @ 2017-09-18 8:12 UTC (permalink / raw)
To: Vinicius Costa Gomes
Cc: netdev, jhs, xiyou.wangcong, jiri, intel-wired-lan, andre.guedes,
ivan.briano, jesus.sanchez-palencia, boon.leong.ong, henrik, tglx
In-Reply-To: <20170901012625.14838-1-vinicius.gomes@intel.com>
On Thu, Aug 31, 2017 at 06:26:20PM -0700, Vinicius Costa Gomes wrote:
> This patchset is an RFC on a proposal of how the Traffic Control subsystem can
> be used to offload the configuration of traffic shapers into network devices
> that provide support for them in HW. Our goal here is to start upstreaming
> support for features related to the Time-Sensitive Networking (TSN) set of
> standards into the kernel.
Just for the record, here is my score card showing the current status
of TSN support in Linux. Comments and corrections are more welcome.
Thanks,
Richard
| FEATURE | STANDARD | STATUS |
|------------------------------------------------+---------------------+------------------------------|
| Synchronization | 802.1AS-2011 | Implemented in |
| | | - Linux kernel PHC subsystem |
| | | - linuxptp (userspace) |
|------------------------------------------------+---------------------+------------------------------|
| Forwarding and Queuing Enhancements | 802.1Q-2014 sec. 34 | RFC posted (this thread) |
| for Time-Sensitive Streams (FQTSS) | | |
|------------------------------------------------+---------------------+------------------------------|
| Stream Reservation Protocol (SRP) | 802.1Q-2014 sec. 35 | in Open-AVB [1] |
|------------------------------------------------+---------------------+------------------------------|
| Audio Video Transport Protocol (AVTP) | IEEE 1722-2011 | DNE |
|------------------------------------------------+---------------------+------------------------------|
| Audio/Video Device Discovery, Enumeration, | IEEE 1722.1-2013 | jdksavdecc-c [2] |
| Connection Management and Control (AVDECC) | | |
| AVDECC Connection Management Protocol (ACMP) | | |
| AVDECC Enumeration and Control Protocol (AECP) | | |
| MAC Address Acquisition Protocol (MAAP) | | in Open-AVB |
|------------------------------------------------+---------------------+------------------------------|
| Frame Preemption | P802.1Qbu | DNE |
| Scheduled Traffic | P802.1Qbv | RFC posted (SO_TXTIME) |
| SRP Enhancements and Performance Improvements | P802.1Qcc | DNE |
DNE = Does Not Exist (to my knowledge)
1. https://github.com/Avnu/OpenAvnu
(DISCLAIMER from the website:)
It is planned to eventually include the various packet encapsulation types,
protocol discovery daemons, libraries to convert media clocks to AVB clocks
and vice versa, and drivers.
This repository does not include all components required to build a full
production AVB/TSN system (e.g. a turnkey solution to stream stored or live audio
or video content). Some simple example applications are provided which
illustrate the flow - but a professional Audio/Video system requires a full media stack
- including audio and video inputs and outputs, media processing elements, and
various graphical user interfaces. Various companies provide such integrated
solutions.
2. https://github.com/jdkoftinoff/jdksavdecc-c
^ permalink raw reply
* Re: [pktgen script v2 0/2] Add a pktgen sample script of NUMA awareness
From: Jesper Dangaard Brouer @ 2017-09-18 9:06 UTC (permalink / raw)
To: Robert Hoo; +Cc: davem, tariqt, kyle.leet, netdev, robert.hu, brouer
In-Reply-To: <1505651798-106642-1-git-send-email-robert.hu@linux.intel.com>
On Sun, 17 Sep 2017 20:36:36 +0800 Robert Hoo <robert.hu@linux.intel.com> wrote:
> Change log
> v2:
> Rebased to https://github.com/netoptimizer/network-testing/tree/master/pktgen
Hi Robert,
Thank you for submitting this against my git tree[1]. I skimmed the
patches and they looked okay. I'll give them a test run, before I
accept them into my tree.
Later I'll synchronize my pktgen scripts/git-tree with the kernel via
regular patches against DaveM's net-next tree[2] (and I'll try to
remember to give you author credit).
[1] https://github.com/netoptimizer/network-testing/tree/master/pktgen
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/samples/pktgen
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: Page allocator bottleneck
From: Tariq Toukan @ 2017-09-18 9:16 UTC (permalink / raw)
To: Mel Gorman, Tariq Toukan
Cc: David Miller, Jesper Dangaard Brouer, Eric Dumazet,
Alexei Starovoitov, Saeed Mahameed, Eran Ben Elisha,
Linux Kernel Network Developers, Andrew Morton, Michal Hocko,
linux-mm
In-Reply-To: <20170915102320.zqceocmvvkyybekj@techsingularity.net>
On 15/09/2017 1:23 PM, Mel Gorman wrote:
> On Thu, Sep 14, 2017 at 07:49:31PM +0300, Tariq Toukan wrote:
>> Insights: Major degradation between #1 and #2, not getting any
>> close to linerate! Degradation is fixed between #2 and #3. This is
>> because page allocator cannot stand the higher allocation rate. In
>> #2, we also see that the addition of rings (cores) reduces BW (!!),
>> as result of increasing congestion over shared resources.
>>
>
> Unfortunately, no surprises there.
>
>> Congestion in this case is very clear. When monitored in perf top:
>> 85.58% [kernel] [k] queued_spin_lock_slowpath
>>
>
> While it's not proven, the most likely candidate is the zone lock
> and that should be confirmed using a call-graph profile. If so, then
> the suggestion to tune to the size of the per-cpu allocator would
> mitigate the problem.
>
Indeed, I tuned the per-cpu allocator and bottleneck is released.
>> I think that page allocator issues should be discussed separately:
>> 1) Rate: Increase the allocation rate on a single core. 2)
>> Scalability: Reduce congestion and sync overhead between cores.
>>
>> This is clearly the current bottleneck in the network stack receive
>> flow.
>>
>> I know about some efforts that were made in the past two years. For
>> example the ones from Jesper et al.: - Page-pool (not accepted
>> AFAIK).
>
> Indeed not and it would also need driver conversion.
>
>> - Page-allocation bulking.
>
> Prototypes exist but it's pointless without the pool or driver
> conversion so it's in the back burner for the moment.
>
As I already mentioned in another reply (to Jesper), this would
perfectly fit with our Striding RQ feature, as we have large descriptors
that serve several packets, requiring the allocation of several pages at
once. I'd gladly move to using the bulking API.
>> - Optimize order-0 allocations in Per-Cpu-Pages.
>>
>
> This had a prototype that was reverted as it must be able to cope
> with both irq and noirq contexts.
Yeah, I remember that I tested and reported the issue.
Unfortunately I never found the time to
> revisit it but a split there to handle both would mitigate the
> problem. Probably not enough to actually reach line speed though so
> tuning of the per-cpu allocator sizes would still be needed. I don't
> know when I'll get the chance to revisit it. I'm travelling all next
> week and am mostly occupied with other work at the moment that is
> consuming all my concentration.
>
>> I am not an mm expert, but wanted to raise the issue again, to
>> combine the efforts and hear from you guys about status and
>> possible directions.
>
> The recent effort to reduce overhead from stats will help mitigate
> the problem.
I should get more familiar with these stats, check how costly they are,
and whether they can be turned off in Kconfig.
> Finishing the page pool, the bulk allocator and converting drivers
> would be the most likely successful path forward but it's currently
> stalled as everyone that was previously involved is too busy.
>
I think we should consider changing the default allocation of PCP
fraction as well, or implement some smart dynamic heuristic.
This turned on to have significant effect over networking performance.
Many thanks Mel!
Regards,
Tariq
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH net-next 09/11] bnxt_en: bnxt: add TC flower filter offload support
From: Jiri Pirko @ 2017-09-18 9:52 UTC (permalink / raw)
To: Sathya Perla; +Cc: Michael Chan, David Miller, Netdev
In-Reply-To: <CAKvpyk1iV4z_f7cUA8DL1nU772hPtiZC4MtjA9t=S5J=8EcD-A@mail.gmail.com>
Mon, Sep 18, 2017 at 11:43:22AM CEST, sathya.perla@broadcom.com wrote:
>On Mon, Sep 11, 2017 at 7:06 PM, Jiri Pirko <jiri@resnulli.us> wrote:
>> Mon, Aug 28, 2017 at 07:40:33PM CEST, michael.chan@broadcom.com wrote:
>>>From: Sathya Perla <sathya.perla@broadcom.com>
>>>
>>>This patch adds support for offloading TC based flow
>>>rules and actions for the 'flower' classifier in the bnxt_en driver.
>>>It includes logic to parse flow rules and actions received from the
>>>TC subsystem, store them and issue the corresponding
>>>hwrm_cfa_flow_alloc/free FW cmds. L2/IPv4/IPv6 flows and drop,
>>>redir, vlan push/pop actions are supported in this patch.
>>>
>>>In this patch the hwrm_cfa_flow_xxx routines are just stubs.
>>>The code for these routines is introduced in the next patch for easier
>>>review. Also, the code to query the TC/flower action stats will
>>>be introduced in a subsequent patch.
>>
>> Hi.
>>
>> You are missing checks for the offload. Please see nfp as an example:
>> Function nfp_flower_setup_tc:
>>
>> !is_classid_clsact_ingress(cls_flower->common.classid) ||
>> cls_flower->common.chain_index)
>
>Thanks for catching this...will send a patch.
>
>>
>> Do you support both ingress and egress or ingress only?
>
>Ingress only for flower offload.
Cool, the check would resolve it. Thanks!
^ permalink raw reply
* Re: [PATCH net-next] net: remove useless comments in dst.c
From: Sergei Shtylyov @ 2017-09-18 10:24 UTC (permalink / raw)
To: Duan Jiong, netdev; +Cc: weiwan
In-Reply-To: <CALttK1QuA3tSdfSUPoYtoQV5reJdsVOicLX_9iN1TkwY6De6HQ@mail.gmail.com>
Hello!
On 9/18/2017 9:00 AM, Duan Jiong wrote:
> dst gc related code has been removed in commit
> 5b7c9a8ff828, so those comments are no longer
Please also specify the commit's summary line enclosed in ("").
> useful.
>
> Signed-off-by: Duan Jiong <jduan@fiberhome.com>
[...]
MBR, Sergei
^ permalink raw reply
* [PATCH] sunrpc: remove redundant initialization of sock
From: Colin King @ 2017-09-18 11:21 UTC (permalink / raw)
To: J . Bruce Fields, Jeff Layton, Trond Myklebust, Anna Schumaker,
David S . Miller, linux-nfs
Cc: kernel-janitors, netdev
From: Colin Ian King <colin.king@canonical.com>
sock is being initialized and then being almost immediately updated
hence the initialized value is not being used and is redundant. Remove
the initialization. Cleans up clang warning:
warning: Value stored to 'sock' during its initialization is never read
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
net/sunrpc/xprtsock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 9b5de31aa429..c1841f234a71 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2203,7 +2203,7 @@ static void xs_udp_setup_socket(struct work_struct *work)
struct sock_xprt *transport =
container_of(work, struct sock_xprt, connect_worker.work);
struct rpc_xprt *xprt = &transport->xprt;
- struct socket *sock = transport->sock;
+ struct socket *sock;
int status = -EIO;
sock = xs_create_sock(xprt, transport,
--
2.14.1
^ permalink raw reply related
* [PATCH] net_sched: use explicit size of struct tcmsg, remove need to declare tcm
From: Colin King @ 2017-09-18 11:40 UTC (permalink / raw)
To: Jamal Hadi Salim, Cong Wang, Jiri Pirko, David S . Miller, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Pointer tcm is being initialized and is never read, it is only being used
to determine the size of struct tcmsg. Clean this up by removing
variable tcm and explicitly using the sizeof struct tcmsg rather than *tcm.
Cleans up clang warning:
warning: Value stored to 'tcm' during its initialization is never read
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
net/sched/sch_api.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index c6deb74e3d2f..aa82116ed10c 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1500,7 +1500,6 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
int s_idx, s_q_idx;
struct net_device *dev;
const struct nlmsghdr *nlh = cb->nlh;
- struct tcmsg *tcm = nlmsg_data(nlh);
struct nlattr *tca[TCA_MAX + 1];
int err;
@@ -1510,7 +1509,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
idx = 0;
ASSERT_RTNL();
- err = nlmsg_parse(nlh, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
+ err = nlmsg_parse(nlh, sizeof(struct tcmsg), tca, TCA_MAX, NULL, NULL);
if (err < 0)
return err;
--
2.14.1
^ permalink raw reply related
* [net PATCH] bnxt_en: check for ingress qdisc in flower offload
From: Sathya Perla @ 2017-09-18 11:35 UTC (permalink / raw)
To: netdev; +Cc: michael.chan
Check for ingress-only qdisc for flower offload, as other qdiscs
are not supported for flower offload.
Suggested-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Sathya Perla <sathya.perla@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
index ccd699f..7dd3d13 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
@@ -750,6 +750,10 @@ int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
{
int rc = 0;
+ if (!is_classid_clsact_ingress(cls_flower->common.classid) ||
+ cls_flower->common.chain_index)
+ return -EOPNOTSUPP;
+
switch (cls_flower->command) {
case TC_CLSFLOWER_REPLACE:
rc = bnxt_tc_add_flow(bp, src_fid, cls_flower);
--
2.7.4
^ permalink raw reply related
* Re: [RFC net-next 0/5] TSN: Add qdisc-based config interfaces for traffic shapers
From: Henrik Austad @ 2017-09-18 11:46 UTC (permalink / raw)
To: Richard Cochran
Cc: Vinicius Costa Gomes, netdev, jhs, xiyou.wangcong, jiri,
intel-wired-lan, andre.guedes, ivan.briano,
jesus.sanchez-palencia, boon.leong.ong
In-Reply-To: <20170918080214.yrejz67wwnp2pjzf@localhost>
[-- Attachment #1: Type: text/plain, Size: 3289 bytes --]
On Mon, Sep 18, 2017 at 10:02:14AM +0200, Richard Cochran wrote:
> On Thu, Aug 31, 2017 at 06:26:20PM -0700, Vinicius Costa Gomes wrote:
> > * Time-aware shaper (802.1Qbv):
>
> I just posted a working alternative showing how to handle 802.1Qbv and
> many other Ethernet field buses.
Yes, I saw them, grabbing them for testing now - thanks!
> > The idea we are currently exploring is to add a "time-aware", priority based
> > qdisc, that also exposes the Tx queues available and provides a mechanism for
> > mapping priority <-> traffic class <-> Tx queues in a similar fashion as
> > mqprio. We are calling this qdisc 'taprio', and its 'tc' cmd line would be:
> >
> > $ $ tc qdisc add dev ens4 parent root handle 100 taprio num_tc 4 \
> > map 2 2 1 0 3 3 3 3 3 3 3 3 3 3 3 3 \
> > queues 0 1 2 3 \
> > sched-file gates.sched [base-time <interval>] \
> > [cycle-time <interval>] [extension-time <interval>]
> >
> > <file> is multi-line, with each line being of the following format:
> > <cmd> <gate mask> <interval in nanoseconds>
> >
> > Qbv only defines one <cmd>: "S" for 'SetGates'
> >
> > For example:
> >
> > S 0x01 300
> > S 0x03 500
> >
> > This means that there are two intervals, the first will have the gate
> > for traffic class 0 open for 300 nanoseconds, the second will have
> > both traffic classes open for 500 nanoseconds.
>
> The idea of the schedule file will not work in practice. Consider the
> fact that the application wants to deliver time critical data in a
> particular slot. How can it find out a) what the time slots are and
> b) when the next slot is scheduled? With this Qdisc, it cannot do
> this, AFAICT. The admin might delete the file after configuring the
> Qdisc!
>
> Using the SO_TXTIME option, the application has total control over the
> scheduling. The great advantages of this approach is that we can
> support any possible combination of periodic or aperiodic scheduling
> and we can support any priority scheme user space dreams up.
Using SO_TXTIME makes a lot of sense. TSN has a presentation_time, which
you can use to deduce the time it should be transmitted (Class A has a 2ms
latency guarantee, B has 50), but given how TSN uses the timestamp, it will
wrap every 4.3 seconds, using SO_TXTIME allows you to schedule transmission
at a much later time. It should also lessen the dependency on a specific
protocol, which is also good.
> For example, one can imaging running two or more loops that only
> occasionally collide. When they do collide, which packet should be
> sent first? Just let user space decide.
If 2 userspace apps send to the same Tx-queue with the same priority, would
it not make sense to just do FIFO? For all practical purposes, they have
the same importance (same SO_PRIORITY, same SO_TXTIME). If the priority
differs, then they would be directed to different queues, where one queue
will take presedence anyway.
How far into the future would it make sense to schedule packets anyway?
I'll have a look at the other series you just posted!
--
Henrik Austad
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [net PATCH] bnxt_en: check for ingress qdisc in flower offload
From: Jiri Pirko @ 2017-09-18 11:56 UTC (permalink / raw)
To: Sathya Perla; +Cc: netdev, michael.chan
In-Reply-To: <1505734537-6695-1-git-send-email-sathya.perla@broadcom.com>
Mon, Sep 18, 2017 at 01:35:37PM CEST, sathya.perla@broadcom.com wrote:
>Check for ingress-only qdisc for flower offload, as other qdiscs
>are not supported for flower offload.
>
>Suggested-by: Jiri Pirko <jiri@resnulli.us>
>Signed-off-by: Sathya Perla <sathya.perla@broadcom.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
^ permalink raw reply
* RE: [PATCH] net_sched: use explicit size of struct tcmsg, remove need to declare tcm
From: David Laight @ 2017-09-18 12:18 UTC (permalink / raw)
To: 'Colin King', Jamal Hadi Salim, Cong Wang, Jiri Pirko,
David S . Miller, netdev@vger.kernel.org
Cc: kernel-janitors@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20170918114038.29741-1-colin.king@canonical.com>
From: Colin King
> Sent: 18 September 2017 12:41
> Pointer tcm is being initialized and is never read, it is only being used
> to determine the size of struct tcmsg. Clean this up by removing
> variable tcm and explicitly using the sizeof struct tcmsg rather than *tcm.
> Cleans up clang warning:
>
> warning: Value stored to 'tcm' during its initialization is never read
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
> net/sched/sch_api.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index c6deb74e3d2f..aa82116ed10c 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -1500,7 +1500,6 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
> int s_idx, s_q_idx;
> struct net_device *dev;
> const struct nlmsghdr *nlh = cb->nlh;
> - struct tcmsg *tcm = nlmsg_data(nlh);
> struct nlattr *tca[TCA_MAX + 1];
> int err;
>
> @@ -1510,7 +1509,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
> idx = 0;
> ASSERT_RTNL();
>
> - err = nlmsg_parse(nlh, sizeof(*tcm), tca, TCA_MAX, NULL, NULL);
> + err = nlmsg_parse(nlh, sizeof(struct tcmsg), tca, TCA_MAX, NULL, NULL);
Would sizeof(*nlmsg_data(nlh)) be cleaner??
David
^ permalink raw reply
* Re: [PATCH v06 35/36] uapi linux/tls.h: don't include <net/tcp.h> in user space
From: Mikko Rapeli @ 2017-09-18 12:57 UTC (permalink / raw)
To: Dmitry V. Levin
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Dave Watson, Ilya Lesokhin,
Aviad Yehezkel, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170904161510.GA16001-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
On Mon, Sep 04, 2017 at 07:15:11PM +0300, Dmitry V. Levin wrote:
> On Wed, Aug 09, 2017 at 02:25:54AM +0300, Dmitry V. Levin wrote:
> > On Sun, Aug 06, 2017 at 06:44:26PM +0200, Mikko Rapeli wrote:
> > > It is not needed and not part of uapi headers, but causes
> > > user space compilation error:
> > >
> > > fatal error: net/tcp.h: No such file or directory
> > > #include <net/tcp.h>
> > > ^
> > >
> > > Signed-off-by: Mikko Rapeli <mikko.rapeli-X3B1VOXEql0@public.gmane.org>
> > > Cc: Dave Watson <davejwatson-b10kYP2dOMg@public.gmane.org>
> > > Cc: Ilya Lesokhin <ilyal-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> > > Cc: Aviad Yehezkel <aviadye-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> > > ---
> > > include/uapi/linux/tls.h | 2 ++
> > > 1 file changed, 2 insertions(+)
> > >
> > > diff --git a/include/uapi/linux/tls.h b/include/uapi/linux/tls.h
> > > index cc1d21db35d8..d87c698623f2 100644
> > > --- a/include/uapi/linux/tls.h
> > > +++ b/include/uapi/linux/tls.h
> > > @@ -37,7 +37,9 @@
> > > #include <asm/byteorder.h>
> > > #include <linux/socket.h>
> > > #include <linux/tcp.h>
> > > +#ifdef __KERNEL__
> > > #include <net/tcp.h>
> > > +#endif
> >
> > Let's move it to include/net/tls.h instead.
>
> So everybody ignored this and *new* uapi header was released
> in a totally unusable form along with v4.13.
Should issues like these be filed into bugzilla instead?
Maybe emails are easier to ignore than bugzilla tickets.
-Mikko
^ permalink raw reply
* [PATCH net] net: phy: Kconfig: Fix PHY infrastructure menu in menuconfig
From: Jerome Brunet @ 2017-09-18 12:59 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, netdev, linux-kernel, Russell King
Since the integration of PHYLINK, the configuration option which
used to be under the PHY infrastructure menu in menuconfig ended
up one level up (the network device driver section)
By placing PHYLINK option right after PHYLIB entry, it broke the
way Kconfig used to build the menu. See kconfig-language.txt, section
"Menu structure", 2nd method.
This is fixed by placing the PHYLINK option just before PHYLIB.
Fixes: 9525ae83959b ("phylink: add phylink infrastructure")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/Kconfig | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index a9d16a3af514..cd931cf9dcc2 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -160,15 +160,6 @@ config MDIO_XGENE
endif
-menuconfig PHYLIB
- tristate "PHY Device support and infrastructure"
- depends on NETDEVICES
- select MDIO_DEVICE
- help
- Ethernet controllers are usually attached to PHY
- devices. This option provides infrastructure for
- managing PHY devices.
-
config PHYLINK
tristate
depends on NETDEVICES
@@ -179,6 +170,15 @@ config PHYLINK
configuration links, PHYs, and Serdes links with MAC level
autonegotiation modes.
+menuconfig PHYLIB
+ tristate "PHY Device support and infrastructure"
+ depends on NETDEVICES
+ select MDIO_DEVICE
+ help
+ Ethernet controllers are usually attached to PHY
+ devices. This option provides infrastructure for
+ managing PHY devices.
+
if PHYLIB
config SWPHY
--
2.13.5
^ permalink raw reply related
* Re: [PATCH net-next v2 0/7] korina: performance fixes and cleanup
From: Roman Yeryomin @ 2017-09-18 13:02 UTC (permalink / raw)
To: Florian Fainelli; +Cc: netdev
In-Reply-To: <649cd233-d9b8-478b-e742-5da469df8f26@gmail.com>
On 17 September 2017 at 23:09, Florian Fainelli <f.fainelli@gmail.com> wrote:
>
>
> On 09/17/2017 10:23 AM, Roman Yeryomin wrote:
>> Changes from v1:
>> - use GRO instead of increasing ring size
>> - use NAPI_POLL_WEIGHT instead of defining own NAPI_WEIGHT
>> - optimize rx descriptor flags processing
>
> net-next is closed at the moment, but these look like reasonable
> changes, I would just replace patch 7 with a patch that entirely drops
> the driver specific version since that does not serve any purpose in the
> context of an in-kernel driver.
OK
> Some nice clean-ups that you should also consider for future changes:
>
> - reduce the duplication of tests/conditions in korina_send_packet(), a
> lot of them are testing for the same things and setting the same
> descriptor bits
Already doing that :)
> - move korina_tx() to a NAPI context instead of working from hard
> interrupt context
>
> - get rid of the MIPS dma_cache_* calls and instead properly use the
> DMA-API to allocate descriptors and invalidate/write-back skb->data
OK
>>
>> Roman Yeryomin (7):
>> net: korina: don't use overflow and underflow interrupts
>> net: korina: optimize rx descriptor flags processing
>> net: korina: use NAPI_POLL_WEIGHT
>> net: korina: use GRO
>> net: korina: whitespace cleanup
>> net: korina: update authors
>> net: korina: bump version
>>
>> drivers/net/ethernet/korina.c | 230 ++++++++++++++----------------------------
>> 1 file changed, 78 insertions(+), 152 deletions(-)
>>
>
> --
> Florian
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox