From 0ad67c7378990cc56fd17769d6199b4af89a627b Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 22 Jun 2017 16:48:44 +0000 Subject: [PATCH 001/109] Add Apache License header --- src/program/wall/common.lua | 1 + src/program/wall/filter/filter.lua | 1 + src/program/wall/spy/spy.lua | 1 + src/program/wall/wall.lua | 1 + 4 files changed, 4 insertions(+) diff --git a/src/program/wall/common.lua b/src/program/wall/common.lua index 7439635dcb..fe92867451 100644 --- a/src/program/wall/common.lua +++ b/src/program/wall/common.lua @@ -1,3 +1,4 @@ +-- Use of this source code is governed by the Apache 2.0 license; see COPYING. module(..., package.seeall) -- This module provides some common definitions for snabbwall programs diff --git a/src/program/wall/filter/filter.lua b/src/program/wall/filter/filter.lua index c55fe4c2b3..8eba882e16 100644 --- a/src/program/wall/filter/filter.lua +++ b/src/program/wall/filter/filter.lua @@ -1,3 +1,4 @@ +-- Use of this source code is governed by the Apache 2.0 license; see COPYING. module(..., package.seeall) local fw = require("apps.wall.l7fw") diff --git a/src/program/wall/spy/spy.lua b/src/program/wall/spy/spy.lua index 442d4d04cd..c070ead9aa 100644 --- a/src/program/wall/spy/spy.lua +++ b/src/program/wall/spy/spy.lua @@ -1,3 +1,4 @@ +-- Use of this source code is governed by the Apache 2.0 license; see COPYING. module(..., package.seeall) local lib = require("core.lib") diff --git a/src/program/wall/wall.lua b/src/program/wall/wall.lua index bf672f9f4e..3bfd8f242a 100644 --- a/src/program/wall/wall.lua +++ b/src/program/wall/wall.lua @@ -1,3 +1,4 @@ +-- Use of this source code is governed by the Apache 2.0 license; see COPYING. module(..., package.seeall) local lib = require("core.lib") From 752196098c1ab64b012a8a90afb3dadf6c551ee6 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 22 Jun 2017 19:30:57 +0200 Subject: [PATCH 002/109] Rename variables --- src/program/wall/tests/filter-pcaps.test | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/program/wall/tests/filter-pcaps.test b/src/program/wall/tests/filter-pcaps.test index be5b059ca2..0d9a75ff51 100755 --- a/src/program/wall/tests/filter-pcaps.test +++ b/src/program/wall/tests/filter-pcaps.test @@ -13,12 +13,13 @@ readonly mac="01:23:45:67:89:ab" # run a test given the pcap file path, the no. of packets expected to # the output file, the no. packets for the reject file, and a firewall policy function test-filter { + local test_name=$1 n_accepted=$2 n_rejected=$3 n_dropped=$4 rule=$5 output=`mktemp` - echo "TEST $1" - "${mydir}/../../../snabb" wall filter -p -4 $ip4 -6 $ip6 -m $mac -o `mktemp` -r `mktemp` -e "$5" pcap "${datadir}/$1" > $output - if ! (grep "Accepted packets: $2" $output && - grep "Rejected packets: $3" $output && - grep "Dropped packets: $4" $output); then + echo "TEST $test_name" + "${mydir}/../../../snabb" wall filter -p -4 $ip4 -6 $ip6 -m $mac -o `mktemp` -r `mktemp` -e "$rule" pcap "${datadir}/$test_name" > $output + if ! (grep "Accepted packets: $n_accepted" $output && + grep "Rejected packets: $n_rejected" $output && + grep "Dropped packets: $n_dropped" $output); then echo "FAIL" return 1 fi From 4aa32da3eeedfe4783679eb24d189f14c45ebc42 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 22 Jun 2017 19:31:05 +0200 Subject: [PATCH 003/109] Explain filtering rules --- src/program/wall/tests/filter-pcaps.test | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/program/wall/tests/filter-pcaps.test b/src/program/wall/tests/filter-pcaps.test index 0d9a75ff51..511a627cbd 100755 --- a/src/program/wall/tests/filter-pcaps.test +++ b/src/program/wall/tests/filter-pcaps.test @@ -27,7 +27,14 @@ function test-filter { return 0 } +# Reject all DHCPv6 packets and drop all the rest. test-filter "dhcpv6.pcap" 0 6 4 "{ DHCPV6 = 'reject', default = 'drop' }" + +# Reject all HTTP packets and accept all the test. test-filter "v6-http.cap" 51 4 0 "{ HTTP = 'reject', default = 'accept' }" + +# Accept RTP packets which flow_count is equals or higher than 69 and drop otherwise. Drop non RTP packets. test-filter "rtp_example.pcap" 465 0 34 "{ RTP = [[match { flow_count >= 69 => accept; otherwise => drop }]], default = 'drop' }" + +# Reject RTP packets which flow_count is equals or higher than 69 and drop otherwise. Drop non RTP packets. test-filter "rtp_example.pcap" 0 465 34 "{ RTP = [[match { flow_count >= 69 => reject; otherwise => drop }]], default = 'drop' }" From e56e9f829e74de3939840ab3d43327de9765d43e Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 22 Jun 2017 17:13:44 +0000 Subject: [PATCH 004/109] List 'filter' program in wall help --- src/program/wall/README | 1 + 1 file changed, 1 insertion(+) diff --git a/src/program/wall/README b/src/program/wall/README index 71b300cfae..0fc8d43f76 100644 --- a/src/program/wall/README +++ b/src/program/wall/README @@ -5,6 +5,7 @@ Usage: Available subcommands: spy Analyze traffic and report statistics + filter Apply filtering rules to incoming packets. Use --help for per-command usage. Example: From cef61c293f2b3497a4576d0c3f92b065249cb1de Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 22 Jun 2017 17:20:01 +0000 Subject: [PATCH 005/109] Show up filtering examples in 'filter' help --- src/program/wall/filter/README | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/program/wall/filter/README b/src/program/wall/filter/README index 56054e39c5..fbd4f5ccd0 100644 --- a/src/program/wall/filter/README +++ b/src/program/wall/filter/README @@ -26,3 +26,11 @@ Options: -6, --ipv6 Set the IPv6 address of this firewall host -D, --duration Set the duration to run the program (in seconds). --cpu Pin to a particular CPU and appropriate NUMA node + +Example: + +# Reject all HTTP packets and accept all the test. +sudo ./snabb wall filter -e "{ HTTP = 'reject', default = 'accept' }" pcap v6-http.cap + +# Accept RTP packets which flow_count is equals or higher than 69 and drop otherwise. Drop non RTP packets. +sudo ./snabb wall filter -e "{ RTP = [[match { flow_count >= 69 => accept; otherwise => drop }]], default = 'drop' }" pcap rtp_example.pcap From 11403971494340bf050c23ef3bb678207e123501 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 22 Jun 2017 19:27:21 +0200 Subject: [PATCH 006/109] Require root permission --- src/program/wall/tests/filter-pcaps.test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/program/wall/tests/filter-pcaps.test b/src/program/wall/tests/filter-pcaps.test index 511a627cbd..152fd57535 100755 --- a/src/program/wall/tests/filter-pcaps.test +++ b/src/program/wall/tests/filter-pcaps.test @@ -1,4 +1,10 @@ #! /usr/bin/env bash + +if [[ $EUID != 0 ]]; then + echo "This script must be run as root" 1>&2 + exit 1 +fi + set -e shopt -s nullglob From 2198cea8d288c6ecc1e85d0169275fae5cd00b1e Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Wed, 28 Jun 2017 11:20:42 +0200 Subject: [PATCH 007/109] Add Snabbwall copyright notice --- src/program/wall/COPYRIGHT.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/program/wall/COPYRIGHT.md diff --git a/src/program/wall/COPYRIGHT.md b/src/program/wall/COPYRIGHT.md new file mode 100644 index 0000000000..c9eadcd4da --- /dev/null +++ b/src/program/wall/COPYRIGHT.md @@ -0,0 +1,4 @@ +Copyright: 2017, Igalia and the Snabb project. +License: See COPYING. + +Snabbwall development has been kindly funded by NLnet Foundation (https://nlnet.nl/). From 7eaf4aafe988b8ad39d3fc2861364d245d602835 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 7 Aug 2017 21:37:50 +0000 Subject: [PATCH 008/109] Refactor snabbwall test script, remove temp files Fixes issue #1134 --- src/program/wall/tests/filter-pcaps.test | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/program/wall/tests/filter-pcaps.test b/src/program/wall/tests/filter-pcaps.test index 152fd57535..1bb0ab3334 100755 --- a/src/program/wall/tests/filter-pcaps.test +++ b/src/program/wall/tests/filter-pcaps.test @@ -27,10 +27,13 @@ function test-filter { grep "Rejected packets: $n_rejected" $output && grep "Dropped packets: $n_dropped" $output); then echo "FAIL" - return 1 + result=1 + else + echo "SUCCESS" + result=0 fi - echo "SUCCESS" - return 0 + rm $output + return $result } # Reject all DHCPv6 packets and drop all the rest. From efbb5e72c2915bd1fb53f51c17e66c1c34a9a7cc Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Sun, 7 May 2017 20:30:19 -0700 Subject: [PATCH 009/109] First attempt at VMDq for intel_mp --- src/apps/intel_mp/intel_mp.lua | 135 ++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index e1760882c4..44c6ffa8e5 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -22,6 +22,7 @@ local lib = require("core.lib") local bits = lib.bits local tophysical = core.memory.virtual_to_physical local register = require("lib.hardware.register") +local index_set = require("lib.index_set") local counter = require("core.counter") local macaddress = require("lib.macaddress") local shm = require("core.shm") @@ -129,6 +130,7 @@ RTRUP2TC 0x03020 - RW DCB Receive Use rPriority to Traffic Class RTTUP2TC 0x0C800 - RW DCB Transmit User Priority to Traffic Class RTTBCNRC 0x04984 - RW DCB Transmit Rate-Scheduler Config RXCSUM 0x05000 - RW Receive Checksum Control +RFCTL 0x05008 - RW Receive Filter Control Register RXCTRL 0x03000 - RW Receive Control RXDGPC 0x02F50 - RC DMA Good Rx Packet Counter RXDSTATCTRL 0x02F40 - RW Rx DMA Statistic Counter Control @@ -248,6 +250,18 @@ EEC 0x00010 - RW EEPROM-Mode Control Register ]] } +-- table to track index sets for use in VMDq mode per pci address +local vmdq_sets = {} + +-- helper for pool number allocation +local function firsthole(t) + for i = 1, #t+1 do + if t[i] == nil then + return i + end + end +end + Intel = { config = { pciaddr = {required=true}, @@ -292,7 +306,10 @@ function Intel:new (conf) linkup_wait = conf.linkup_wait or self.config.linkup_wait.default, linkup_wait_recheck = conf.linkup_wait_recheck or self.config.linkup_wait_recheck.default, - wait_for_link = conf.wait_for_link + wait_for_link = conf.wait_for_link, + vmdq = conf.vmdq, + poolnum = conf.poolnum, + macaddr = conf.macaddr, } local vendor = lib.firstline(self.path .. "/vendor") @@ -304,6 +321,15 @@ function Intel:new (conf) self.max_q = byid.max_q + -- VMDq checks + assert(not self.vmdq or device == "0x1533", "VMDq not supported on i210") + assert(not self.poolnum or self.vmdq, "Pool number only supported for VMDq") + if self.vmdq then + assert(self.rxq >= 4 * self.poolnum and + self.rxq <= 4 * self.poolnum + 3, + "Pool number and rxq do not match") + end + -- Setup device access self.base, self.fd = pci.map_pci_memory_unlocked(self.pciaddress, 0) self.master = self.fd:flock("ex, nb") @@ -671,6 +697,30 @@ function Intel:sync_stats () end end +-- set MAC address (4.6.10.1.4) +function Intel:set_MAC () + if not self.mac then return end + local mac = macaddress:new(self.mac) + self:add_receive_MAC(mac) + self:set_transmit_MAC(mac) +end + +function Intel:add_receive_MAC (mac) + local mac_set = vmdq_sets[self.pciaddress].mac_set + local mac_index, is_new = mac_set:add(tostring(mac)) + if is_new then + self.r.RAL[mac_index](mac:subbits(0,32)) + self.r.RAH[mac_index](bits({AV=31},mac:subbits(32,48))) + end + self.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)] + :set(bits{Ena=self.poolnum%32}) +end + +function Intel:set_transmit_MAC (mac) + local poolnum = self.poolnum or 0 + self.r.PFVFSPOOF[math.floor(poolnum/8)]:set(bits{MACAS=poolnum%8}) +end + function Intel:rxpackets () return self.r.GPRC() end function Intel:txpackets () return self.r.GPTC() end function Intel:rxmcast () return self.r.MPRC() + self.r.BPRC() end @@ -813,6 +863,11 @@ function Intel1g:init_queue_stats (frame) end end +function Intel1g:vmdq_enable () + -- 011 -> VMDq mode, no RSS + self.r.MRQC:set(bits { VMDq1 = 0, VMDq2 = 1 }) +end + Intel82599.driver = "Intel82599" Intel82599.offsets = { SRRCTL = { @@ -965,9 +1020,87 @@ function Intel82599:init () self.r.CTRL_EXT:set(bits {NS_DIS = 1}) self:rss_enable() + + if self.vmdq then + self:vmdq_enable() + self:set_MAC() + end + self:unlock_sw_sem() end +-- enable VMDq mode, see 4.6.10.1 +-- follows the configuration flow in 4.6.11.3.3 +-- (should only be called on the master instance) +function Intel82599:vmdq_enable () + -- must be set prior to setting MTQC (7.2.1.2.1) + self.r.RTTDCS:set(bits { ARBDIS=6 }) + + -- 1010 -> 32 pools, 4 RSS queues each + self.r.MRQC:set(bits { VMDq = 3, RSS = 1 }) + + -- TODO: not sure this is needed, but it's in intel10g + -- disable RSC (7.11) + self.r.RFCTL:set(bits { RSC_Dis=5 }) + + -- 128 Tx Queues, 64 VMs (4.6.11.3.3) + self.r.MTQC(bits { VT_Ena=1, Num_TC_OR_Q=2 }) + + -- enable virtualization, replication enabled, define default pool + self.r.PFVTCTL(bits { VT_Ena=0, Rpl_En=30, DisDefPool=29 }) + + -- enable VMDq Tx to Rx loopback + self.r.PFDTXGSWC:set(bits { LBE=0 }) + + -- needs to be set for loopback (7.10.3.4) + self.r.FCRTH[0](0x10000) + + -- enable vlan filter (4.6.7, 7.1.1.2) + self.r.VLNCTRL:set(bits { VFE=30 }) + + -- intel10g zeroes out ETQF,ETQS here but they are init to 0 + + -- initialize index sets + vmdq_sets[self.pciaddress] = { + mac_set = index_set:new(127, "MAC address table"), + vlan_set = index_set:new(64, "VLAN Filter table"), + mirror_set = index_set:new(4, "Mirror pool table") } + + -- RTRUP2TC/RTTUP2TC cleared above in init + + -- DMA TX TCP max allowed size requests (set to 1MB) + self.r.DTXMXSZRQ(0xFFF) + + -- disable PFC, enable legacy control flow + self.r.MFLCN(bits { RFCE=3 }) + self.r.FCCFG(bits { TFCE=3 }) + + -- RTTDT2C, RTTPT2C, RTRPT4C cleared above in init() + + -- QDE bit = 0 for all queues + for i = 0, 127 do + self.r.PFQDE(bor(lshift(1,16), lshift(i,8))) + end + + -- clear RTTDT1C, PFVLVF for all pools, set them later + for i = 0, 63 do + self.r.RTTDQSEL(i) + self.r.RTTDT1C(0x00) + end + + -- disable TC arbitrations, enable packet buffer free space monitor + self.r.RTTDCS:set() + self.r.RTTDCS:clr(bits { TDPAC=0, TDRM=4, BPBFSM=23 }) + self.r.RTTDCS:set(bits { VMPAC=1, BDPM=22 }) + self.r.RTTPCS:clr(bits { TPPAC=5, TPRM=8 }) + -- set RTTPCS.ARBD + self.r.RTTPCS:bits(22, 31, 0x244) + self.r.RTRPCS:clr(bits { RAC=2, RRM=1 }) + + -- must be cleared after MTQC configuration (7.2.1.2.1) + self.r.RTTDCS:clr(bits { ARBDIS=6 }) +end + function Intel:debug (args) local args = args or {} local pfx = args.prefix or "DEBUG_" From 60474bcabbbf269c187504a3501f2c4a9264754a Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 8 May 2017 19:54:15 +0000 Subject: [PATCH 010/109] Fix up VMDq mode so that it actually runs --- src/apps/intel_mp/intel_mp.lua | 49 ++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 44c6ffa8e5..bbd584cdc9 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -67,6 +67,9 @@ MPSAR 0x0A600 +0x04*0..255 RW MAC Pool Select Array PFUTA 0X0F400 +0x04*0..127 RW PF Unicast Table Array PFVLVF 0x0F100 +0x04*0..63 RW PF VM VLAN Pool Filter PFVLVFB 0x0F200 +0x04*0..127 RW PF VM VLAN Pool Filter Bitmap +PFVFRE 0x051E0 +0x04*0..1 RW PF VF Receive Enable +PFVFSPOOF 0x08200 +0x04*0..7 RW PF VF Anti Spoof Control +PFVML2FLT 0x0F000 +0x04*0..63 RW PF VM L2 Control Register QPRC 0x01030 +0x40*0..15 RC Queue Packets Received Count QPRDC 0x01430 +0x40*0..15 RC Queue Packets Received Drop Count QBRC64 0x01034 +0x40*0..15 RC64 Queue Bytes Received Count @@ -74,6 +77,7 @@ QPTC 0x08680 +0x40*0..15 RC Queue Packets Transmitted Count QBTC64 0x08700 +0x40*0..15 RC64 Queue Bytes Transmitted Count Low SAQF 0x0E000 +0x04*0..127 RW Source Address Queue Filter SDPQF 0x0E400 +0x04*0..127 RW Source Destination Port Queue Filter +PSRTYPE 0x0EA00 +0x04*0..63 RW Packet Split Receive Type Register RAH 0x0A204 +0x08*0..127 RW Receive Address High RAL 0x0A200 +0x08*0..127 RW Receive Address Low RAL64 0x0A200 +0x08*0..127 RW64 Receive Address Low and High @@ -87,6 +91,7 @@ TXPBSIZE 0x0CC00 +0x04*0..7 RW Transmit Packet Buffer Size TXPBTHRESH 0x04950 +0x04*0..7 RW Tx Packet Buffer Threshold VFTA 0x0A000 +0x04*0..127 RW VLAN Filter Table Array QPRDC 0x01430 +0x40*0..15 RC Queue Packets Received Drop Count +FCRTH 0x03260 +0x40*0..7 RW Flow Control Receive Threshold High ]], inherit = "gbl", rxq = [[ @@ -125,9 +130,16 @@ MFLCN 0x04294 - RW MAC Flow Control Register MRQC 0x0EC80 - RW Multiple Receive Queues Command Register MTQC 0x08120 - RW Multiple Transmit Queues Command Register PFVTCTL 0x051B0 - RW PF Virtual Control Register +PFQDE 0x02F04 - RW PF Queue Drop Enable Register +PFDTXGSWC 0x08220 - RW PF DMA Tx General Switch Control RDRXCTL 0x02F00 - RW Receive DMA Control Register +RTRPCS 0x02430 - RW DCB Receive Packet plane Control and Status +RTTDCS 0x04900 - RW DCB Transmit Descriptor Plane Control and Status +RTTPCS 0x0CD00 - RW DCB Transmit Packet Plane Control and Status RTRUP2TC 0x03020 - RW DCB Receive Use rPriority to Traffic Class RTTUP2TC 0x0C800 - RW DCB Transmit User Priority to Traffic Class +RTTDQSEL 0x04904 - RW DCB Transmit Descriptor Plane Queue Select +RTTDT1C 0x04908 - RW DCB Transmit Descriptor Plane T1 Config RTTBCNRC 0x04984 - RW DCB Transmit Rate-Scheduler Config RXCSUM 0x05000 - RW Receive Checksum Control RFCTL 0x05008 - RW Receive Filter Control Register @@ -266,6 +278,9 @@ Intel = { config = { pciaddr = {required=true}, ndescriptors = {default=2048}, + vmdq = {default=false}, + macaddr = {}, + poolnum = {}, txq = {}, rxq = {}, mtu = {default=9014}, @@ -322,7 +337,8 @@ function Intel:new (conf) self.max_q = byid.max_q -- VMDq checks - assert(not self.vmdq or device == "0x1533", "VMDq not supported on i210") + assert(not self.vmdq or device ~= "0x1533" or device ~= "0x157b", + "VMDq not supported on i210") assert(not self.poolnum or self.vmdq, "Pool number only supported for VMDq") if self.vmdq then assert(self.rxq >= 4 * self.poolnum and @@ -411,6 +427,15 @@ function Intel:init_rx_q () local rxdesc_ring_t = ffi.typeof("$[$]", rxdesc_t, self.ndesc) self.rxdesc = ffi.cast(ffi.typeof("$&", rxdesc_ring_t), memory.dma_alloc(ffi.sizeof(rxdesc_ring_t))) + + -- VMDq pool state (4.6.10.1.4) + if self.vmdq then + -- packet splitting (none) + self.r.PSRTYPE[self.poolnum](0) + -- multicast promiscuous, broadcast accept, accept untagged pkts + self.r.PFVML2FLT[self.poolnum]:set(bits { MPE=28, BAM=27, AUPE=24 }) + end + -- Receive state self.r.RDBAL(tophysical(self.rxdesc) % 2^32) self.r.RDBAH(tophysical(self.rxdesc) / 2^32) @@ -440,6 +465,9 @@ function Intel:init_rx_q () if self.driver == "Intel82599" then self.r.RXCTRL:set(bits{ RXEN=0 }) self.r.DCA_RXCTRL:clr(bits{RxCTRL=12}) + if self.vmdq then + self.r.PFVFRE[math.floor(self.poolnum/32)]:set(bits{VFRE=self.poolnum%32}) + end elseif self.driver == "Intel1g" then self.r.RCTL:set(bits { RXEN = 1 }) end @@ -699,8 +727,8 @@ end -- set MAC address (4.6.10.1.4) function Intel:set_MAC () - if not self.mac then return end - local mac = macaddress:new(self.mac) + if not self.macaddr then return end + local mac = macaddress:new(self.macaddr) self:add_receive_MAC(mac) self:set_transmit_MAC(mac) end @@ -1033,6 +1061,12 @@ end -- follows the configuration flow in 4.6.11.3.3 -- (should only be called on the master instance) function Intel82599:vmdq_enable () + -- initialize index sets + vmdq_sets[self.pciaddress] = { + mac_set = index_set:new(127, "MAC address table"), + vlan_set = index_set:new(64, "VLAN Filter table"), + mirror_set = index_set:new(4, "Mirror pool table") } + -- must be set prior to setting MTQC (7.2.1.2.1) self.r.RTTDCS:set(bits { ARBDIS=6 }) @@ -1046,7 +1080,7 @@ function Intel82599:vmdq_enable () -- 128 Tx Queues, 64 VMs (4.6.11.3.3) self.r.MTQC(bits { VT_Ena=1, Num_TC_OR_Q=2 }) - -- enable virtualization, replication enabled, define default pool + -- enable virtualization, replication enabled, disable default pool self.r.PFVTCTL(bits { VT_Ena=0, Rpl_En=30, DisDefPool=29 }) -- enable VMDq Tx to Rx loopback @@ -1060,12 +1094,6 @@ function Intel82599:vmdq_enable () -- intel10g zeroes out ETQF,ETQS here but they are init to 0 - -- initialize index sets - vmdq_sets[self.pciaddress] = { - mac_set = index_set:new(127, "MAC address table"), - vlan_set = index_set:new(64, "VLAN Filter table"), - mirror_set = index_set:new(4, "Mirror pool table") } - -- RTRUP2TC/RTTUP2TC cleared above in init -- DMA TX TCP max allowed size requests (set to 1MB) @@ -1089,7 +1117,6 @@ function Intel82599:vmdq_enable () end -- disable TC arbitrations, enable packet buffer free space monitor - self.r.RTTDCS:set() self.r.RTTDCS:clr(bits { TDPAC=0, TDRM=4, BPBFSM=23 }) self.r.RTTDCS:set(bits { VMPAC=1, BDPM=22 }) self.r.RTTPCS:clr(bits { TPPAC=5, TPRM=8 }) From 19edfb1df39e15384afc898d4452708af973e14c Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 8 May 2017 19:54:55 +0000 Subject: [PATCH 011/109] First attempt at tests for VMDq mode --- src/apps/intel_mp/test_10g_1q_blast_vmdq.sh | 9 +++ src/apps/intel_mp/testvmdqrecv.snabb | 75 +++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100755 src/apps/intel_mp/test_10g_1q_blast_vmdq.sh create mode 100755 src/apps/intel_mp/testvmdqrecv.snabb diff --git a/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh new file mode 100755 index 0000000000..9dd6c01575 --- /dev/null +++ b/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source.pcap & +BLAST=$! + +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 0 0 > results.0 + +kill -9 $BLAST +test `cat results.0 | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 +exit $? diff --git a/src/apps/intel_mp/testvmdqrecv.snabb b/src/apps/intel_mp/testvmdqrecv.snabb new file mode 100755 index 0000000000..c36547f877 --- /dev/null +++ b/src/apps/intel_mp/testvmdqrecv.snabb @@ -0,0 +1,75 @@ +#!../../snabb snsh +local args = main.parameters +assert(#args == 3, "testvmdqrecv.snabb pciaddr poolno qno") +local pciaddr = table.remove(args, 1) +local poolno = tonumber(table.remove(args,1)) +local qno = tonumber(table.remove(args,1)) + +local intel = require("apps.intel_mp.intel_mp") +local basic = require("apps.basic.basic_apps") +local ffi = require("ffi") +local C = ffi.C + +local c = config.new() +config.app(c, "nic", intel.Intel, { pciaddr=pciaddr, macaddr="90:72:82:78:c9:7a", vmdq=true, poolnum=poolno, rxq = qno, ndescriptors = 2048, wait_for_link=true }) +config.app(c, "sink", basic.Sink) +if os.getenv("SNABB_RECV_EXPENSIVE") then + local filter = require("apps.packet_filter.pcap_filter") + + local count = 10 + config.link(c, "nic.output -> filter0.input") + for i=0,count do + local n = tostring(i) + local s = "filter"..n + config.app(c, s, filter.PcapFilter, { filter = [[ not dst host 10.2.29.1 and not dst host 10.2.50.1 ]]}) + end + for i=1,count do + local m = tostring(i-1) + local n = tostring(i) + local s = "filter"..m..".output -> filter"..n..".input" + config.link(c, s) + end + config.app(c, "sane", filter.PcapFilter, { filter = [[ src host 172.16.172.3 and dst net 1.2.0.0/16 and ip proto 0 ]] }) + config.link(c, "filter"..tostring(count)..".output -> sane.input") + config.link(c, "sane.output -> sink.input") +else + config.link(c, "nic.output -> sink.input") +end + +engine.configure(c) +local spinup = os.getenv("SNABB_RECV_SPINUP") +if spinup then + engine.main({duration = spinup}) +end + +local counters = { + Intel82599 = { "GPRC", "RXDGPC" }, + Intel1g = { "GPRC", "RPTHC" } +} + +local duration = os.getenv("SNABB_RECV_DURATION") or 2 +local before = {} +local nic = engine.app_table.nic +local master = nic.master + +if master then + for _,v in pairs(counters[nic.driver]) do + before[v] = nic.r[v]() + end +end + +if os.getenv("SNABB_RECV_DEBUG") then + for _=1,duration do + engine.main({duration = 1}) + nic:debug() + end +else + engine.main({duration = duration}) +end + +if master then + for _,v in pairs(counters[nic.driver]) do + print(string.format("%s %d", v, tonumber(nic.r[v]() - before[v])/duration)) + end +end +main.exit(0) From 70bd72d2527b3519dbc0ee77a00d193ef5a22bd8 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 8 May 2017 22:05:29 +0000 Subject: [PATCH 012/109] Try testing different MAC addrs with VMDq --- src/apps/intel_mp/source2.pcap | Bin 0 -> 5124 bytes src/apps/intel_mp/test_10g_1q_blast_vmdq.sh | 2 +- src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 10 ++++++++++ src/apps/intel_mp/testvmdqrecv.snabb | 5 +++-- 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 src/apps/intel_mp/source2.pcap create mode 100755 src/apps/intel_mp/test_10g_2q_blast_vmdq.sh diff --git a/src/apps/intel_mp/source2.pcap b/src/apps/intel_mp/source2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..fe11518fb31ff58d4f170e6ad26c4b7c0dd3af47 GIT binary patch literal 5124 zcmb8x$xhQ@6o&Ed-&O`utcXR_g4Pl2OmSvVXq}a@b)Z~?VbQSU3S7I8ummOHT5gOy}R7Z(sLXC%Y@P z=1%(0K&XZ=+C7Vh?Vs&rJ08VCwpf=Kvc;Oj8C$GMoVCS@#IP+sNSw39dx@ki-btLd#aoFHTfC9D zV2jrhqqcY@anTkpB~rF{Au(o)n#3hrR3*l3u`F@f7E2OWZ1G&;sx6*Lq;0V%F=2}Z ziAh_`OI)+XoWyloJeA1U;)%o!TRfJyX^Te^w`}oH;j|5jA39dd8Tzw?C`bco~k>Khh!PQ5CtB(X%9|^8L5?p;G zxcW$N^^xG}Bf-^2f~$`NS04$kJ`!AgB)IxWaP^Vk>LbC`M}n)51Xmvku09f6eI&U0 xNO1L$;OZm6)klJ>j|5jA39dd8Tzw?C`bco~k>Khh!PQ5CtB(X%ABkS|{ROv~hp7Mn literal 0 HcmV?d00001 diff --git a/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh index 9dd6c01575..8ba5f58fe7 100755 --- a/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh @@ -2,7 +2,7 @@ SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source.pcap & BLAST=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 0 0 > results.0 +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 0 0 > results.0 kill -9 $BLAST test `cat results.0 | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh new file mode 100755 index 0000000000..8f9b92ef73 --- /dev/null +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source2.pcap & +BLAST=$! + +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 0 0 > results.0 & +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" 1 4 > results.1 + +kill -9 $BLAST +test `cat results.0 | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 +exit $? diff --git a/src/apps/intel_mp/testvmdqrecv.snabb b/src/apps/intel_mp/testvmdqrecv.snabb index c36547f877..7fba2347ef 100755 --- a/src/apps/intel_mp/testvmdqrecv.snabb +++ b/src/apps/intel_mp/testvmdqrecv.snabb @@ -1,7 +1,8 @@ #!../../snabb snsh local args = main.parameters -assert(#args == 3, "testvmdqrecv.snabb pciaddr poolno qno") +assert(#args == 4, "testvmdqrecv.snabb pciaddr macaddr poolno qno") local pciaddr = table.remove(args, 1) +local macaddr = table.remove(args, 1) local poolno = tonumber(table.remove(args,1)) local qno = tonumber(table.remove(args,1)) @@ -11,7 +12,7 @@ local ffi = require("ffi") local C = ffi.C local c = config.new() -config.app(c, "nic", intel.Intel, { pciaddr=pciaddr, macaddr="90:72:82:78:c9:7a", vmdq=true, poolnum=poolno, rxq = qno, ndescriptors = 2048, wait_for_link=true }) +config.app(c, "nic", intel.Intel, { pciaddr=pciaddr, macaddr=macaddr, vmdq=true, poolnum=poolno, rxq = qno, ndescriptors = 2048, wait_for_link=true }) config.app(c, "sink", basic.Sink) if os.getenv("SNABB_RECV_EXPENSIVE") then local filter = require("apps.packet_filter.pcap_filter") From 284ba9f65f59c58d0edf788a5ac97369d985d447 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 9 May 2017 18:03:36 -0700 Subject: [PATCH 013/109] Fix MAC address registration in VMDq mode Avoid using index sets and just query the registers since it's hard to share this state among the apps. Also do the MAC registration in the right place. --- src/apps/intel_mp/intel_mp.lua | 39 ++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index bbd584cdc9..ff35ddb6d2 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -22,7 +22,6 @@ local lib = require("core.lib") local bits = lib.bits local tophysical = core.memory.virtual_to_physical local register = require("lib.hardware.register") -local index_set = require("lib.index_set") local counter = require("core.counter") local macaddress = require("lib.macaddress") local shm = require("core.shm") @@ -262,9 +261,6 @@ EEC 0x00010 - RW EEPROM-Mode Control Register ]] } --- table to track index sets for use in VMDq mode per pci address -local vmdq_sets = {} - -- helper for pool number allocation local function firsthole(t) for i = 1, #t+1 do @@ -339,6 +335,7 @@ function Intel:new (conf) -- VMDq checks assert(not self.vmdq or device ~= "0x1533" or device ~= "0x157b", "VMDq not supported on i210") + assert(not self.vmdq or self.macaddr, "VMDq must be set to set macaddr") assert(not self.poolnum or self.vmdq, "Pool number only supported for VMDq") if self.vmdq then assert(self.rxq >= 4 * self.poolnum and @@ -356,6 +353,8 @@ function Intel:new (conf) self.fd:flock("sh") self:init_tx_q() self:init_rx_q() + self:set_MAC() + -- TODO: set VLAN, mirror here -- Initialize per app statistics counter.set(self.shm.mtu, self.mtu) @@ -734,12 +733,27 @@ function Intel:set_MAC () end function Intel:add_receive_MAC (mac) - local mac_set = vmdq_sets[self.pciaddress].mac_set - local mac_index, is_new = mac_set:add(tostring(mac)) - if is_new then - self.r.RAL[mac_index](mac:subbits(0,32)) - self.r.RAH[mac_index](bits({AV=31},mac:subbits(32,48))) + local mac_index + + -- scan to see if the MAC is already recorded or find the + -- first free MAC index + for idx=1, 127 do + local valid = self.r.RAH[idx]:bits(31, 1) + + if valid == 0 then + mac_index = idx + self.r.RAL[mac_index](mac:subbits(0,32)) + self.r.RAH[mac_index](bits({AV=31},mac:subbits(32,48))) + break + else + if self.r.RAL[idx]() == mac:subbits(0, 32) and + self.r.RAH[idx]:bits(0, 15) == mac:subbits(32, 48) then + mac_index = idx + break + end + end end + self.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)] :set(bits{Ena=self.poolnum%32}) end @@ -1051,7 +1065,6 @@ function Intel82599:init () if self.vmdq then self:vmdq_enable() - self:set_MAC() end self:unlock_sw_sem() @@ -1061,12 +1074,6 @@ end -- follows the configuration flow in 4.6.11.3.3 -- (should only be called on the master instance) function Intel82599:vmdq_enable () - -- initialize index sets - vmdq_sets[self.pciaddress] = { - mac_set = index_set:new(127, "MAC address table"), - vlan_set = index_set:new(64, "VLAN Filter table"), - mirror_set = index_set:new(4, "Mirror pool table") } - -- must be set prior to setting MTQC (7.2.1.2.1) self.r.RTTDCS:set(bits { ARBDIS=6 }) From 70968dd4407898321ab8953539dcbbc9603cb2d0 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 10 May 2017 08:21:45 -0700 Subject: [PATCH 014/109] Add comment explaining some RSS code --- src/apps/intel_mp/intel_mp.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index ff35ddb6d2..4307688a59 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -621,6 +621,12 @@ function Intel:rss_key () self.r.RSSRK[i](math.random(2^32)) end end + +-- Set RSS redirection table, which has 32 * 4 entries which contain +-- RSS indices, the lower 4 bits (or fewer) of which are used to +-- select an RSS queue. +-- +-- Also returns the current state of the redirection table function Intel:rss_tab (newtab) local current = {} local pos = 0 From 32857a2f3a35baf9d12e0d8aff897840fcc456db Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 10 May 2017 08:33:48 -0700 Subject: [PATCH 015/109] Enable RSS queues via PSRTYPE properly for VMDq --- src/apps/intel_mp/intel_mp.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 4307688a59..386ff6408c 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -429,8 +429,8 @@ function Intel:init_rx_q () -- VMDq pool state (4.6.10.1.4) if self.vmdq then - -- packet splitting (none) - self.r.PSRTYPE[self.poolnum](0) + -- packet splitting none, enable 4 RSS queues per pool + self.r.PSRTYPE[self.poolnum](bits { RQPL=30 }) -- multicast promiscuous, broadcast accept, accept untagged pkts self.r.PFVML2FLT[self.poolnum]:set(bits { MPE=28, BAM=27, AUPE=24 }) end From aca0bf33496ed117bccb9389a2cc37f48fd5adc3 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 10 May 2017 08:44:49 -0700 Subject: [PATCH 016/109] Use :bits to set the VMDq RSS mode properly --- src/apps/intel_mp/intel_mp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 386ff6408c..c422aac7d5 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1084,7 +1084,7 @@ function Intel82599:vmdq_enable () self.r.RTTDCS:set(bits { ARBDIS=6 }) -- 1010 -> 32 pools, 4 RSS queues each - self.r.MRQC:set(bits { VMDq = 3, RSS = 1 }) + self.r.MRQC:bits(0, 4, 0xA) -- TODO: not sure this is needed, but it's in intel10g -- disable RSC (7.11) From cc026018d23604649a252dfd1fac77b52738a0ef Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 10 May 2017 13:41:36 -0700 Subject: [PATCH 017/109] Remove RSS bit check for setting RETA RSS is always enabled, so there shouldn't be a case in which this is a no-op anyway. Also the check is complicated by the fact that RSS can be enabled in many ways (with DCB, VMDq, etc.). --- src/apps/intel_mp/intel_mp.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index c422aac7d5..55986dbcea 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -644,10 +644,6 @@ function Intel:rss_tab (newtab) return current end function Intel:rss_tab_build () - -- noop if rss is not enabled - local b = bits { RSS = self:offset("MRQC", "RSS") } - if bit.band(self.r.MRQC(), b) ~= b then return end - local tab = {} for i=0,self.max_q-1,1 do if band(self.r.ALLRXDCTL[i](), bits { Enable = 25 }) > 0 then From 12a55f0c28b17d5769511d72427a232b0e7a9194 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 10 May 2017 13:43:13 -0700 Subject: [PATCH 018/109] Fix RTTPCS bit set that had a wrong length arg --- src/apps/intel_mp/intel_mp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 55986dbcea..4628e0136d 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1130,7 +1130,7 @@ function Intel82599:vmdq_enable () self.r.RTTDCS:set(bits { VMPAC=1, BDPM=22 }) self.r.RTTPCS:clr(bits { TPPAC=5, TPRM=8 }) -- set RTTPCS.ARBD - self.r.RTTPCS:bits(22, 31, 0x244) + self.r.RTTPCS:bits(22, 10, 0x244) self.r.RTRPCS:clr(bits { RAC=2, RRM=1 }) -- must be cleared after MTQC configuration (7.2.1.2.1) From 162eac062680813e5731dd71ec22763e74d8be75 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 11 May 2017 19:59:50 +0000 Subject: [PATCH 019/109] Adjust test to test that both vmdq pools get pkts --- src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index 8f9b92ef73..3f4353f412 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# +# Test VMDq mode with two pools with different MACs + SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source2.pcap & BLAST=$! @@ -6,5 +9,10 @@ SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" 1 4 > results.1 kill -9 $BLAST -test `cat results.0 | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 +test `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 + +# both queues should see packets +test \( $? -eq 0 \) -a \( `cat results.0 | grep -m 1 fpb | awk '{print $9}'` -gt 0 \) +test \( $? -eq 0 \) -a \( `cat results.1 | grep -m 1 fpb | awk '{print $9}'` -gt 0 \) + exit $? From 97e36349ef9d7c43cf44728eba3f09d35a5b5359 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 11 May 2017 15:31:01 -0700 Subject: [PATCH 020/109] Move MAC pool enable code and make it cross-NIC Also add code to unset MAC on stop() --- src/apps/intel_mp/intel_mp.lua | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 4628e0136d..6baf77caa3 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -692,6 +692,9 @@ function Intel:stop () end end end + if self.vmdq then + self.unset_MAC() + end if self.fd:flock("nb, ex") then self.r.CTRL:clr( bits { SETLINKUP = 6 } ) --self.r.CTRL_EXT:clear( bits { DriverLoaded = 28 }) @@ -739,7 +742,7 @@ function Intel:add_receive_MAC (mac) -- scan to see if the MAC is already recorded or find the -- first free MAC index - for idx=1, 127 do + for idx=1, self.max_mac_addr do local valid = self.r.RAH[idx]:bits(31, 1) if valid == 0 then @@ -756,8 +759,8 @@ function Intel:add_receive_MAC (mac) end end - self.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)] - :set(bits{Ena=self.poolnum%32}) + -- associate MAC with the app's VMDq pool + self:enable_MAC_for_pool(mac_index) end function Intel:set_transmit_MAC (mac) @@ -781,6 +784,7 @@ Intel1g.offsets = { RSS = 1 } } +Intel1g.max_mac_addr = 15 function Intel1g:init_phy () -- 4.3.1.4 PHY Reset self.r.MANC:wait(bits { BLK_Phy_Rst_On_IDE = 18 }, 0) @@ -912,6 +916,17 @@ function Intel1g:vmdq_enable () self.r.MRQC:set(bits { VMDq1 = 0, VMDq2 = 1 }) end +function Intel1g:enable_MAC_for_pool(mac_index) + self.r.RAH[mac_index]:set(bits { Ena = 18 + self.poolnum }) +end + +function Intel1g:unset_MAC () + local msk = bits { Ena = 18 + self.poolnum } + for mac_index = 0, self.max_mac_addr do + pf.r.RAH[mac_index]:clr(msk) + end +end + Intel82599.driver = "Intel82599" Intel82599.offsets = { SRRCTL = { @@ -921,6 +936,7 @@ Intel82599.offsets = { RSS = 0 } } +Intel82599.max_mac_addr = 127 function Intel82599:link_status () local mask = bits { Link_up = 30 } return bit.band(self.r.LINKS(), mask) == mask @@ -1137,6 +1153,18 @@ function Intel82599:vmdq_enable () self.r.RTTDCS:clr(bits { ARBDIS=6 }) end +function Intel82599:enable_MAC_for_pool (mac_index) + self.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)] + :set(bits{Ena=self.poolnum%32}) +end + +function Intel82599:unset_MAC () + local msk = bits { Ena=self.poolnum%32 } + for mac_index = 0, self.max_mac_addr do + pf.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)]:clr(msk) + end +end + function Intel:debug (args) local args = args or {} local pfx = args.prefix or "DEBUG_" From 09c3bc6357ad33a96d87a217fe5025e16118ce1b Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 16 May 2017 11:40:12 -0700 Subject: [PATCH 021/109] Adjust the VMDq initialization assertions --- src/apps/intel_mp/intel_mp.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 6baf77caa3..46bf27a8b4 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -335,12 +335,21 @@ function Intel:new (conf) -- VMDq checks assert(not self.vmdq or device ~= "0x1533" or device ~= "0x157b", "VMDq not supported on i210") - assert(not self.vmdq or self.macaddr, "VMDq must be set to set macaddr") + assert(not self.macaddr or self.vmdq, "VMDq must be set to use MAC address") assert(not self.poolnum or self.vmdq, "Pool number only supported for VMDq") if self.vmdq then + assert(self.macaddr, "MAC address must be set in VMDq mode") + assert(self.poolnum, "Pool number must be set in VMDq mode") assert(self.rxq >= 4 * self.poolnum and self.rxq <= 4 * self.poolnum + 3, "Pool number and rxq do not match") + if self.driver == "Intel82599" then + assert(self.poolnum < 32, + "Pool overflow: Intel 82599 supports up to 32 VMDq pools") + elseif self.driver == "Intel1g" then + assert(self.poolnum < 8, + "Pool overflow: Intel i350 supports up to 8 VMDq pools") + end end -- Setup device access From 6240e9ab285c205ff56a6c7b48da349e4fcaaf24 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 16 May 2017 11:48:14 -0700 Subject: [PATCH 022/109] Error when the max number of MAC addresses is reached --- src/apps/intel_mp/intel_mp.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 46bf27a8b4..89eaf05877 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -768,6 +768,8 @@ function Intel:add_receive_MAC (mac) end end + assert(mac_index, "Max number of MAC addresses reached") + -- associate MAC with the app's VMDq pool self:enable_MAC_for_pool(mac_index) end From cf044c7e09b5cd109ea3e55d46a637fe8f5130e2 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 16 May 2017 11:48:26 -0700 Subject: [PATCH 023/109] Add code for enabling VLAN filtering/tagging This code is mostly copied from the intel10g.lua driver. Also add a new VLAN test and adjust old tests as needed. --- src/apps/intel_mp/intel_mp.lua | 73 +++++++++++++++++++- src/apps/intel_mp/source-vlan.pcap | Bin 0 -> 5532 bytes src/apps/intel_mp/test_10g_2q_blast_vlan.sh | 17 +++++ src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 4 +- src/apps/intel_mp/testvmdqrecv.snabb | 5 +- 5 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 src/apps/intel_mp/source-vlan.pcap create mode 100755 src/apps/intel_mp/test_10g_2q_blast_vlan.sh diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 89eaf05877..7d52660c05 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -68,6 +68,7 @@ PFVLVF 0x0F100 +0x04*0..63 RW PF VM VLAN Pool Filter PFVLVFB 0x0F200 +0x04*0..127 RW PF VM VLAN Pool Filter Bitmap PFVFRE 0x051E0 +0x04*0..1 RW PF VF Receive Enable PFVFSPOOF 0x08200 +0x04*0..7 RW PF VF Anti Spoof Control +PFVMVIR 0x08000 +0x04*0..63 RW PF VM VLAN Insert Register PFVML2FLT 0x0F000 +0x04*0..63 RW PF VM L2 Control Register QPRC 0x01030 +0x40*0..15 RC Queue Packets Received Count QPRDC 0x01430 +0x40*0..15 RC Queue Packets Received Drop Count @@ -277,6 +278,7 @@ Intel = { vmdq = {default=false}, macaddr = {}, poolnum = {}, + vlan = {}, txq = {}, rxq = {}, mtu = {default=9014}, @@ -321,6 +323,7 @@ function Intel:new (conf) vmdq = conf.vmdq, poolnum = conf.poolnum, macaddr = conf.macaddr, + vlan = conf.vlan, } local vendor = lib.firstline(self.path .. "/vendor") @@ -363,7 +366,8 @@ function Intel:new (conf) self:init_tx_q() self:init_rx_q() self:set_MAC() - -- TODO: set VLAN, mirror here + self:set_VLAN() + -- TODO: set mirror here -- Initialize per app statistics counter.set(self.shm.mtu, self.mtu) @@ -779,6 +783,71 @@ function Intel:set_transmit_MAC (mac) self.r.PFVFSPOOF[math.floor(poolnum/8)]:set(bits{MACAS=poolnum%8}) end +-- set VLAN for the driver instance +function Intel:set_VLAN () + local vlan = self.vlan + if not vlan then return end + assert(vlan>=0 and vlan<4096, "bad VLAN number") + self:add_receive_VLAN(vlan) + self:set_tag_VLAN(vlan) +end + +function Intel:add_receive_VLAN (vlan) + assert(vlan>=0 and vlan<4096, "bad VLAN number") + local vlan_index + + -- scan to see if the VLAN is already recorded or find the + -- first free VLAN index + for idx=1, self.max_vlan do + local valid = self.r.PFVLVF[idx]:bits(31, 1) + + if valid == 0 then + vlan_index = idx + self.r.VFTA[math.floor(vlan/32)]:set(bits{Ena=vlan%32}) + self.r.PFVLVF[vlan_index](bits({Vl_En=31},vlan)) + break + else + if self.r.PFVLVF[idx]:bits(0, 11) == vlan then + mac_index = idx + break + end + end + + end + + assert(vlan_index, "Max number of VLAN IDs reached") + + self.r.PFVLVFB[2*vlan_index + math.floor(self.poolnum/32)] + :set(bits{PoolEna=self.poolnum%32}) +end + +function Intel:set_tag_VLAN (vlan) + local poolnum = self.poolnum or 0 + self.r.PFVFSPOOF[math.floor(poolnum/8)]:set(bits{VLANAS=poolnum%8+8}) + -- set Port VLAN ID & VLANA to always add VLAN tag + -- TODO: on i350 it's the VMVIR register + self.r.PFVMVIR[poolnum](bits({VLANA=30}, vlan)) +end + +function Intel:unset_VLAN () + local r = self.r + local offs, mask = math.floor(self.poolnum/32), bits{PoolEna=self.poolnum%32} + + for vln_ndx = 0, 63 do + if band(r.PFVLVFB[2*vln_ndx+offs](), mask) ~= 0 then + -- found a vlan this pool belongs to + r.PFVLVFB[2*vln_ndx+offs]:clr(mask) + if r.PFVLVFB[2*vln_ndx+offs]() == 0 then + -- it was the last pool of the vlan + local vlan = tonumber(band(r.PFVLVF[vln_ndx](), 0xFFF)) + r.PFVLVF[vln_ndx](0x0) + r.VFTA[math.floor(vlan/32)]:clr(bits{Ena=vlan%32}) + --self.pf.vlan_set:pop(vlan) + end + end + end +end + function Intel:rxpackets () return self.r.GPRC() end function Intel:txpackets () return self.r.GPTC() end function Intel:rxmcast () return self.r.MPRC() + self.r.BPRC() end @@ -796,6 +865,7 @@ Intel1g.offsets = { } } Intel1g.max_mac_addr = 15 +Intel1g.max_vlan = 8 function Intel1g:init_phy () -- 4.3.1.4 PHY Reset self.r.MANC:wait(bits { BLK_Phy_Rst_On_IDE = 18 }, 0) @@ -948,6 +1018,7 @@ Intel82599.offsets = { } } Intel82599.max_mac_addr = 127 +Intel82599.max_vlan = 64 function Intel82599:link_status () local mask = bits { Link_up = 30 } return bit.band(self.r.LINKS(), mask) == mask diff --git a/src/apps/intel_mp/source-vlan.pcap b/src/apps/intel_mp/source-vlan.pcap new file mode 100644 index 0000000000000000000000000000000000000000..a4134e851b3a04c36dc421ced4060bce7c1ebcca GIT binary patch literal 5532 zcmbW($xf4D7{&4T`&tEYDx;vbiUKmUbO01Z1(nu;LFNitE`qQyZj4?5S0G`}id$gC z8gIi3aD^o~gq#)U_#|)gyvg(1|9>AI?8PA&&gSHM2vPl$`PEU~{nHTo>ig;2+4}kQ z=-Wc2ww?a_qkhsD$|1C!o+iTP@qTJQ5yc^LR1GS!)EB7OQlFs`mfCq&ag}P#?6{sdlEkj+k)DqM+OD#fOx6}gE4NHB5x@oC-sFbDVpqec; z3)Nz&8K_oEeSm7S)O)CQOTB~Yu+&?qTb8Ooby}(n)n%z^sN0r$19itzuc7W*>J?Pl zQd3YFOHD%Ev(!td`<8kE)orQgP!B9M0rk*Q&!BoN^%SbtQsYp4mU;s9$Wo7?`YkmE zHDIYxs6k7OKn+={1eLW^5h`b?0@Sdj@=$q84MP!IF{-mXutuq~wAnB^N9yxnN1j1xrdUSW0_43zn2zu%zUI zB_$UuDY;-t$puSFE?81>!IF{-mXutuq~wAnB^N9yxnN1j1xrdUSW results.0 & +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 2 1 4 > results.1 + +kill -9 $BLAST +[[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ +# both queues should see packets +[[ `cat results.0 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] &&\ +[[ `cat results.1 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] + +exit $? diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index 3f4353f412..b8678dcd6f 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -5,8 +5,8 @@ SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source2.pcap & BLAST=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 0 0 > results.0 & -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" 1 4 > results.1 +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" nil 0 0 > results.0 & +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 1 4 > results.1 kill -9 $BLAST test `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 diff --git a/src/apps/intel_mp/testvmdqrecv.snabb b/src/apps/intel_mp/testvmdqrecv.snabb index 7fba2347ef..490b5ae60f 100755 --- a/src/apps/intel_mp/testvmdqrecv.snabb +++ b/src/apps/intel_mp/testvmdqrecv.snabb @@ -1,8 +1,9 @@ #!../../snabb snsh local args = main.parameters -assert(#args == 4, "testvmdqrecv.snabb pciaddr macaddr poolno qno") +assert(#args == 5, "testvmdqrecv.snabb pciaddr macaddr vlan poolno qno") local pciaddr = table.remove(args, 1) local macaddr = table.remove(args, 1) +local vlan = load("return " .. table.remove(args, 1))() local poolno = tonumber(table.remove(args,1)) local qno = tonumber(table.remove(args,1)) @@ -12,7 +13,7 @@ local ffi = require("ffi") local C = ffi.C local c = config.new() -config.app(c, "nic", intel.Intel, { pciaddr=pciaddr, macaddr=macaddr, vmdq=true, poolnum=poolno, rxq = qno, ndescriptors = 2048, wait_for_link=true }) +config.app(c, "nic", intel.Intel, { pciaddr=pciaddr, macaddr=macaddr, vlan=vlan, vmdq=true, poolnum=poolno, rxq = qno, ndescriptors = 2048, wait_for_link=true }) config.app(c, "sink", basic.Sink) if os.getenv("SNABB_RECV_EXPENSIVE") then local filter = require("apps.packet_filter.pcap_filter") From e31423765a73b780f06efbe1b10d23f154f7fa41 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 16 May 2017 22:53:15 +0000 Subject: [PATCH 024/109] Refactor vmdq test script The previous iteration was unreliable for unknown reasons. This refactoring should be clearer and run more reliably. --- src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index b8678dcd6f..b69a656f39 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -9,10 +9,10 @@ SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 1 4 > results.1 kill -9 $BLAST -test `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 +[[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ # both queues should see packets -test \( $? -eq 0 \) -a \( `cat results.0 | grep -m 1 fpb | awk '{print $9}'` -gt 0 \) -test \( $? -eq 0 \) -a \( `cat results.1 | grep -m 1 fpb | awk '{print $9}'` -gt 0 \) +[[ `cat results.0 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] &&\ +[[ `cat results.1 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] exit $? From 88c0810df2517a443911569176e21de5302f511d Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 17 May 2017 00:57:46 +0000 Subject: [PATCH 025/109] Enable VLAN takedown code for VMDq --- src/apps/intel_mp/intel_mp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 7d52660c05..6533110df2 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -707,6 +707,7 @@ function Intel:stop () end if self.vmdq then self.unset_MAC() + self.unset_VLAN() end if self.fd:flock("nb, ex") then self.r.CTRL:clr( bits { SETLINKUP = 6 } ) @@ -842,7 +843,6 @@ function Intel:unset_VLAN () local vlan = tonumber(band(r.PFVLVF[vln_ndx](), 0xFFF)) r.PFVLVF[vln_ndx](0x0) r.VFTA[math.floor(vlan/32)]:clr(bits{Ena=vlan%32}) - --self.pf.vlan_set:pop(vlan) end end end From c3b58d0e42eb7740c2a4334098f97edc78a261e6 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 23 May 2017 02:44:36 -0700 Subject: [PATCH 026/109] Refactor intel_mp recv test scripts to reduce duplication --- src/apps/intel_mp/testrecv.lua | 88 ++++++++++++++++++++++++++++ src/apps/intel_mp/testrecv.snabb | 70 +--------------------- src/apps/intel_mp/testvmdqrecv.snabb | 69 +--------------------- 3 files changed, 93 insertions(+), 134 deletions(-) create mode 100644 src/apps/intel_mp/testrecv.lua diff --git a/src/apps/intel_mp/testrecv.lua b/src/apps/intel_mp/testrecv.lua new file mode 100644 index 0000000000..83b88ff571 --- /dev/null +++ b/src/apps/intel_mp/testrecv.lua @@ -0,0 +1,88 @@ +-- Helper module for testing intel_mp driver receive + +local intel = require("apps.intel_mp.intel_mp") +local basic = require("apps.basic.basic_apps") +local ffi = require("ffi") +local C = ffi.C + +function test(pciaddr, qno, vmdq, poolno, macaddr, vlan) + local c = config.new() + if vmdq then + config.app(c, "nic", intel.Intel, + { pciaddr=pciaddr, + macaddr=macaddr, + vlan=vlan, + vmdq=true, + poolnum=poolno, + rxq = qno, + ndescriptors = 2048, + wait_for_link=true }) + else + config.app(c, "nic", intel.Intel, + { pciaddr=pciaddr, + rxq = qno, + ndescriptors = 2048, + wait_for_link=true }) + end + config.app(c, "sink", basic.Sink) + if os.getenv("SNABB_RECV_EXPENSIVE") then + local filter = require("apps.packet_filter.pcap_filter") + + local count = 10 + config.link(c, "nic.output -> filter0.input") + for i=0,count do + local n = tostring(i) + local s = "filter"..n + config.app(c, s, filter.PcapFilter, { filter = [[ not dst host 10.2.29.1 and not dst host 10.2.50.1 ]]}) + end + for i=1,count do + local m = tostring(i-1) + local n = tostring(i) + local s = "filter"..m..".output -> filter"..n..".input" + config.link(c, s) + end + config.app(c, "sane", filter.PcapFilter, { filter = [[ src host 172.16.172.3 and dst net 1.2.0.0/16 and ip proto 0 ]] }) + config.link(c, "filter"..tostring(count)..".output -> sane.input") + config.link(c, "sane.output -> sink.input") + else + config.link(c, "nic.output -> sink.input") + end + + engine.configure(c) + local spinup = os.getenv("SNABB_RECV_SPINUP") + if spinup then + engine.main({duration = spinup}) + end + + local counters = { + Intel82599 = { "GPRC", "RXDGPC" }, + Intel1g = { "GPRC", "RPTHC" } + } + + local duration = os.getenv("SNABB_RECV_DURATION") or 2 + local before = {} + local nic = engine.app_table.nic + local master = nic.master + + if master then + for _,v in pairs(counters[nic.driver]) do + before[v] = nic.r[v]() + end + end + + if os.getenv("SNABB_RECV_DEBUG") then + for _=1,duration do + engine.main({duration = 1}) + nic:debug() + end + else + engine.main({duration = duration}) + end + + if master then + for _,v in pairs(counters[nic.driver]) do + print(string.format("%s %d", v, tonumber(nic.r[v]() - before[v])/duration)) + end + end + main.exit(0) +end diff --git a/src/apps/intel_mp/testrecv.snabb b/src/apps/intel_mp/testrecv.snabb index 6b41b14aa8..acbfdd8ec1 100755 --- a/src/apps/intel_mp/testrecv.snabb +++ b/src/apps/intel_mp/testrecv.snabb @@ -1,74 +1,10 @@ #!../../snabb snsh + local args = main.parameters assert(#args == 2, "testrecv.snabb pciaddr qno") local pciaddr = table.remove(args, 1) local qno = tonumber(table.remove(args,1)) -local intel = require("apps.intel_mp.intel_mp") -local basic = require("apps.basic.basic_apps") -local ffi = require("ffi") -local C = ffi.C - -local c = config.new() -config.app(c, "nic", intel.Intel, { pciaddr=pciaddr, rxq = qno, ndescriptors = 2048, wait_for_link=true }) -config.app(c, "sink", basic.Sink) -if os.getenv("SNABB_RECV_EXPENSIVE") then - local filter = require("apps.packet_filter.pcap_filter") - - local count = 10 - config.link(c, "nic.output -> filter0.input") - for i=0,count do - local n = tostring(i) - local s = "filter"..n - config.app(c, s, filter.PcapFilter, { filter = [[ not dst host 10.2.29.1 and not dst host 10.2.50.1 ]]}) - end - for i=1,count do - local m = tostring(i-1) - local n = tostring(i) - local s = "filter"..m..".output -> filter"..n..".input" - config.link(c, s) - end - config.app(c, "sane", filter.PcapFilter, { filter = [[ src host 172.16.172.3 and dst net 1.2.0.0/16 and ip proto 0 ]] }) - config.link(c, "filter"..tostring(count)..".output -> sane.input") - config.link(c, "sane.output -> sink.input") -else - config.link(c, "nic.output -> sink.input") -end - -engine.configure(c) -local spinup = os.getenv("SNABB_RECV_SPINUP") -if spinup then - engine.main({duration = spinup}) -end - -local counters = { - Intel82599 = { "GPRC", "RXDGPC" }, - Intel1g = { "GPRC", "RPTHC" } -} - -local duration = os.getenv("SNABB_RECV_DURATION") or 2 -local before = {} -local nic = engine.app_table.nic -local master = nic.master - -if master then - for _,v in pairs(counters[nic.driver]) do - before[v] = nic.r[v]() - end -end - -if os.getenv("SNABB_RECV_DEBUG") then - for _=1,duration do - engine.main({duration = 1}) - nic:debug() - end -else - engine.main({duration = duration}) -end +local test = require("apps.intel_mp.testrecv").test -if master then - for _,v in pairs(counters[nic.driver]) do - print(string.format("%s %d", v, tonumber(nic.r[v]() - before[v])/duration)) - end -end -main.exit(0) +test(pciaddr, qno, false) diff --git a/src/apps/intel_mp/testvmdqrecv.snabb b/src/apps/intel_mp/testvmdqrecv.snabb index 490b5ae60f..474bd76502 100755 --- a/src/apps/intel_mp/testvmdqrecv.snabb +++ b/src/apps/intel_mp/testvmdqrecv.snabb @@ -7,71 +7,6 @@ local vlan = load("return " .. table.remove(args, 1))() local poolno = tonumber(table.remove(args,1)) local qno = tonumber(table.remove(args,1)) -local intel = require("apps.intel_mp.intel_mp") -local basic = require("apps.basic.basic_apps") -local ffi = require("ffi") -local C = ffi.C +local test = require("apps.intel_mp.testrecv").test -local c = config.new() -config.app(c, "nic", intel.Intel, { pciaddr=pciaddr, macaddr=macaddr, vlan=vlan, vmdq=true, poolnum=poolno, rxq = qno, ndescriptors = 2048, wait_for_link=true }) -config.app(c, "sink", basic.Sink) -if os.getenv("SNABB_RECV_EXPENSIVE") then - local filter = require("apps.packet_filter.pcap_filter") - - local count = 10 - config.link(c, "nic.output -> filter0.input") - for i=0,count do - local n = tostring(i) - local s = "filter"..n - config.app(c, s, filter.PcapFilter, { filter = [[ not dst host 10.2.29.1 and not dst host 10.2.50.1 ]]}) - end - for i=1,count do - local m = tostring(i-1) - local n = tostring(i) - local s = "filter"..m..".output -> filter"..n..".input" - config.link(c, s) - end - config.app(c, "sane", filter.PcapFilter, { filter = [[ src host 172.16.172.3 and dst net 1.2.0.0/16 and ip proto 0 ]] }) - config.link(c, "filter"..tostring(count)..".output -> sane.input") - config.link(c, "sane.output -> sink.input") -else - config.link(c, "nic.output -> sink.input") -end - -engine.configure(c) -local spinup = os.getenv("SNABB_RECV_SPINUP") -if spinup then - engine.main({duration = spinup}) -end - -local counters = { - Intel82599 = { "GPRC", "RXDGPC" }, - Intel1g = { "GPRC", "RPTHC" } -} - -local duration = os.getenv("SNABB_RECV_DURATION") or 2 -local before = {} -local nic = engine.app_table.nic -local master = nic.master - -if master then - for _,v in pairs(counters[nic.driver]) do - before[v] = nic.r[v]() - end -end - -if os.getenv("SNABB_RECV_DEBUG") then - for _=1,duration do - engine.main({duration = 1}) - nic:debug() - end -else - engine.main({duration = duration}) -end - -if master then - for _,v in pairs(counters[nic.driver]) do - print(string.format("%s %d", v, tonumber(nic.r[v]() - before[v])/duration)) - end -end -main.exit(0) +test(pciaddr, qno, true, poolno, macaddr, vlan) From 6991cce56f4ed953cf47acdbb1707f9c36c535b2 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 23 May 2017 09:03:33 -0700 Subject: [PATCH 027/109] Enable VLAN tag stripping in VMDq mode Also add new test for VLAN stripping --- src/apps/intel_mp/intel_mp.lua | 6 ++++ src/apps/intel_mp/test_10g_vlan.sh | 5 +++ src/apps/intel_mp/testvlan.snabb | 54 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 src/apps/intel_mp/test_10g_vlan.sh create mode 100755 src/apps/intel_mp/testvlan.snabb diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 6533110df2..9b847d6b5b 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -468,6 +468,12 @@ function Intel:init_rx_q () Drop_En = self:offset("SRRCTL", "Drop_En") }) self:lock_sw_sem() + + -- enable VLAN tag stripping in VMDq mode + if self.vmdq then + self.r.RXDCTL:set(bits { VME = 30 }) + end + self.r.RXDCTL:set( bits { Enable = 25 }) self.r.RXDCTL:wait( bits { Enable = 25 }) C.full_memory_barrier() diff --git a/src/apps/intel_mp/test_10g_vlan.sh b/src/apps/intel_mp/test_10g_vlan.sh new file mode 100644 index 0000000000..64048ea47c --- /dev/null +++ b/src/apps/intel_mp/test_10g_vlan.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# +# Test VMDq mode with vlan tagging + +./testvlan.snabb $SNABB_PCI_INTEL0 $SNABB_PCI_INTEL1 "90:72:82:78:c9:7a" source-vlan.pcap diff --git a/src/apps/intel_mp/testvlan.snabb b/src/apps/intel_mp/testvlan.snabb new file mode 100755 index 0000000000..589a66e429 --- /dev/null +++ b/src/apps/intel_mp/testvlan.snabb @@ -0,0 +1,54 @@ +#!../../snabb snsh + +-- Snabb test script for vlan tagging/insertion. This test is for checking +-- that vlan stripping is working. + +local args = main.parameters +assert(#args == 4, "testvlan.snabb pciaddr1 pciaddr2 macaddr pcapfile") +local pciaddr1 = table.remove(args, 1) +local pciaddr2 = table.remove(args, 1) +local macaddr = table.remove(args, 1) +local pcapfile = table.remove(args,1) + +local basic_apps = require("apps.basic.basic_apps") +local intel = require("apps.intel_mp.intel_mp") +local pcap = require("apps.pcap.pcap") +local filter = require("apps.packet_filter.pcap_filter") +local C = require("ffi").C + +local c = config.new() +config.app(c, "pcap", pcap.PcapReader, pcapfile) + +-- these are on the same core but that's ok, this is a correctness test +config.app(c, "nic1", intel.Intel, + {pciaddr=pciaddr1, txq = 0, ndescriptors=2048, wait_for_link = true}) +config.app(c, "nic2", intel.Intel, + {pciaddr=pciaddr2, + vmdq = true, + macaddr = macaddr, + vlan = 1, + poolnum = 0, + rxq = 0, + ndescriptors=2048, + wait_for_link = true}) + +-- use pflua to filter based on presence of vlan tag +config.app(c, "filter1", filter.PcapFilter, { filter = [[ ether[12:2] == 0x8100 ]] }) +config.app(c, "filter2", filter.PcapFilter, { filter = [[ ether[12:2] != 0x8100 ]] }) +config.app(c, "tee", basic_apps.Tee) +config.app(c, 'sink', basic_apps.Sink) + +config.link(c, "pcap.output -> nic1.input") +config.link(c, "nic2.output -> tee.input") +config.link(c, "tee.output1 -> filter1.input") +config.link(c, "tee.output2 -> filter2.input") +config.link(c, "filter1.output -> sink.in1") +config.link(c, "filter2.output -> sink.in2") + +engine.configure(c) +engine.main({ duration = 1 }) + +assert(link.stats(engine.app_table.sink.input.in1).rxpackets == 0, + "expected no vlan tagged packets") +assert(link.stats(engine.app_table.sink.input.in2).rxpackets > 0, + "expected some non-vlan tagged packets") From 432e35a99015ed62c31ca1e3a94d4b180fb98093 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 25 May 2017 03:13:13 -0700 Subject: [PATCH 028/109] Adjust VLAN test to also test tag insertion --- src/apps/intel_mp/testvlan.snabb | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/apps/intel_mp/testvlan.snabb b/src/apps/intel_mp/testvlan.snabb index 589a66e429..fd2e8f6f78 100755 --- a/src/apps/intel_mp/testvlan.snabb +++ b/src/apps/intel_mp/testvlan.snabb @@ -21,7 +21,9 @@ config.app(c, "pcap", pcap.PcapReader, pcapfile) -- these are on the same core but that's ok, this is a correctness test config.app(c, "nic1", intel.Intel, - {pciaddr=pciaddr1, txq = 0, ndescriptors=2048, wait_for_link = true}) + {pciaddr=pciaddr1, + rxq = 0, txq = 0, + ndescriptors=2048, wait_for_link = true}) config.app(c, "nic2", intel.Intel, {pciaddr=pciaddr2, vmdq = true, @@ -29,12 +31,14 @@ config.app(c, "nic2", intel.Intel, vlan = 1, poolnum = 0, rxq = 0, + txq = 0, ndescriptors=2048, wait_for_link = true}) -- use pflua to filter based on presence of vlan tag config.app(c, "filter1", filter.PcapFilter, { filter = [[ ether[12:2] == 0x8100 ]] }) config.app(c, "filter2", filter.PcapFilter, { filter = [[ ether[12:2] != 0x8100 ]] }) +config.app(c, "filter3", filter.PcapFilter, { filter = [[ ether[12:2] == 0x8100 ]] }) config.app(c, "tee", basic_apps.Tee) config.app(c, 'sink', basic_apps.Sink) @@ -43,12 +47,19 @@ config.link(c, "nic2.output -> tee.input") config.link(c, "tee.output1 -> filter1.input") config.link(c, "tee.output2 -> filter2.input") config.link(c, "filter1.output -> sink.in1") -config.link(c, "filter2.output -> sink.in2") + +-- send good packets back out through NIC to test vlan tag insertion +-- use a filter to check presence of tag +config.link(c, "filter2.output -> nic2.input") +config.link(c, "nic1.output -> filter3.input") +config.link(c, "filter3.output -> sink.in2") engine.configure(c) engine.main({ duration = 1 }) assert(link.stats(engine.app_table.sink.input.in1).rxpackets == 0, - "expected no vlan tagged packets") + "expected no vlan tagged packets (after stripping)") +assert(link.stats(engine.app_table.nic2.input.input).rxpackets > 0, + "expected some non-vlan tagged packets (after stripping)") assert(link.stats(engine.app_table.sink.input.in2).rxpackets > 0, - "expected some non-vlan tagged packets") + "expected vlan tagged packets (after insertion)") From ec0c436f8c48135232a9fa235a36c7ad40e3a084 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 25 May 2017 03:27:51 -0700 Subject: [PATCH 029/109] VMDq settings for transmit queues --- src/apps/intel_mp/intel_mp.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 9b847d6b5b..066aeb8f46 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -519,6 +519,11 @@ function Intel:init_tx_q () -- 4.5.10 self.r.TDBAH(tophysical(self.txdesc) / 2^32) self.r.TDLEN(self.ndesc * ffi.sizeof(txdesc_t)) + -- for VMDq need some additional pool configs + if self.vmdq then + self.r.RTTDQSEL(self.poolnum) + end + if self.r.DMATXCTL then self.r.DMATXCTL:set(bits { TE = 0 }) self.r.TXDCTL:set(bits{SWFLSH=26, hthresh=8} + 32) From c303d301f093a2c4af667083f56809c69e7a99c7 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 26 May 2017 10:49:29 +0000 Subject: [PATCH 030/109] Add a test for VLAN tag insertion & VMDq tx --- src/apps/intel_mp/test_10g_vmdq_tx.sh | 5 +++ src/apps/intel_mp/testvmdqtx.snabb | 53 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/apps/intel_mp/test_10g_vmdq_tx.sh create mode 100755 src/apps/intel_mp/testvmdqtx.snabb diff --git a/src/apps/intel_mp/test_10g_vmdq_tx.sh b/src/apps/intel_mp/test_10g_vmdq_tx.sh new file mode 100644 index 0000000000..7a98961316 --- /dev/null +++ b/src/apps/intel_mp/test_10g_vmdq_tx.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# +# Test packet transmit for VMDq mode + +./testvmdqtx.snabb $SNABB_PCI_INTEL0 $SNABB_PCI_INTEL1 "50:46:5d:74:1d:f9" source.pcap diff --git a/src/apps/intel_mp/testvmdqtx.snabb b/src/apps/intel_mp/testvmdqtx.snabb new file mode 100755 index 0000000000..9fd3b23d79 --- /dev/null +++ b/src/apps/intel_mp/testvmdqtx.snabb @@ -0,0 +1,53 @@ +#!../../snabb snsh + +-- Snabb test script for transmit in VMDq mode, also tests VLAN +-- tag insertion + +local args = main.parameters +assert(#args == 4, "testvmdqtx.snabb pciaddr1 pciaddr2 macaddr pcapfile") +local pciaddr1 = table.remove(args, 1) +local pciaddr2 = table.remove(args, 1) +local macaddr = table.remove(args, 1) +local pcapfile = table.remove(args,1) + +local basic_apps = require("apps.basic.basic_apps") +local intel = require("apps.intel_mp.intel_mp") +local pcap = require("apps.pcap.pcap") +local filter = require("apps.packet_filter.pcap_filter") +local C = require("ffi").C + +local c = config.new() + +-- send packets on nic1 +config.app(c, "nic1", intel.Intel, + { pciaddr=pciaddr1, + vmdq = true, + macaddr = macaddr, + poolnum = 0, + txq = 0, + vlan = 1, + ndescriptors=2048, + wait_for_link = true }) + +-- nic2 just receives packets so we can check them +config.app(c, "nic2", intel.Intel, + { pciaddr=pciaddr2, + rxq = 0, + ndescriptors=2048, + wait_for_link = true }) + +config.app(c, "pcap", pcap.PcapReader, pcapfile) +config.app(c, "filter", filter.PcapFilter, { filter = [[ ether[12:2] == 0x8100 ]] }) +config.app(c, 'sink', basic_apps.Sink) + +config.link(c, "pcap.output -> nic1.input") +config.link(c, "nic2.output -> filter.input") +config.link(c, "filter.output -> sink.input") + +engine.configure(c) +engine.main({ duration = 1 }) + +assert(link.stats(engine.app_table.filter.input.input).rxpackets > 0, + "expected some packets on the receiving NIC") +assert(link.stats(engine.app_table.sink.input.input).rxpackets > 0, + "expected VLAN tagged packets on the receiving NIC") From 45a74947d5c0a21045157dbe0b80b261f7002464 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 31 May 2017 01:25:07 +0000 Subject: [PATCH 031/109] Set registers needed to make Tx test work * PFVFTE to enable Tx from appropriate VFs * RTTD1TC for bandwidth allocation algorithm for Tx --- src/apps/intel_mp/intel_mp.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 066aeb8f46..1cec0ce34a 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -67,6 +67,7 @@ PFUTA 0X0F400 +0x04*0..127 RW PF Unicast Table Array PFVLVF 0x0F100 +0x04*0..63 RW PF VM VLAN Pool Filter PFVLVFB 0x0F200 +0x04*0..127 RW PF VM VLAN Pool Filter Bitmap PFVFRE 0x051E0 +0x04*0..1 RW PF VF Receive Enable +PFVFTE 0x08110 +0x04*0..1 RW PF VF Transmit Enable PFVFSPOOF 0x08200 +0x04*0..7 RW PF VF Anti Spoof Control PFVMVIR 0x08000 +0x04*0..63 RW PF VM VLAN Insert Register PFVML2FLT 0x0F000 +0x04*0..63 RW PF VM L2 Control Register @@ -522,6 +523,10 @@ function Intel:init_tx_q () -- 4.5.10 -- for VMDq need some additional pool configs if self.vmdq then self.r.RTTDQSEL(self.poolnum) + -- set baseline value for credit refill for tx bandwidth algorithm + self.r.RTTDT1C(0x80) + -- enables packet Tx for this VF's pool + self.r.PFVFTE[math.floor(self.poolnum/33)]:set(bits{VFTE=self.poolnum%32}) end if self.r.DMATXCTL then From e8a1c36cd1f8079a784f96e19e229e32083009d4 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 31 May 2017 01:34:31 +0000 Subject: [PATCH 032/109] Fix assertion for Rx queue num to allow nil --- src/apps/intel_mp/intel_mp.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 1cec0ce34a..24fda4b853 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -344,8 +344,9 @@ function Intel:new (conf) if self.vmdq then assert(self.macaddr, "MAC address must be set in VMDq mode") assert(self.poolnum, "Pool number must be set in VMDq mode") - assert(self.rxq >= 4 * self.poolnum and - self.rxq <= 4 * self.poolnum + 3, + assert(not self.rxq or + (self.rxq >= 4 * self.poolnum and + self.rxq <= 4 * self.poolnum + 3), "Pool number and rxq do not match") if self.driver == "Intel82599" then assert(self.poolnum < 32, From e1766fb29d79a32fe6c584f106b5d4859fb8e283 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 31 May 2017 18:55:01 +0000 Subject: [PATCH 033/109] Adjust intel_mp to error with VMDq on non-82599 --- src/apps/intel_mp/intel_mp.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 24fda4b853..5fe8f50939 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -337,8 +337,7 @@ function Intel:new (conf) self.max_q = byid.max_q -- VMDq checks - assert(not self.vmdq or device ~= "0x1533" or device ~= "0x157b", - "VMDq not supported on i210") + assert(not self.vmdq or device == "0x10fb", "VMDq only supported on 82599") assert(not self.macaddr or self.vmdq, "VMDq must be set to use MAC address") assert(not self.poolnum or self.vmdq, "Pool number only supported for VMDq") if self.vmdq then @@ -1010,8 +1009,7 @@ function Intel1g:init_queue_stats (frame) end function Intel1g:vmdq_enable () - -- 011 -> VMDq mode, no RSS - self.r.MRQC:set(bits { VMDq1 = 0, VMDq2 = 1 }) + error("unimplemented") end function Intel1g:enable_MAC_for_pool(mac_index) From 8e07ff32738fa497b6df96023aba6ce81cb33c95 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 5 Jun 2017 20:24:52 +0000 Subject: [PATCH 034/109] Remove unnecessary helper function --- src/apps/intel_mp/intel_mp.lua | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 5fe8f50939..3fdd8b7d9d 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -263,15 +263,6 @@ EEC 0x00010 - RW EEPROM-Mode Control Register ]] } --- helper for pool number allocation -local function firsthole(t) - for i = 1, #t+1 do - if t[i] == nil then - return i - end - end -end - Intel = { config = { pciaddr = {required=true}, From 67420dd03844fdaa1c1746d7b39a115cd06c04ff Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 6 Jun 2017 15:46:52 +0000 Subject: [PATCH 035/109] Fix permissions on two intel_mp tests --- src/apps/intel_mp/test_10g_vlan.sh | 0 src/apps/intel_mp/test_10g_vmdq_tx.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/apps/intel_mp/test_10g_vlan.sh mode change 100644 => 100755 src/apps/intel_mp/test_10g_vmdq_tx.sh diff --git a/src/apps/intel_mp/test_10g_vlan.sh b/src/apps/intel_mp/test_10g_vlan.sh old mode 100644 new mode 100755 diff --git a/src/apps/intel_mp/test_10g_vmdq_tx.sh b/src/apps/intel_mp/test_10g_vmdq_tx.sh old mode 100644 new mode 100755 From e6f2b05d74b9604111dfd4b89a609cdedee31aff Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 6 Jun 2017 17:58:49 +0000 Subject: [PATCH 036/109] Fix 1q vmdq test and testrecv.lua The former wasn't updated for an API change and the latter was missing a module declaration. --- src/apps/intel_mp/test_10g_1q_blast_vmdq.sh | 2 +- src/apps/intel_mp/testrecv.lua | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh index 8ba5f58fe7..176b253ac8 100755 --- a/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_1q_blast_vmdq.sh @@ -2,7 +2,7 @@ SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source.pcap & BLAST=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 0 0 > results.0 +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" nil 0 0 > results.0 kill -9 $BLAST test `cat results.0 | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 diff --git a/src/apps/intel_mp/testrecv.lua b/src/apps/intel_mp/testrecv.lua index 83b88ff571..137dbd83d6 100644 --- a/src/apps/intel_mp/testrecv.lua +++ b/src/apps/intel_mp/testrecv.lua @@ -1,5 +1,7 @@ -- Helper module for testing intel_mp driver receive +module(..., package.seeall) + local intel = require("apps.intel_mp.intel_mp") local basic = require("apps.basic.basic_apps") local ffi = require("ffi") From 5dc4dcd4798e78e827997d8e7c63252b4af15a2d Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 6 Jun 2017 18:24:21 +0000 Subject: [PATCH 037/109] Adjust VLAN test to avoid testing tag insertion The tag insertion part of this test didn't work because the MAC didn't match when the app tried to resend the packet. It's not necessary since the transmit test covers this anyway. --- src/apps/intel_mp/testvlan.snabb | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/apps/intel_mp/testvlan.snabb b/src/apps/intel_mp/testvlan.snabb index fd2e8f6f78..33fe44531c 100755 --- a/src/apps/intel_mp/testvlan.snabb +++ b/src/apps/intel_mp/testvlan.snabb @@ -22,7 +22,7 @@ config.app(c, "pcap", pcap.PcapReader, pcapfile) -- these are on the same core but that's ok, this is a correctness test config.app(c, "nic1", intel.Intel, {pciaddr=pciaddr1, - rxq = 0, txq = 0, + txq = 0, ndescriptors=2048, wait_for_link = true}) config.app(c, "nic2", intel.Intel, {pciaddr=pciaddr2, @@ -31,14 +31,12 @@ config.app(c, "nic2", intel.Intel, vlan = 1, poolnum = 0, rxq = 0, - txq = 0, ndescriptors=2048, wait_for_link = true}) -- use pflua to filter based on presence of vlan tag config.app(c, "filter1", filter.PcapFilter, { filter = [[ ether[12:2] == 0x8100 ]] }) config.app(c, "filter2", filter.PcapFilter, { filter = [[ ether[12:2] != 0x8100 ]] }) -config.app(c, "filter3", filter.PcapFilter, { filter = [[ ether[12:2] == 0x8100 ]] }) config.app(c, "tee", basic_apps.Tee) config.app(c, 'sink', basic_apps.Sink) @@ -47,19 +45,12 @@ config.link(c, "nic2.output -> tee.input") config.link(c, "tee.output1 -> filter1.input") config.link(c, "tee.output2 -> filter2.input") config.link(c, "filter1.output -> sink.in1") - --- send good packets back out through NIC to test vlan tag insertion --- use a filter to check presence of tag -config.link(c, "filter2.output -> nic2.input") -config.link(c, "nic1.output -> filter3.input") -config.link(c, "filter3.output -> sink.in2") +config.link(c, "filter2.output -> sink.in2") engine.configure(c) engine.main({ duration = 1 }) assert(link.stats(engine.app_table.sink.input.in1).rxpackets == 0, - "expected no vlan tagged packets (after stripping)") -assert(link.stats(engine.app_table.nic2.input.input).rxpackets > 0, - "expected some non-vlan tagged packets (after stripping)") + "expected zero vlan tagged packets (after stripping)") assert(link.stats(engine.app_table.sink.input.in2).rxpackets > 0, - "expected vlan tagged packets (after insertion)") + "expected some non-vlan tagged packets (after stripping)") From 590e2caedc4f3bac6cddd6bb9f540141c36473e1 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 6 Jun 2017 23:45:19 +0000 Subject: [PATCH 038/109] Add waits to avoid race conditions in vmdq tests --- src/apps/intel_mp/test_10g_2q_blast_vlan.sh | 2 ++ src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/apps/intel_mp/test_10g_2q_blast_vlan.sh b/src/apps/intel_mp/test_10g_2q_blast_vlan.sh index 7639910413..95ad68cd1a 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vlan.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vlan.sh @@ -6,8 +6,10 @@ SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source-vlan.pcap & BLAST=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 1 0 0 > results.0 & +PID1=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 2 1 4 > results.1 +wait $PID1 kill -9 $BLAST [[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ # both queues should see packets diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index b69a656f39..ca81f0fcbe 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -6,8 +6,10 @@ SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source2.pcap & BLAST=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" nil 0 0 > results.0 & +PID1=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 1 4 > results.1 +wait $PID1 kill -9 $BLAST [[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ From c0558d6f5a051c71d8c784ba38b704346f88898c Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 6 Jun 2017 23:45:55 +0000 Subject: [PATCH 039/109] Add documentation for new vmdq-related parameters --- src/apps/intel_mp/README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index 7847f7eb1b..13e5ea85e8 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -33,6 +33,32 @@ specified but assumed to be broadly applicable. *Optional*. The transmit queue to attach to, numbered from 0. +— Key **vmdq** + +*Optional*. A boolean parameter that specifies whether VMDq (Virtual Machine +Device Queues) is enabled. When VMDq is enabled, each instance of the driver +is associated with a *pool* that can be assigned a MAC address or VLAN tag. +Packets are delivered to pools that match the corresponding MACs or VLAN tags. +Each pool may be associated with several receive and transmit queues. + +For a given NIC, all driver instances should have this parameter either +enabled or disabled uniformly. If this is enabled, *macaddr* must be +specified. + +— Key **poolnum** + +*Optional*. The VMDq pool to associated with, numbered from 0. The default +is 0. + +— Key **macaddr** + +*Optional*. The MAC address to use as a string. The default is a wild-card +(i.e., accept all packets). + +— Key **vlan** +*Optional*. A twelve-bit integer (0-4095). If set, incoming packets from +other VLANs are dropped and outgoing packets are tagged with a VLAN header. + — Key **rsskey** *Optional*. The rsskey is a 32 bit integer that seeds the hash used to @@ -92,3 +118,7 @@ Each chipset supports a differing number of receive / transmit queues: * Intel82599 supports 16 receive and 16 transmit queues, 0-15 * Intel1g i350 supports 8 receive and 8 transmit queues, 0-7 * Intel1g i210 supports 4 receive and 4 transmit queues, 0-3 + +The Intel82599 supports both VMDq and RSS with 32/64 pools and 4/2 RSS queues for +each pool. This driver only supports configurations with 32 pools/4 queues. +While the i350 supports VMDq, this driver does not currently support it. From f83c6090ae1eeea7107e47926647d76cd7e5d328 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 6 Jun 2017 23:46:19 +0000 Subject: [PATCH 040/109] Refactor vmdq-related assertions --- src/apps/intel_mp/intel_mp.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 3fdd8b7d9d..cbd261ee3a 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -328,10 +328,8 @@ function Intel:new (conf) self.max_q = byid.max_q -- VMDq checks - assert(not self.vmdq or device == "0x10fb", "VMDq only supported on 82599") - assert(not self.macaddr or self.vmdq, "VMDq must be set to use MAC address") - assert(not self.poolnum or self.vmdq, "Pool number only supported for VMDq") if self.vmdq then + assert(device == "0x10fb", "VMDq only supported on 82599") assert(self.macaddr, "MAC address must be set in VMDq mode") assert(self.poolnum, "Pool number must be set in VMDq mode") assert(not self.rxq or @@ -345,6 +343,9 @@ function Intel:new (conf) assert(self.poolnum < 8, "Pool overflow: Intel i350 supports up to 8 VMDq pools") end + else + assert(not self.macaddr, "VMDq must be set to use MAC address") + assert(not self.poolnum, "VMDq must be set to specify a pool number") end -- Setup device access From 6b321ac645f37b3782ef7eec06e078bb2f6b9dca Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Wed, 7 Jun 2017 17:13:36 +0200 Subject: [PATCH 041/109] Make intel_mp tests run even when either 1G or 10G cards are not present --- src/apps/intel_mp/selftest.sh | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/apps/intel_mp/selftest.sh b/src/apps/intel_mp/selftest.sh index 064de9b649..dc54fe2c33 100755 --- a/src/apps/intel_mp/selftest.sh +++ b/src/apps/intel_mp/selftest.sh @@ -1,11 +1,16 @@ #!/usr/bin/env bash cd $(dirname $0) -[ -z $SNABB_PCI_INTEL1G0 ] && exit $TEST_SKIPPED -[ -z $SNABB_PCI_INTEL1G1 ] && exit $TEST_SKIPPED -[ -z $SNABB_PCI_INTEL0 ] && exit $TEST_SKIPPED -[ -z $SNABB_PCI_INTEL1 ] && exit $TEST_SKIPPED +if [ $SNABB_PCI_INTEL1G0 ] && [ $SNABB_PCI_INTEL1G1 ]; then + TESTS1G=$(find . -executable | grep -e 'test_1g') +fi +if [ $SNABB_PCI_INTEL0 ] && [ $SNABB_PCI_INTEL1 ]; then + TESTS10G=$(find . -executable | grep -e 'test_10g') +fi +if [ -z "$TESTS1G" ] && [ -z "$TESTS10G" ]; then + exit $TEST_SKIPPED +fi FILTER=${1:-.*} -TESTS=$(find . -executable | grep -e 'test[0-9]' -e 'test_' | grep -e "$FILTER" | sort) +TESTS=$(echo "$TESTS1G" "$TESTS10G" | grep -e "$FILTER" | sort) ESTATUS=0 export SNABB_RECV_DEBUG=true export SNABB_RECV_MASTER_STATS=true @@ -19,9 +24,9 @@ for i in $TESTS; do echo "PASSED: $i" else for res in `ls results.*`; do - echo $res; - cat $res - echo + echo $res; + cat $res + echo done echo "FAILED: $i" ESTATUS=-1 From f31b29a52705405c865a1026e3c49de01fc5c91a Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 7 Jun 2017 19:08:05 +0000 Subject: [PATCH 042/109] Adjust VMDq test for 82599 to be more robust There are multiple ids for 82599 variants that may be added later --- src/apps/intel_mp/intel_mp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index cbd261ee3a..64aab83f1b 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -329,7 +329,7 @@ function Intel:new (conf) -- VMDq checks if self.vmdq then - assert(device == "0x10fb", "VMDq only supported on 82599") + assert(byid.driver == Intel82599, "VMDq only supported on 82599") assert(self.macaddr, "MAC address must be set in VMDq mode") assert(self.poolnum, "Pool number must be set in VMDq mode") assert(not self.rxq or From 871494e254148139e768824fb4b3b352e82846d4 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 7 Jun 2017 23:01:51 +0000 Subject: [PATCH 043/109] Add VMDq consistency check for intel_mp apps Makes sure that all apps on a given NIC either use or don't use VMDq uniformly --- src/apps/intel_mp/intel_mp.lua | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 64aab83f1b..58c4bbde8a 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -356,6 +356,7 @@ function Intel:new (conf) self:init() self.fd:flock("sh") + self:check_vmdq() self:init_tx_q() self:init_rx_q() self:set_MAC() @@ -1000,6 +1001,9 @@ function Intel1g:init_queue_stats (frame) end end +function Intel1g:check_vmdq () + error("unimplemented") +end function Intel1g:vmdq_enable () error("unimplemented") end @@ -1026,6 +1030,7 @@ Intel82599.offsets = { } Intel82599.max_mac_addr = 127 Intel82599.max_vlan = 64 +Intel82599.mrqc_bits = 0xA function Intel82599:link_status () local mask = bits { Link_up = 30 } return bit.band(self.r.LINKS(), mask) == mask @@ -1177,6 +1182,20 @@ function Intel82599:init () self:unlock_sw_sem() end +-- helper method for checking that the main process used the same +-- VMDq setting if this is a worker process (noop on main) +function Intel82599:check_vmdq () + if not self.master then + if self.vmdq then + assert(self.r.MRQC:bits(0, 4) == self.mrqc_bits, + "VMDq not set by the main process for this NIC") + else + assert(self.r.MRQC:bits(0, 4) ~= self.mrqc_bits, + "VMDq was set by the main process for this NIC") + end + end +end + -- enable VMDq mode, see 4.6.10.1 -- follows the configuration flow in 4.6.11.3.3 -- (should only be called on the master instance) @@ -1185,7 +1204,7 @@ function Intel82599:vmdq_enable () self.r.RTTDCS:set(bits { ARBDIS=6 }) -- 1010 -> 32 pools, 4 RSS queues each - self.r.MRQC:bits(0, 4, 0xA) + self.r.MRQC:bits(0, 4, self.mrqc_bits) -- TODO: not sure this is needed, but it's in intel10g -- disable RSC (7.11) From a13a3859de5e043ee5242065446bc64602b08c41 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Fri, 9 Jun 2017 12:42:16 +0200 Subject: [PATCH 044/109] Disable VMDq check if not in VMDq mode --- src/apps/intel_mp/intel_mp.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 58c4bbde8a..cbe2ff363f 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -356,7 +356,9 @@ function Intel:new (conf) self:init() self.fd:flock("sh") - self:check_vmdq() + if self.vmdq then + self:check_vmdq() + end self:init_tx_q() self:init_rx_q() self:set_MAC() From 31229a602c2bd2a2bcf7fe7d32e322fb950e85fb Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 13 Jun 2017 20:57:49 +0000 Subject: [PATCH 045/109] Allow mirroring in VMDq mode Ported mirroring from intel10g driver. No VLAN mirroring implemented yet. Also added a test for mirroring. --- src/apps/intel_mp/intel_mp.lua | 93 ++++++++++++++++++++++- src/apps/intel_mp/test_10g_vmdq_mirror.sh | 64 ++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100755 src/apps/intel_mp/test_10g_vmdq_mirror.sh diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index cbe2ff363f..25629370b5 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -66,6 +66,9 @@ MPSAR 0x0A600 +0x04*0..255 RW MAC Pool Select Array PFUTA 0X0F400 +0x04*0..127 RW PF Unicast Table Array PFVLVF 0x0F100 +0x04*0..63 RW PF VM VLAN Pool Filter PFVLVFB 0x0F200 +0x04*0..127 RW PF VM VLAN Pool Filter Bitmap +PFMRCTL 0x0F600 +0x04*0..3 RW PF Mirror Rule Control +PFMRVLAN 0x0F610 +0x04*0..7 RW PF Mirror Rule VLAN +PFMRVM 0x0F630 +0x04*0..7 RW PF Mirror Rule Pool PFVFRE 0x051E0 +0x04*0..1 RW PF VF Receive Enable PFVFTE 0x08110 +0x04*0..1 RW PF VF Transmit Enable PFVFSPOOF 0x08200 +0x04*0..7 RW PF VF Anti Spoof Control @@ -271,6 +274,7 @@ Intel = { macaddr = {}, poolnum = {}, vlan = {}, + mirror = {}, txq = {}, rxq = {}, mtu = {default=9014}, @@ -316,6 +320,7 @@ function Intel:new (conf) poolnum = conf.poolnum, macaddr = conf.macaddr, vlan = conf.vlan, + want_mirror = conf.mirror, } local vendor = lib.firstline(self.path .. "/vendor") @@ -346,6 +351,7 @@ function Intel:new (conf) else assert(not self.macaddr, "VMDq must be set to use MAC address") assert(not self.poolnum, "VMDq must be set to specify a pool number") + assert(not self.mirror, "VMDq must be set to specify mirroring rules") end -- Setup device access @@ -363,7 +369,7 @@ function Intel:new (conf) self:init_rx_q() self:set_MAC() self:set_VLAN() - -- TODO: set mirror here + self:set_mirror() -- Initialize per app statistics counter.set(self.shm.mtu, self.mtu) @@ -719,6 +725,7 @@ function Intel:stop () if self.vmdq then self.unset_MAC() self.unset_VLAN() + self.unset_mirror() end if self.fd:flock("nb, ex") then self.r.CTRL:clr( bits { SETLINKUP = 6 } ) @@ -859,6 +866,90 @@ function Intel:unset_VLAN () end end +function Intel:set_mirror () + if not self.want_mirror then return end + want_mirror = self.want_mirror + + -- set MAC promiscuous + self.r.PFVML2FLT[self.poolnum]:set(bits{ + AUPE=24, ROMPE=25, ROPE=26, BAM=27, MPE=28}) + + -- pick one of a limited (4) number of mirroring rules + for idx=0, 3 do + -- check if no mirroring enable bits (3:0) are set + -- (i.e., this rule is unused and available) + if self.r.PFMRCTL[idx]:bits(0, 4) == 0 then + mirror_ndx = idx + break + -- there's already a rule for this pool, overwrite + elseif self.r.PFMRCTL[idx]:bits(8, 5) == self.poolnum then + mirror_ndx = idx + break + end + end + + assert(mirror_ndx, "Max number of mirroring rules reached") + + local mirror_rule = 0ULL + + -- mirror some or all pools + if want_mirror.pool then + mirror_rule = bor(bits{VPME=0}, mirror_rule) + if want_mirror.pool == true then -- mirror all pools + self.r.PFMRVM[mirror_ndx](0xFFFFFFFF) + self.r.PFMRVM[mirror_ndx+4](0xFFFFFFFF) + elseif type(want_mirror.pool) == 'table' then + local bm0 = self.r.PFMRVM[mirror_ndx]() + local bm1 = self.r.PFMRVM[mirror_ndx+4]() + for _, pool in ipairs(want_mirror.pool) do + if pool <= 32 then + bm0 = bor(lshift(1, pool), bm0) + else + bm1 = bor(lshift(1, pool-32), bm1) + end + end + self.r.PFMRVM[mirror_ndx](bm0) + self.r.PFMRVM[mirror_ndx+4](bm1) + end + end + + -- mirror hardware port + if want_mirror.port then + if want_mirror.port == true or + want_mirror.port == 'in' or + want_mirror.port == 'inout' then + mirror_rule = bor(bits{UPME=1}, mirror_rule) + end + if want_mirror.port == true or + want_mirror.port == 'out' or + want_mirror.port == 'inout' then + mirror_rule = bor(bits{DPME=2}, mirror_rule) + end + end + + -- TODO: implement VLAN mirroring + + if mirror_rule ~= 0 then + mirror_rule = bor(mirror_rule, lshift(self.poolnum, 8)) + self.r.PFMRCTL[mirror_ndx]:set(mirror_rule) + end +end + +function Intel:unset_mirror () + for rule_i = 0, 3 do + -- check if any mirror rule points here + local rule_dest = band(bit.rshift(self.r.PFMRCTL[rule_i](), 8), 63) + local bits = band(self.r.PFMRCTL[rule_i](), 0x07) + if bits ~= 0 and rule_dest == self.poolnum then + self.r.PFMRCTL[rule_i](0x0) -- clear rule + self.r.PFMRVLAN[rule_i](0x0) -- clear VLANs mirrored + self.r.PFMRVLAN[rule_i+4](0x0) + self.r.PFMRVM[rule_i](0x0) -- clear pools mirrored + self.r.PFMRVM[rule_i+4](0x0) + end + end +end + function Intel:rxpackets () return self.r.GPRC() end function Intel:txpackets () return self.r.GPTC() end function Intel:rxmcast () return self.r.MPRC() + self.r.BPRC() end diff --git a/src/apps/intel_mp/test_10g_vmdq_mirror.sh b/src/apps/intel_mp/test_10g_vmdq_mirror.sh new file mode 100755 index 0000000000..f5cca92af3 --- /dev/null +++ b/src/apps/intel_mp/test_10g_vmdq_mirror.sh @@ -0,0 +1,64 @@ +#!../../snabb snsh + +-- Snabb test script for mirroring rules in VMDq mode + +local basic_apps = require("apps.basic.basic_apps") +local intel = require("apps.intel_mp.intel_mp") +local pcap = require("apps.pcap.pcap") +local lib = require("core.lib") + +local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") +local pciaddr1 = lib.getenv("SNABB_PCI_INTEL1") + +local c = config.new() + +-- send packets on nic0 +config.app(c, "nic0", intel.Intel, + { pciaddr = pciaddr0, + txq = 0, + wait_for_link = true }) + +-- nic1 with three pools with several mirror configs +config.app(c, "nic1p0", intel.Intel, + { pciaddr = pciaddr1, + vmdq = true, + poolnum = 0, + macaddr = "90:72:82:78:c9:7a", + rxq = 0, + wait_for_link = true }) + +config.app(c, "nic1p1", intel.Intel, + { pciaddr = pciaddr1, + vmdq = true, + poolnum = 1, + mirror = { pool = { 0 } }, + macaddr = "12:34:56:78:9a:bc", + rxq = 4, + wait_for_link = true }) + +config.app(c, "nic1p2", intel.Intel, + { pciaddr = pciaddr1, + vmdq = true, + poolnum = 2, + mirror = { pool = true }, + macaddr = "aa:aa:aa:aa:aa:aa", + rxq = 8, + wait_for_link = true }) + +config.app(c, "pcap", pcap.PcapReader, "source2.pcap") +config.app(c, 'sink', basic_apps.Sink) + +config.link(c, "pcap.output -> nic0.input") +config.link(c, "nic1p0.output -> sink.input0") +config.link(c, "nic1p1.output -> sink.input1") +config.link(c, "nic1p2.output -> sink.input2") + +engine.configure(c) +engine.main({ duration = 1 }) + +assert(link.stats(engine.app_table.sink.input.input0).rxpackets == 51, + "wrong number of packets received on pool 0") +assert(link.stats(engine.app_table.sink.input.input1).rxpackets == 102, + "wrong number of packets received on pool 1") +assert(link.stats(engine.app_table.sink.input.input2).rxpackets == 102, + "wrong number of packets received on pool 2") From 59deb3502a8d4be3a855283e54df6f38b3330a81 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 14 Jun 2017 21:21:15 +0000 Subject: [PATCH 046/109] Avoid use of `bits` function in hot code The `bits` function is slow because of the call to `pairs` inside of it. --- src/apps/intel_mp/intel_mp.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 25629370b5..744efde235 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1052,14 +1052,13 @@ function Intel1g:init () end function Intel1g:link_status () - local mask = bits { Link_up = 1 } - return bit.band(self.r.STATUS(), mask) == mask + return bit.band(self.r.STATUS(), lshift(1, 1)) == mask end function Intel1g:link_speed () return ({10000,100000,1000000,1000000})[1+bit.band(bit.rshift(self.r.STATUS(), 6),3)] end function Intel1g:promisc () - return band(self.r.RCTL(), bits{UPE=3}) ~= 0ULL + return band(self.r.RCTL(), lshift(1, 3)) ~= 0ULL end function Intel1g:rxbytes () return self.r.GORCH()*2^32 + self.r.GORCL() end function Intel1g:rxdrop () return self.r.MPC() + self.r.RNBC() end @@ -1125,7 +1124,7 @@ Intel82599.max_mac_addr = 127 Intel82599.max_vlan = 64 Intel82599.mrqc_bits = 0xA function Intel82599:link_status () - local mask = bits { Link_up = 30 } + local mask = lshift(1, 30) return bit.band(self.r.LINKS(), mask) == mask end function Intel82599:link_speed () @@ -1136,7 +1135,7 @@ function Intel82599:link_speed () or 1000000 -- 100 Mb/s end function Intel82599:promisc () - return band(self.r.FCTRL(), bits{UPE=9}) ~= 0ULL + return band(self.r.FCTRL(), lshift(1, 9)) ~= 0ULL end function Intel82599:rxbytes () return self.r.GORC64() end function Intel82599:rxdrop () return self.r.QPRDC[0]() end From 2d288c144b445c4936640206dfd96a8d01e228be Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 14 Jun 2017 21:57:02 +0000 Subject: [PATCH 047/109] Avoid `pairs` in more places in intel_mp --- src/apps/intel_mp/intel_mp.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 744efde235..5494d84362 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -756,7 +756,8 @@ function Intel:sync_stats () set(stats.txdrop, self:txdrop()) set(stats.txerrors, self:txerrors()) set(stats.rxdmapackets, self:rxdmapackets()) - for name, register in pairs(self.queue_stats) do + for idx = 1, #self.queue_stats, 2 do + local name, register = self.queue_stats[idx], self.queue_stats[idx+1] set(stats[name], register()) end end @@ -1087,7 +1088,8 @@ function Intel1g:init_queue_stats (frame) for i=0,self.max_q-1 do for k,v in pairs(perqregs) do local name = "q" .. i .. "_" .. k - self.queue_stats[name] = self.r[v][i] + table.insert(self.queue_stats, name) + table.insert(self.queue_stats, self.r[v][i]) frame[name] = {counter} end end @@ -1162,7 +1164,8 @@ function Intel82599:init_queue_stats (frame) for i=0,15 do for k,v in pairs(perqregs) do local name = "q" .. i .. "_" .. k - self.queue_stats[name] = self.r[v][i] + table.insert(self.queue_stats, name) + table.insert(self.queue_stats, self.r[v][i]) frame[name] = {counter} end end From 656ce13abd2be25c0549b0f60cf57dc984da81cf Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 15 Jun 2017 16:53:29 +0000 Subject: [PATCH 048/109] Fix mistake in commit d1b0a87fb23ce9b49a --- src/apps/intel_mp/intel_mp.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 5494d84362..8441c215ed 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1053,7 +1053,8 @@ function Intel1g:init () end function Intel1g:link_status () - return bit.band(self.r.STATUS(), lshift(1, 1)) == mask + local mask = lshift(1, 1) + return bit.band(self.r.STATUS(), mask) == mask end function Intel1g:link_speed () return ({10000,100000,1000000,1000000})[1+bit.band(bit.rshift(self.r.STATUS(), 6),3)] From f2e8e3073e2ae41de9f08b1f4304593940c81402 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 15 Jun 2017 17:31:44 +0000 Subject: [PATCH 049/109] Sort keys in debug prinouts for easier reading --- src/apps/intel_mp/intel_mp.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 8441c215ed..1cc88d759a 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1426,8 +1426,13 @@ function Intel:debug (args) end if prnt then - for k,v in pairs(r) do - print(pfx..k,v) + local keys = {} + for k,_ in pairs(r) do + table.insert(keys, k) + end + table.sort(keys) + for _,k in ipairs(keys) do + print(pfx..k, r[k]) end end return r From 5de384a23920736b27e8bdce28a8cae8ec1210ec Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 15 Jun 2017 23:20:31 +0000 Subject: [PATCH 050/109] Fix offsets for QBTC/QPTC registers See page 705 in the 82599 datasheet --- src/apps/intel_mp/intel_mp.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 1cc88d759a..cd02b0919e 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -77,8 +77,8 @@ PFVML2FLT 0x0F000 +0x04*0..63 RW PF VM L2 Control Register QPRC 0x01030 +0x40*0..15 RC Queue Packets Received Count QPRDC 0x01430 +0x40*0..15 RC Queue Packets Received Drop Count QBRC64 0x01034 +0x40*0..15 RC64 Queue Bytes Received Count -QPTC 0x08680 +0x40*0..15 RC Queue Packets Transmitted Count -QBTC64 0x08700 +0x40*0..15 RC64 Queue Bytes Transmitted Count Low +QPTC 0x08680 +0x04*0..15 RC Queue Packets Transmitted Count +QBTC64 0x08700 +0x08*0..15 RC64 Queue Bytes Transmitted Count Low SAQF 0x0E000 +0x04*0..127 RW Source Address Queue Filter SDPQF 0x0E400 +0x04*0..127 RW Source Destination Port Queue Filter PSRTYPE 0x0EA00 +0x04*0..63 RW Packet Split Receive Type Register From ddf0a241a2461200755da3bb9296eb9890360b73 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 16 Jun 2017 00:01:37 +0000 Subject: [PATCH 051/109] Add rxcounter support in intel_mp Allows queue counters to be assigned to app instances as the intel10g driver allows. Also implements get_rxstats(). For 1g NICs, get_rxstats() gets the stats for the (non-user assigned) per-queue registers. --- src/apps/intel_mp/intel_mp.lua | 43 +++++++++++++++++++++++ src/apps/intel_mp/test_10g_vmdq_mirror.sh | 11 ++++++ 2 files changed, 54 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index cd02b0919e..fa6737acc9 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -90,6 +90,7 @@ RTTDT2C 0x04910 +0x04*0..7 RW DCB Transmit Descriptor Plane T2 Config RTTPT2C 0x0CD20 +0x04*0..7 RW DCB Transmit Packet Plane T2 Config RTRPT4C 0x02140 +0x04*0..7 RW DCB Receive Packet Plane T4 Config RXPBSIZE 0x03C00 +0x04*0..7 RW Receive Packet Buffer Size +RQSMR 0x02300 +0x04*0..31 RW Receive Queue Statistic Mapping Registers TQSM 0x08600 +0x04*0..31 RW Transmit Queue Statistic Mapping Registers TXPBSIZE 0x0CC00 +0x04*0..7 RW Transmit Packet Buffer Size TXPBTHRESH 0x04950 +0x04*0..7 RW Tx Packet Buffer Threshold @@ -275,6 +276,7 @@ Intel = { poolnum = {}, vlan = {}, mirror = {}, + rxcounter = {}, txq = {}, rxq = {}, mtu = {default=9014}, @@ -321,6 +323,7 @@ function Intel:new (conf) macaddr = conf.macaddr, vlan = conf.vlan, want_mirror = conf.mirror, + rxcounter = conf.rxcounter, } local vendor = lib.firstline(self.path .. "/vendor") @@ -370,6 +373,7 @@ function Intel:new (conf) self:set_MAC() self:set_VLAN() self:set_mirror() + self:set_rxstats() -- Initialize per app statistics counter.set(self.shm.mtu, self.mtu) @@ -1096,6 +1100,22 @@ function Intel1g:init_queue_stats (frame) end end +function Intel1g:get_rxstats () + assert(self.rxq, "cannot retrieve rxstats without rxq") + local frame = shm.open_frame("pci/"..self.pciaddress) + local rxc = self.rxq + return { + counter_id = rxc, + packets = counter.read(frame["q"..rxc.."_rxpackets"]), + dropped = counter.read(frame["q"..rxc.."_rxdrops"]), + bytes = counter.read(frame["q"..rxc.."_rxbytes"]) + } +end + +-- noop because 1g NICs have per-queue counters that aren't +-- configurable +function Intel1g:set_rxstats () return end + function Intel1g:check_vmdq () error("unimplemented") end @@ -1369,6 +1389,29 @@ function Intel82599:unset_MAC () end end +-- return rxstats for the counter assigned to this queue +-- the data has to be read from the shm frame since the main instance +-- is in control of the counter registers (and clears them on read) +function Intel82599:get_rxstats () + assert(self.rxcounter and self.rxq, "cannot retrieve rxstats") + local frame = shm.open_frame("pci/"..self.pciaddress) + local rxc = self.rxcounter + return { + counter_id = rxc, + packets = counter.read(frame["q"..rxc.."_rxpackets"]), + dropped = counter.read(frame["q"..rxc.."_rxdrops"]), + bytes = counter.read(frame["q"..rxc.."_rxbytes"]) + } +end + +-- enable the given counter for this app's rx queue +function Intel82599:set_rxstats () + if not self.rxcounter or not self.rxq then return end + local counter = self.rxcounter + assert(counter>=0 and counter<16, "bad Rx counter") + self.r.RQSMR[math.floor(self.rxq/4)]:set(lshift(counter,8*(self.rxq%4))) +end + function Intel:debug (args) local args = args or {} local pfx = args.prefix or "DEBUG_" diff --git a/src/apps/intel_mp/test_10g_vmdq_mirror.sh b/src/apps/intel_mp/test_10g_vmdq_mirror.sh index f5cca92af3..f0502d532c 100755 --- a/src/apps/intel_mp/test_10g_vmdq_mirror.sh +++ b/src/apps/intel_mp/test_10g_vmdq_mirror.sh @@ -1,6 +1,8 @@ #!../../snabb snsh -- Snabb test script for mirroring rules in VMDq mode +-- +-- Also tests rxcounters for consistency with link counts local basic_apps = require("apps.basic.basic_apps") local intel = require("apps.intel_mp.intel_mp") @@ -25,6 +27,7 @@ config.app(c, "nic1p0", intel.Intel, poolnum = 0, macaddr = "90:72:82:78:c9:7a", rxq = 0, + rxcounter = 1, wait_for_link = true }) config.app(c, "nic1p1", intel.Intel, @@ -34,6 +37,7 @@ config.app(c, "nic1p1", intel.Intel, mirror = { pool = { 0 } }, macaddr = "12:34:56:78:9a:bc", rxq = 4, + rxcounter = 2, wait_for_link = true }) config.app(c, "nic1p2", intel.Intel, @@ -43,6 +47,7 @@ config.app(c, "nic1p2", intel.Intel, mirror = { pool = true }, macaddr = "aa:aa:aa:aa:aa:aa", rxq = 8, + rxcounter = 3, wait_for_link = true }) config.app(c, "pcap", pcap.PcapReader, "source2.pcap") @@ -58,7 +63,13 @@ engine.main({ duration = 1 }) assert(link.stats(engine.app_table.sink.input.input0).rxpackets == 51, "wrong number of packets received on pool 0") +assert(engine.app_table.nic1p0:get_rxstats().packets == 51, + "expected get_rxstats and link stats to agree") assert(link.stats(engine.app_table.sink.input.input1).rxpackets == 102, "wrong number of packets received on pool 1") +assert(engine.app_table.nic1p1:get_rxstats().packets == 102, + "expected get_rxstats and link stats to agree") assert(link.stats(engine.app_table.sink.input.input2).rxpackets == 102, "wrong number of packets received on pool 2") +assert(engine.app_table.nic1p2:get_rxstats().packets == 102, + "expected get_rxstats and link stats to agree") From 37b7c2b25a20e628518355ada795a3ce5fc816ac Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 16 Jun 2017 21:37:45 +0000 Subject: [PATCH 052/109] Add txcounter support in intel_mp Similar to the rxcounter support. This also enables counter sync in the `push` method so that statistics are available when only Tx is enabled for the app. --- src/apps/intel_mp/intel_mp.lua | 39 ++++++++++++++++++++++++++++++ src/apps/intel_mp/testvmdqtx.snabb | 8 ++++++ 2 files changed, 47 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index fa6737acc9..a870ffd934 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -277,6 +277,7 @@ Intel = { vlan = {}, mirror = {}, rxcounter = {}, + txcounter = {}, txq = {}, rxq = {}, mtu = {default=9014}, @@ -324,6 +325,7 @@ function Intel:new (conf) vlan = conf.vlan, want_mirror = conf.mirror, rxcounter = conf.rxcounter, + txcounter = conf.txcounter, } local vendor = lib.firstline(self.path .. "/vendor") @@ -374,6 +376,7 @@ function Intel:new (conf) self:set_VLAN() self:set_mirror() self:set_rxstats() + self:set_txstats() -- Initialize per app statistics counter.set(self.shm.mtu, self.mtu) @@ -601,6 +604,11 @@ function Intel:push () cursor = self:ringnext(cursor) end self.r.TDT(self.tdt) + + -- same code as in pull, we repeat it in case this app only enables Tx + if self.run_stats and self.sync_timer() then + self:sync_stats() + end end function Intel:pull () @@ -1112,9 +1120,21 @@ function Intel1g:get_rxstats () } end +function Intel1g:get_txstats () + assert(self.txq, "cannot retrieve rxstats without txq") + local frame = shm.open_frame("pci/"..self.pciaddress) + local txc = self.txq + return { + counter_id = txc, + packets = counter.read(frame["q"..txc.."_txpackets"]), + bytes = counter.read(frame["q"..txc.."_txbytes"]) + } +end + -- noop because 1g NICs have per-queue counters that aren't -- configurable function Intel1g:set_rxstats () return end +function Intel1g:set_txstats () return end function Intel1g:check_vmdq () error("unimplemented") @@ -1404,6 +1424,17 @@ function Intel82599:get_rxstats () } end +function Intel82599:get_txstats () + assert(self.txcounter and self.txq, "cannot retrieve txstats") + local frame = shm.open_frame("pci/"..self.pciaddress) + local txc = self.txcounter + return { + counter_id = txc, + packets = counter.read(frame["q"..txc.."_txpackets"]), + bytes = counter.read(frame["q"..txc.."_txbytes"]) + } +end + -- enable the given counter for this app's rx queue function Intel82599:set_rxstats () if not self.rxcounter or not self.rxq then return end @@ -1412,6 +1443,14 @@ function Intel82599:set_rxstats () self.r.RQSMR[math.floor(self.rxq/4)]:set(lshift(counter,8*(self.rxq%4))) end +-- enable the given counter for this app's tx queue +function Intel82599:set_txstats () + if not self.txcounter or not self.txq then return end + local counter = self.txcounter + assert(counter>=0 and counter<16, "bad Tx counter") + self.r.TQSM[math.floor(self.txq/4)]:set(lshift(counter,8*(self.txq%4))) +end + function Intel:debug (args) local args = args or {} local pfx = args.prefix or "DEBUG_" diff --git a/src/apps/intel_mp/testvmdqtx.snabb b/src/apps/intel_mp/testvmdqtx.snabb index 9fd3b23d79..94efcf7325 100755 --- a/src/apps/intel_mp/testvmdqtx.snabb +++ b/src/apps/intel_mp/testvmdqtx.snabb @@ -2,6 +2,8 @@ -- Snabb test script for transmit in VMDq mode, also tests VLAN -- tag insertion +-- +-- Also ensures that the Tx counters work local args = main.parameters assert(#args == 4, "testvmdqtx.snabb pciaddr1 pciaddr2 macaddr pcapfile") @@ -25,6 +27,7 @@ config.app(c, "nic1", intel.Intel, macaddr = macaddr, poolnum = 0, txq = 0, + txcounter = 1, vlan = 1, ndescriptors=2048, wait_for_link = true }) @@ -47,7 +50,12 @@ config.link(c, "filter.output -> sink.input") engine.configure(c) engine.main({ duration = 1 }) +assert(link.stats(engine.app_table.nic1.input.input).rxpackets > 0, + "expected some packets from pcap to Tx NIC") assert(link.stats(engine.app_table.filter.input.input).rxpackets > 0, "expected some packets on the receiving NIC") +assert(link.stats(engine.app_table.filter.input.input).rxpackets == + engine.app_table.nic1:get_txstats().packets, + "expected txstats() to match up with link stats") assert(link.stats(engine.app_table.sink.input.input).rxpackets > 0, "expected VLAN tagged packets on the receiving NIC") From 142896df91cf0746c37da64716a39155129d3e25 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 16 Jun 2017 23:21:48 +0000 Subject: [PATCH 053/109] Port Tx rate limit and priority code to intel_mp --- src/apps/intel_mp/intel_mp.lua | 30 +++++++++++++++++ src/apps/intel_mp/test_10g_rate_limit.sh | 43 ++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100755 src/apps/intel_mp/test_10g_rate_limit.sh diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index a870ffd934..df95835bd5 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -278,6 +278,8 @@ Intel = { mirror = {}, rxcounter = {}, txcounter = {}, + rate_limit = {default=0}, + priority = {default=1.0}, txq = {}, rxq = {}, mtu = {default=9014}, @@ -326,6 +328,8 @@ function Intel:new (conf) want_mirror = conf.mirror, rxcounter = conf.rxcounter, txcounter = conf.txcounter, + limit = conf.rate_limit, + priority = conf.priority, } local vendor = lib.firstline(self.path .. "/vendor") @@ -377,6 +381,7 @@ function Intel:new (conf) self:set_mirror() self:set_rxstats() self:set_txstats() + self:set_tx_rate() -- Initialize per app statistics counter.set(self.shm.mtu, self.mtu) @@ -739,6 +744,7 @@ function Intel:stop () self.unset_VLAN() self.unset_mirror() end + self.unset_tx_rate() if self.fd:flock("nb, ex") then self.r.CTRL:clr( bits { SETLINKUP = 6 } ) --self.r.CTRL_EXT:clear( bits { DriverLoaded = 28 }) @@ -1154,6 +1160,9 @@ function Intel1g:unset_MAC () end end +function Intel1g:set_tx_rate () return end +function Intel1g:unset_tx_rate () return end + Intel82599.driver = "Intel82599" Intel82599.offsets = { SRRCTL = { @@ -1409,6 +1418,27 @@ function Intel82599:unset_MAC () end end +function Intel82599:set_tx_rate () + if not self.txq then return end + self.r.RTTDQSEL(self.poolnum or self.txq) + if self.limit >= 10 then + -- line rate = 10,000 Mb/s + local factor = 10000 / tonumber(self.limit) + -- 10.14 bits + factor = bit.band(math.floor(factor*2^14+0.5), 2^24-1) + self.r.RTTBCNRC(bits({RS_ENA=31}, factor)) + else + self.r.RTTBCNRC(0x00) + end + self.r.RTTDT1C(bit.band(math.floor(self.priority * 0x80), 0x3FF)) +end + +function Intel82599:unset_tx_rate () + self.limit = 0 + self.priority = 0 + self:set_tx_rate() +end + -- return rxstats for the counter assigned to this queue -- the data has to be read from the shm frame since the main instance -- is in control of the counter registers (and clears them on read) diff --git a/src/apps/intel_mp/test_10g_rate_limit.sh b/src/apps/intel_mp/test_10g_rate_limit.sh new file mode 100755 index 0000000000..412128781f --- /dev/null +++ b/src/apps/intel_mp/test_10g_rate_limit.sh @@ -0,0 +1,43 @@ +#!../../snabb snsh + +-- Snabb test script for testing Tx rate limits + +local basic_apps = require("apps.basic.basic_apps") +local intel = require("apps.intel_mp.intel_mp") +local lib = require("core.lib") + +local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") +local pciaddr1 = lib.getenv("SNABB_PCI_INTEL1") + +local c = config.new() + +-- send packets on nic0 +config.app(c, "nic0", intel.driver, + { pciaddr = pciaddr0, + txq = 0, + -- minimum possible rate of 10Mbps + rate_limit = 10, + wait_for_link = true }) + +-- receive nic +config.app(c, "nic1", intel.driver, + { pciaddr = pciaddr1, + rxq = 0, + rxcounter = 1, + wait_for_link = true }) + +-- send 1KB packets repeatedly +config.app(c, "source", basic_apps.Source, 1024) +config.app(c, 'sink', basic_apps.Sink) + +config.link(c, "source.output -> nic0.input") +config.link(c, "nic1.output -> sink.input") + +engine.configure(c) +engine.main({ duration = 1 }) + +-- check that the stats show within 10% of 10Mb +local rxbytes = engine.app_table.nic1:get_rxstats().bytes +local target = 2^17 * 10 +assert(rxbytes > target * 0.90 and rxbytes < target * 1.10, + "expected about 1310720 bytes (10Mb), got " .. tonumber(rxbytes) .. " bytes") From 1cf3239de5f860dbef8ee8f67628971060fbf44e Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 19 Jun 2017 15:31:38 +0000 Subject: [PATCH 054/109] Fix silly typo in method call --- src/apps/intel_mp/intel_mp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index df95835bd5..3945990640 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -744,7 +744,7 @@ function Intel:stop () self.unset_VLAN() self.unset_mirror() end - self.unset_tx_rate() + self:unset_tx_rate() if self.fd:flock("nb, ex") then self.r.CTRL:clr( bits { SETLINKUP = 6 } ) --self.r.CTRL_EXT:clear( bits { DriverLoaded = 28 }) From 071290a2071d505a8429cbc481a51e805fb177d4 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 20 Jun 2017 22:21:14 +0000 Subject: [PATCH 055/109] Add code from intel10g for discarding unsent pkts Replaces crashing code that was just using packet.free on all of the txqueue elements. --- src/apps/intel_mp/intel_mp.lua | 21 +++++++++++++++------ src/apps/intel_mp/test_10g_txq_stop.sh | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) create mode 100755 src/apps/intel_mp/test_10g_txq_stop.sh diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 3945990640..3349f142be 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -730,14 +730,9 @@ function Intel:stop () --TXDCTL[n].SWFLSH and wait --wait until tdh == tdt --wait on rxd[tdh].status = dd + self:discard_unsent_packets() self.r.TXDCTL(0) self.r.TXDCTL:wait(bits { ENABLE = 25 }, 0) - for i = 0, self.ndesc-1 do - if self.txqueue[i] then - packet.free(self.txqueue[i]) - self.txqueue[i] = nil - end - end end if self.vmdq then self.unset_MAC() @@ -756,6 +751,20 @@ function Intel:stop () end end +function Intel:discard_unsent_packets () + local old_tdt = self.tdt + self.tdt = self.r.TDT() + self.tdh = self.r.TDH() + self.r.TDT(self.tdh) + while old_tdt ~= self.tdh do + old_tdt = band(old_tdt - 1, self.ndesc - 1) + packet.free(self.txqueue[old_tdt]) + self.txdesc[old_tdt].address = -1 + self.txdesc[old_tdt].options = 0 + end + self.tdt = self.tdh +end + function Intel:sync_stats () local set, stats = counter.set, self.stats set(stats.speed, self:link_speed()) diff --git a/src/apps/intel_mp/test_10g_txq_stop.sh b/src/apps/intel_mp/test_10g_txq_stop.sh new file mode 100755 index 0000000000..8015501bcf --- /dev/null +++ b/src/apps/intel_mp/test_10g_txq_stop.sh @@ -0,0 +1,24 @@ +#!../../snabb snsh + +-- Test to make sure the app shuts down propertly on reconfiguration + +local intel = require("apps.intel_mp.intel_mp") +local lib = require("core.lib") + +local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") +local pciaddr1 = lib.getenv("SNABB_PCI_INTEL1") + +local c = config.new() + +config.app(c, "n1", intel.Intel, + { pciaddr = pciaddr1, + rxq = 0, + txq = 0, + wait_for_link = true }) + +engine.configure(c) +engine.main({ duration = 1 }) + +local c2 = config.new() +engine.configure(c2) +engine.main({ duration = 1 }) From 87e0d45df87ce55fa2b3146277add73bd5e88905 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 20 Jun 2017 22:25:39 +0000 Subject: [PATCH 056/109] Fix some buggy app teardown code in intel_mp --- src/apps/intel_mp/intel_mp.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 3349f142be..50bc981aa8 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -735,9 +735,9 @@ function Intel:stop () self.r.TXDCTL:wait(bits { ENABLE = 25 }, 0) end if self.vmdq then - self.unset_MAC() - self.unset_VLAN() - self.unset_mirror() + self:unset_MAC() + self:unset_VLAN() + self:unset_mirror() end self:unset_tx_rate() if self.fd:flock("nb, ex") then @@ -845,7 +845,7 @@ function Intel:add_receive_VLAN (vlan) -- scan to see if the VLAN is already recorded or find the -- first free VLAN index - for idx=1, self.max_vlan do + for idx=0, self.max_vlan-1 do local valid = self.r.PFVLVF[idx]:bits(31, 1) if valid == 0 then @@ -1423,7 +1423,7 @@ end function Intel82599:unset_MAC () local msk = bits { Ena=self.poolnum%32 } for mac_index = 0, self.max_mac_addr do - pf.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)]:clr(msk) + self.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)]:clr(msk) end end From d276077f66637deb5294bac12f6825915d3f35c1 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 20 Jun 2017 22:39:24 +0000 Subject: [PATCH 057/109] Fix teardown test for this branch The test depended on some modifications from another branch that disabled app link presence tests. --- src/apps/intel_mp/test_10g_txq_stop.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/apps/intel_mp/test_10g_txq_stop.sh b/src/apps/intel_mp/test_10g_txq_stop.sh index 8015501bcf..1713bd49ed 100755 --- a/src/apps/intel_mp/test_10g_txq_stop.sh +++ b/src/apps/intel_mp/test_10g_txq_stop.sh @@ -2,6 +2,7 @@ -- Test to make sure the app shuts down propertly on reconfiguration +local basic_apps = require("apps.basic.basic_apps") local intel = require("apps.intel_mp.intel_mp") local lib = require("core.lib") @@ -15,6 +16,10 @@ config.app(c, "n1", intel.Intel, rxq = 0, txq = 0, wait_for_link = true }) +config.app(c, "source", basic_apps.Source) +config.app(c, "sink", basic_apps.Sink) +config.link(c, "source.output -> n1.input") +config.link(c, "n1.output -> sink.input") engine.configure(c) engine.main({ duration = 1 }) From a236d29fa77484b8cdbd6a259f4e2c61f80b573b Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 21 Jun 2017 22:28:13 +0000 Subject: [PATCH 058/109] Rename `limit` field to `rate_limit` --- src/apps/intel_mp/intel_mp.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 50bc981aa8..8e07c7b1fc 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -328,7 +328,7 @@ function Intel:new (conf) want_mirror = conf.mirror, rxcounter = conf.rxcounter, txcounter = conf.txcounter, - limit = conf.rate_limit, + rate_limit = conf.rate_limit, priority = conf.priority, } @@ -1430,9 +1430,9 @@ end function Intel82599:set_tx_rate () if not self.txq then return end self.r.RTTDQSEL(self.poolnum or self.txq) - if self.limit >= 10 then + if self.rate_limit >= 10 then -- line rate = 10,000 Mb/s - local factor = 10000 / tonumber(self.limit) + local factor = 10000 / tonumber(self.rate_limit) -- 10.14 bits factor = bit.band(math.floor(factor*2^14+0.5), 2^24-1) self.r.RTTBCNRC(bits({RS_ENA=31}, factor)) @@ -1443,7 +1443,7 @@ function Intel82599:set_tx_rate () end function Intel82599:unset_tx_rate () - self.limit = 0 + self.rate_limit = 0 self.priority = 0 self:set_tx_rate() end From ce2e400320df0bd4ec9b1c4c95b1fa64d61862b6 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 21 Jun 2017 23:31:40 +0000 Subject: [PATCH 059/109] Fix another typo in VLAN code --- src/apps/intel_mp/intel_mp.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 8e07c7b1fc..a24ca89a97 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -855,11 +855,10 @@ function Intel:add_receive_VLAN (vlan) break else if self.r.PFVLVF[idx]:bits(0, 11) == vlan then - mac_index = idx + vlan_index = idx break end end - end assert(vlan_index, "Max number of VLAN IDs reached") From 34d2612252f5abab241b7fb30bfea63a78f6450f Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 19 Jun 2017 09:24:15 +0200 Subject: [PATCH 060/109] Add default for number of pools --- src/apps/intel_mp/README.md | 4 ++-- src/apps/intel_mp/intel_mp.lua | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index 13e5ea85e8..13bf176a9d 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -27,11 +27,11 @@ specified but assumed to be broadly applicable. — Key **rxq** -*Optional*. The receive queue to attach to, numbered from 0. +*Optional*. The receive queue to attach to, numbered from 0. The default is 0. — Key **txq** -*Optional*. The transmit queue to attach to, numbered from 0. +*Optional*. The transmit queue to attach to, numbered from 0. The default is 0. — Key **vmdq** diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index a24ca89a97..e77407e7d4 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -273,7 +273,7 @@ Intel = { ndescriptors = {default=2048}, vmdq = {default=false}, macaddr = {}, - poolnum = {}, + poolnum = {default=0}, vlan = {}, mirror = {}, rxcounter = {}, From a9d7c31152bf979cf43951c213fe3a8b38b0ed67 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 19 Jun 2017 09:53:28 +0200 Subject: [PATCH 061/109] Remove redundant poolnum check --- src/apps/intel_mp/intel_mp.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index e77407e7d4..0e6743db23 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -345,7 +345,6 @@ function Intel:new (conf) if self.vmdq then assert(byid.driver == Intel82599, "VMDq only supported on 82599") assert(self.macaddr, "MAC address must be set in VMDq mode") - assert(self.poolnum, "Pool number must be set in VMDq mode") assert(not self.rxq or (self.rxq >= 4 * self.poolnum and self.rxq <= 4 * self.poolnum + 3), From 07baa180e7c8de2c31b06814a106a5c3d8325756 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 19 Jun 2017 12:15:06 +0200 Subject: [PATCH 062/109] Remove another redundant check on poolnum --- src/apps/intel_mp/intel_mp.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 0e6743db23..6ac3834db1 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -358,7 +358,6 @@ function Intel:new (conf) end else assert(not self.macaddr, "VMDq must be set to use MAC address") - assert(not self.poolnum, "VMDq must be set to specify a pool number") assert(not self.mirror, "VMDq must be set to specify mirroring rules") end From 41380721fae60ff3c968192e2d5014849e75fead Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 19 Jun 2017 14:55:31 +0200 Subject: [PATCH 063/109] Replace intel1g with intel_mp in comments and strings --- src/apps/intel_mp/intel_mp.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 6ac3834db1..4675a6bbb9 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1,4 +1,4 @@ --- intel1g: Device driver app for Intel 1G and 10G network cards +-- intel_mp: Device driver app for Intel 1G and 10G network cards -- It supports -- - Intel1G i210 and i350 based 1G network cards -- - Intel82599 82599 based 10G network cards @@ -580,7 +580,7 @@ end function Intel:push () if not self.txq then return end local li = self.input["input"] - assert(li, "intel1g:push: no input link") + assert(li, "intel_mp:push: no input link") while not link.empty(li) and self:ringnext(self.tdt) ~= self.tdh do local p = link.receive(li) @@ -617,7 +617,7 @@ end function Intel:pull () if not self.rxq then return end local lo = self.output["output"] - assert(lo, "intel1g: output link required") + assert(lo, "intel_mp:pull: output link required") local pkts = 0 while band(self.rxdesc[self.rdt].status, 0x01) == 1 and pkts < engine.pull_npackets do From 9615f89ea569d71b0ced8d67e8c98cf6fe0a4673 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 19 Jun 2017 15:05:01 +0200 Subject: [PATCH 064/109] Remove tabs from testrecv.lua --- src/apps/intel_mp/testrecv.lua | 62 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/apps/intel_mp/testrecv.lua b/src/apps/intel_mp/testrecv.lua index 137dbd83d6..2a44ac169b 100644 --- a/src/apps/intel_mp/testrecv.lua +++ b/src/apps/intel_mp/testrecv.lua @@ -28,37 +28,37 @@ function test(pciaddr, qno, vmdq, poolno, macaddr, vlan) end config.app(c, "sink", basic.Sink) if os.getenv("SNABB_RECV_EXPENSIVE") then - local filter = require("apps.packet_filter.pcap_filter") + local filter = require("apps.packet_filter.pcap_filter") - local count = 10 - config.link(c, "nic.output -> filter0.input") - for i=0,count do - local n = tostring(i) - local s = "filter"..n - config.app(c, s, filter.PcapFilter, { filter = [[ not dst host 10.2.29.1 and not dst host 10.2.50.1 ]]}) - end - for i=1,count do - local m = tostring(i-1) - local n = tostring(i) - local s = "filter"..m..".output -> filter"..n..".input" - config.link(c, s) - end - config.app(c, "sane", filter.PcapFilter, { filter = [[ src host 172.16.172.3 and dst net 1.2.0.0/16 and ip proto 0 ]] }) - config.link(c, "filter"..tostring(count)..".output -> sane.input") - config.link(c, "sane.output -> sink.input") + local count = 10 + config.link(c, "nic.output -> filter0.input") + for i=0,count do + local n = tostring(i) + local s = "filter"..n + config.app(c, s, filter.PcapFilter, { filter = [[ not dst host 10.2.29.1 and not dst host 10.2.50.1 ]]}) + end + for i=1,count do + local m = tostring(i-1) + local n = tostring(i) + local s = "filter"..m..".output -> filter"..n..".input" + config.link(c, s) + end + config.app(c, "sane", filter.PcapFilter, { filter = [[ src host 172.16.172.3 and dst net 1.2.0.0/16 and ip proto 0 ]] }) + config.link(c, "filter"..tostring(count)..".output -> sane.input") + config.link(c, "sane.output -> sink.input") else - config.link(c, "nic.output -> sink.input") + config.link(c, "nic.output -> sink.input") end engine.configure(c) local spinup = os.getenv("SNABB_RECV_SPINUP") if spinup then - engine.main({duration = spinup}) + engine.main({duration = spinup}) end local counters = { - Intel82599 = { "GPRC", "RXDGPC" }, - Intel1g = { "GPRC", "RPTHC" } + Intel82599 = { "GPRC", "RXDGPC" }, + Intel1g = { "GPRC", "RPTHC" } } local duration = os.getenv("SNABB_RECV_DURATION") or 2 @@ -67,24 +67,24 @@ function test(pciaddr, qno, vmdq, poolno, macaddr, vlan) local master = nic.master if master then - for _,v in pairs(counters[nic.driver]) do - before[v] = nic.r[v]() - end + for _,v in pairs(counters[nic.driver]) do + before[v] = nic.r[v]() + end end if os.getenv("SNABB_RECV_DEBUG") then - for _=1,duration do - engine.main({duration = 1}) - nic:debug() - end + for _=1,duration do + engine.main({duration = 1}) + nic:debug() + end else - engine.main({duration = duration}) + engine.main({duration = duration}) end if master then - for _,v in pairs(counters[nic.driver]) do + for _,v in pairs(counters[nic.driver]) do print(string.format("%s %d", v, tonumber(nic.r[v]() - before[v])/duration)) - end + end end main.exit(0) end From 7217501741dfa677874754e5bbee0a42cf1ad88c Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 19 Jun 2017 17:33:57 +0200 Subject: [PATCH 065/109] Remove redundant checks for link in push and pull methods --- src/apps/intel_mp/intel_mp.lua | 6 ++++-- src/apps/intel_mp/testrecv.lua | 2 +- src/apps/intel_mp/testvlan.snabb | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 4675a6bbb9..65ee5c4c51 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -580,7 +580,8 @@ end function Intel:push () if not self.txq then return end local li = self.input["input"] - assert(li, "intel_mp:push: no input link") + if li == nil then return end +-- assert(li, "intel_mp:push: no input link") while not link.empty(li) and self:ringnext(self.tdt) ~= self.tdh do local p = link.receive(li) @@ -617,7 +618,8 @@ end function Intel:pull () if not self.rxq then return end local lo = self.output["output"] - assert(lo, "intel_mp:pull: output link required") + if lo == nil then return end +-- assert(lo, "intel_mp:pull: output link required") local pkts = 0 while band(self.rxdesc[self.rdt].status, 0x01) == 1 and pkts < engine.pull_npackets do diff --git a/src/apps/intel_mp/testrecv.lua b/src/apps/intel_mp/testrecv.lua index 2a44ac169b..4c391dc412 100644 --- a/src/apps/intel_mp/testrecv.lua +++ b/src/apps/intel_mp/testrecv.lua @@ -83,7 +83,7 @@ function test(pciaddr, qno, vmdq, poolno, macaddr, vlan) if master then for _,v in pairs(counters[nic.driver]) do - print(string.format("%s %d", v, tonumber(nic.r[v]() - before[v])/duration)) + print(string.format("%s %d", v, tonumber(nic.r[v]() - before[v])/duration)) end end main.exit(0) diff --git a/src/apps/intel_mp/testvlan.snabb b/src/apps/intel_mp/testvlan.snabb index 33fe44531c..c041e20279 100755 --- a/src/apps/intel_mp/testvlan.snabb +++ b/src/apps/intel_mp/testvlan.snabb @@ -23,7 +23,8 @@ config.app(c, "pcap", pcap.PcapReader, pcapfile) config.app(c, "nic1", intel.Intel, {pciaddr=pciaddr1, txq = 0, - ndescriptors=2048, wait_for_link = true}) + ndescriptors=2048, + wait_for_link = true}) config.app(c, "nic2", intel.Intel, {pciaddr=pciaddr2, vmdq = true, From 50fcf690f52dfb4005b86674fc7bcf3a2cc3e9da Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 3 Jul 2017 14:43:08 +0200 Subject: [PATCH 066/109] Fix txdesc bug in intel_mp driver --- src/apps/intel_mp/intel_mp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 65ee5c4c51..5ae84ce139 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -760,7 +760,7 @@ function Intel:discard_unsent_packets () old_tdt = band(old_tdt - 1, self.ndesc - 1) packet.free(self.txqueue[old_tdt]) self.txdesc[old_tdt].address = -1 - self.txdesc[old_tdt].options = 0 + self.txdesc[old_tdt].flags = 0 end self.tdt = self.tdh end From f13aa500e545bf649858cdc1051db7874e4e48f4 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 7 Jul 2017 15:54:00 +0000 Subject: [PATCH 067/109] Make rx queue numbers relative to the pool number For example, rxq=0 for pool 1 means queue 4. --- src/apps/intel_mp/README.md | 2 ++ src/apps/intel_mp/intel_mp.lua | 9 +++++---- src/apps/intel_mp/test_10g_2q_blast_vlan.sh | 2 +- src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 2 +- src/apps/intel_mp/test_10g_vmdq_mirror.sh | 4 ++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index 13bf176a9d..f07c702509 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -28,6 +28,8 @@ specified but assumed to be broadly applicable. — Key **rxq** *Optional*. The receive queue to attach to, numbered from 0. The default is 0. +When VMDq is enabled, this number is used to index a queue (from 0 to 3) +for the selected pool. — Key **txq** diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 5ae84ce139..697ee42060 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -345,10 +345,11 @@ function Intel:new (conf) if self.vmdq then assert(byid.driver == Intel82599, "VMDq only supported on 82599") assert(self.macaddr, "MAC address must be set in VMDq mode") - assert(not self.rxq or - (self.rxq >= 4 * self.poolnum and - self.rxq <= 4 * self.poolnum + 3), - "Pool number and rxq do not match") + + -- for VMDq, make rxq relative to the pool number + assert(self.rxq >= 0 and self.rxq < 4, "rxqueue must be in 0..3") + self.rxq = self.rxq + 4 * self.poolnum + if self.driver == "Intel82599" then assert(self.poolnum < 32, "Pool overflow: Intel 82599 supports up to 32 VMDq pools") diff --git a/src/apps/intel_mp/test_10g_2q_blast_vlan.sh b/src/apps/intel_mp/test_10g_2q_blast_vlan.sh index 95ad68cd1a..45ff7e891c 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vlan.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vlan.sh @@ -7,7 +7,7 @@ BLAST=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 1 0 0 > results.0 & PID1=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 2 1 4 > results.1 +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" 2 1 0 > results.1 wait $PID1 kill -9 $BLAST diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index ca81f0fcbe..6e602df01c 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -7,7 +7,7 @@ BLAST=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" nil 0 0 > results.0 & PID1=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 1 4 > results.1 +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 1 0 > results.1 wait $PID1 kill -9 $BLAST diff --git a/src/apps/intel_mp/test_10g_vmdq_mirror.sh b/src/apps/intel_mp/test_10g_vmdq_mirror.sh index f0502d532c..8d02ec33b9 100755 --- a/src/apps/intel_mp/test_10g_vmdq_mirror.sh +++ b/src/apps/intel_mp/test_10g_vmdq_mirror.sh @@ -36,7 +36,7 @@ config.app(c, "nic1p1", intel.Intel, poolnum = 1, mirror = { pool = { 0 } }, macaddr = "12:34:56:78:9a:bc", - rxq = 4, + rxq = 0, rxcounter = 2, wait_for_link = true }) @@ -46,7 +46,7 @@ config.app(c, "nic1p2", intel.Intel, poolnum = 2, mirror = { pool = true }, macaddr = "aa:aa:aa:aa:aa:aa", - rxq = 8, + rxq = 0, rxcounter = 3, wait_for_link = true }) From 475cc80b5ba5c9e8a86b93fdf6b00a86a378ee47 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 14 Jul 2017 08:34:13 +0000 Subject: [PATCH 068/109] Disable MTU check that intel10g disables In the intel10g driver, a similar check is explicitly disabled because it doesn't work in some cases in which VLAN tagging is involved. See the comments in intel10g for details. --- src/apps/intel_mp/intel_mp.lua | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 697ee42060..e66eba18a9 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -586,16 +586,17 @@ function Intel:push () while not link.empty(li) and self:ringnext(self.tdt) ~= self.tdh do local p = link.receive(li) - if p.length > self.mtu then - packet.free(p) - counter.add(self.shm.txdrop) - else - self.txdesc[self.tdt].address = tophysical(p.data) - self.txdesc[self.tdt].flags = - bor(p.length, self.txdesc_flags, lshift(p.length+0ULL, 46)) - self.txqueue[self.tdt] = p - self.tdt = self:ringnext(self.tdt) - end + -- NB: see comment in intel10g for why this is commented out, + -- the rest of the loop body goes in an else branch + --if p.length > self.mtu then + -- packet.free(p) + -- counter.add(self.shm.txdrop) + --end + self.txdesc[self.tdt].address = tophysical(p.data) + self.txdesc[self.tdt].flags = + bor(p.length, self.txdesc_flags, lshift(p.length+0ULL, 46)) + self.txqueue[self.tdt] = p + self.tdt = self:ringnext(self.tdt) end -- Reclaim transmit contexts local cursor = self.tdh From 24ced235ab1076159f7fa3e1891108463d851941 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 14 Jul 2017 08:36:28 +0000 Subject: [PATCH 069/109] Make txq number relative to the pool number too Also fix the MTQC register value so that 32 pools with 4 queues are used, analagous with MRQC. --- src/apps/intel_mp/intel_mp.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index e66eba18a9..ed8540469e 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -346,9 +346,11 @@ function Intel:new (conf) assert(byid.driver == Intel82599, "VMDq only supported on 82599") assert(self.macaddr, "MAC address must be set in VMDq mode") - -- for VMDq, make rxq relative to the pool number + -- for VMDq, make rxq/txq relative to the pool number assert(self.rxq >= 0 and self.rxq < 4, "rxqueue must be in 0..3") self.rxq = self.rxq + 4 * self.poolnum + assert(self.txq >= 0 and self.txq < 4, "txqueue must be in 0..3") + self.txq = self.txq + 4 * self.poolnum if self.driver == "Intel82599" then assert(self.poolnum < 32, @@ -1365,8 +1367,8 @@ function Intel82599:vmdq_enable () -- disable RSC (7.11) self.r.RFCTL:set(bits { RSC_Dis=5 }) - -- 128 Tx Queues, 64 VMs (4.6.11.3.3) - self.r.MTQC(bits { VT_Ena=1, Num_TC_OR_Q=2 }) + -- 128 Tx Queues, 32 VMs (4.6.11.3.3) + self.r.MTQC(bits { VT_Ena=1, Num_TC_OR_Q=3 }) -- enable virtualization, replication enabled, disable default pool self.r.PFVTCTL(bits { VT_Ena=0, Rpl_En=30, DisDefPool=29 }) From 20bc39c36e6eb997eb64fba865d5a7ea77c534f5 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 18 Jul 2017 00:02:37 +0000 Subject: [PATCH 070/109] Adjust the max Rx/Tx queue numbers in VMDq mode Also adjust pool numbers in a test to exercise the queue number check --- src/apps/intel_mp/intel_mp.lua | 3 +++ src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index ed8540469e..daba004551 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -352,6 +352,9 @@ function Intel:new (conf) assert(self.txq >= 0 and self.txq < 4, "txqueue must be in 0..3") self.txq = self.txq + 4 * self.poolnum + -- max queue number is different in VMDq mode + self.max_q = 128 + if self.driver == "Intel82599" then assert(self.poolnum < 32, "Pool overflow: Intel 82599 supports up to 32 VMDq pools") diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index 6e602df01c..48825548aa 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -7,7 +7,7 @@ BLAST=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" nil 0 0 > results.0 & PID1=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 1 0 > results.1 +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 31 3 > results.1 wait $PID1 kill -9 $BLAST From ae707ce8f8e4c46fc5095ad9e9d6e1d8e5982e62 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Tue, 18 Jul 2017 12:16:56 +0200 Subject: [PATCH 071/109] Allow 64 pools instead of 32, and 2 queues per pool instead of 4 --- src/apps/intel_mp/intel_mp.lua | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index daba004551..99cdc434f4 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -347,17 +347,17 @@ function Intel:new (conf) assert(self.macaddr, "MAC address must be set in VMDq mode") -- for VMDq, make rxq/txq relative to the pool number - assert(self.rxq >= 0 and self.rxq < 4, "rxqueue must be in 0..3") - self.rxq = self.rxq + 4 * self.poolnum - assert(self.txq >= 0 and self.txq < 4, "txqueue must be in 0..3") - self.txq = self.txq + 4 * self.poolnum + assert(self.rxq >= 0 and self.rxq < 2, "rxqueue must be in 0..1") + self.rxq = self.rxq + 2 * self.poolnum + assert(self.txq >= 0 and self.txq < 1, "txqueue must be in 0..1") + self.txq = self.txq + 2 * self.poolnum -- max queue number is different in VMDq mode self.max_q = 128 if self.driver == "Intel82599" then - assert(self.poolnum < 32, - "Pool overflow: Intel 82599 supports up to 32 VMDq pools") + assert(self.poolnum < 64, + "Pool overflow: Intel 82599 supports up to 64 VMDq pools") elseif self.driver == "Intel1g" then assert(self.poolnum < 8, "Pool overflow: Intel i350 supports up to 8 VMDq pools") @@ -460,8 +460,8 @@ function Intel:init_rx_q () -- VMDq pool state (4.6.10.1.4) if self.vmdq then - -- packet splitting none, enable 4 RSS queues per pool - self.r.PSRTYPE[self.poolnum](bits { RQPL=30 }) + -- packet splitting none, enable 2 RSS queues per pool + self.r.PSRTYPE[self.poolnum](bits { RQPL=29 }) -- multicast promiscuous, broadcast accept, accept untagged pkts self.r.PFVML2FLT[self.poolnum]:set(bits { MPE=28, BAM=27, AUPE=24 }) end @@ -543,7 +543,7 @@ function Intel:init_tx_q () -- 4.5.10 -- set baseline value for credit refill for tx bandwidth algorithm self.r.RTTDT1C(0x80) -- enables packet Tx for this VF's pool - self.r.PFVFTE[math.floor(self.poolnum/33)]:set(bits{VFTE=self.poolnum%32}) + self.r.PFVFTE[math.floor(self.poolnum/32)]:set(bits{VFTE=self.poolnum%32}) end if self.r.DMATXCTL then @@ -676,7 +676,7 @@ function Intel:rss_key () end end --- Set RSS redirection table, which has 32 * 4 entries which contain +-- Set RSS redirection table, which has 64 * 2 entries which contain -- RSS indices, the lower 4 bits (or fewer) of which are used to -- select an RSS queue. -- @@ -685,8 +685,8 @@ function Intel:rss_tab (newtab) local current = {} local pos = 0 - for i=0,31,1 do - for j=0,3,1 do + for i=0,63,1 do + for j=0,1,1 do current[self.r.RETA[i]:byte(j)] = 1 if newtab ~= nil then local new = newtab[pos%#newtab+1] @@ -936,10 +936,10 @@ function Intel:set_mirror () local bm0 = self.r.PFMRVM[mirror_ndx]() local bm1 = self.r.PFMRVM[mirror_ndx+4]() for _, pool in ipairs(want_mirror.pool) do - if pool <= 32 then + if pool <= 64 then bm0 = bor(lshift(1, pool), bm0) else - bm1 = bor(lshift(1, pool-32), bm1) + bm1 = bor(lshift(1, pool-64), bm1) end end self.r.PFMRVM[mirror_ndx](bm0) @@ -1189,7 +1189,11 @@ Intel82599.offsets = { } Intel82599.max_mac_addr = 127 Intel82599.max_vlan = 64 -Intel82599.mrqc_bits = 0xA + +-- 1010 -> 32 pools, 4 RSS queues each +-- 1011 -> 64 pools, 2 RSS queues each +Intel82599.mrqc_bits = 0xB + function Intel82599:link_status () local mask = lshift(1, 30) return bit.band(self.r.LINKS(), mask) == mask @@ -1363,15 +1367,14 @@ function Intel82599:vmdq_enable () -- must be set prior to setting MTQC (7.2.1.2.1) self.r.RTTDCS:set(bits { ARBDIS=6 }) - -- 1010 -> 32 pools, 4 RSS queues each self.r.MRQC:bits(0, 4, self.mrqc_bits) -- TODO: not sure this is needed, but it's in intel10g -- disable RSC (7.11) self.r.RFCTL:set(bits { RSC_Dis=5 }) - -- 128 Tx Queues, 32 VMs (4.6.11.3.3) - self.r.MTQC(bits { VT_Ena=1, Num_TC_OR_Q=3 }) + -- 128 Tx Queues, 64 VMs (4.6.11.3.3 and 8.2.3.9.15) + self.r.MTQC(bits { VT_Ena=1, Num_TC_OR_Q=2 }) -- enable virtualization, replication enabled, disable default pool self.r.PFVTCTL(bits { VT_Ena=0, Rpl_En=30, DisDefPool=29 }) From 0574ad6b343d5b59fcbc941ba08e28200b6df24a Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Tue, 18 Jul 2017 12:39:25 +0200 Subject: [PATCH 072/109] Undo wrong change --- src/apps/intel_mp/intel_mp.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 99cdc434f4..f8f979548f 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -685,8 +685,8 @@ function Intel:rss_tab (newtab) local current = {} local pos = 0 - for i=0,63,1 do - for j=0,1,1 do + for i=0,31,1 do + for j=0,3,1 do current[self.r.RETA[i]:byte(j)] = 1 if newtab ~= nil then local new = newtab[pos%#newtab+1] From 5a6177f61f04d30c1f321c50410c3d3106f72ca8 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Tue, 18 Jul 2017 13:15:18 +0200 Subject: [PATCH 073/109] Fix intel_mp test --- src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index 48825548aa..31baaed21e 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -7,7 +7,7 @@ BLAST=$! SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" nil 0 0 > results.0 & PID1=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 31 3 > results.1 +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil 63 1 > results.1 wait $PID1 kill -9 $BLAST From fd6e310a8503fe263934a41862f5b3d685a67a54 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Tue, 18 Jul 2017 15:20:40 +0200 Subject: [PATCH 074/109] Remove duplicate require line --- src/apps/intel_mp/intel_mp.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index f8f979548f..660db7da4d 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -25,7 +25,6 @@ local register = require("lib.hardware.register") local counter = require("core.counter") local macaddress = require("lib.macaddress") local shm = require("core.shm") -local counter = require("core.counter") -- It's not clear what address to use for EEMNGCTL_i210 DPDK PMD / linux e1000 -- both use 1010 but the docs say 12030 From 0c23646673814a88b6e3ad9500aeafb8f91bd219 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 24 Jul 2017 23:05:22 +0000 Subject: [PATCH 075/109] Fix VLAN tag setting after a NIC app is restarted It's not enough to scan and find the first empty spot or a matching VLAN in one pass, since depending on the order that apps are shut down an earlier space may free up. Duplicate VLAN entries in PFVLVF do not work, so we have to make sure VLANs are unique. --- src/apps/intel_mp/intel_mp.lua | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 660db7da4d..b81901b819 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -847,7 +847,7 @@ end function Intel:add_receive_VLAN (vlan) assert(vlan>=0 and vlan<4096, "bad VLAN number") - local vlan_index + local vlan_index, first_empty -- scan to see if the VLAN is already recorded or find the -- first free VLAN index @@ -855,18 +855,21 @@ function Intel:add_receive_VLAN (vlan) local valid = self.r.PFVLVF[idx]:bits(31, 1) if valid == 0 then + if not first_empty then + first_empty = idx + end + elseif self.r.PFVLVF[idx]:bits(0, 11) == vlan then vlan_index = idx - self.r.VFTA[math.floor(vlan/32)]:set(bits{Ena=vlan%32}) - self.r.PFVLVF[vlan_index](bits({Vl_En=31},vlan)) break - else - if self.r.PFVLVF[idx]:bits(0, 11) == vlan then - vlan_index = idx - break - end end end + if not vlan_index and first_empty then + vlan_index = first_empty + self.r.VFTA[math.floor(vlan/32)]:set(bits{Ena=vlan%32}) + self.r.PFVLVF[vlan_index](bits({Vl_En=31},vlan)) + end + assert(vlan_index, "Max number of VLAN IDs reached") self.r.PFVLVFB[2*vlan_index + math.floor(self.poolnum/32)] From 31e625e0682ef932b92c1578a9010bade9ac38c4 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Wed, 26 Jul 2017 11:22:58 +0200 Subject: [PATCH 076/109] Add the poll-follower-for-channel fix --- src/apps/config/leader.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/apps/config/leader.lua b/src/apps/config/leader.lua index 6643e561ff..2d33d88da0 100644 --- a/src/apps/config/leader.lua +++ b/src/apps/config/leader.lua @@ -680,9 +680,8 @@ function Leader:send_messages_to_followers() for _,follower in ipairs(self.followers) do if not follower.channel then local name = '/'..tostring(follower.pid)..'/config-follower-channel' - -- local success, channel = pcall(channel.open, name) - --if success then follower.channel = channel end - follower.channel = channel.open(name) + local success, channel = pcall(channel.open, name) + if success then follower.channel = channel end end local channel = follower.channel if channel then From a58fa28d2690a52794577de0623ff4fc34a02d7e Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Wed, 26 Jul 2017 16:05:52 +0200 Subject: [PATCH 077/109] Typo fix to make CI run again --- src/apps/intel_mp/intel_mp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index b81901b819..f85e908e88 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -303,7 +303,7 @@ byPciID = { } -- The `driver' variable is used as a reference to the driver class in --- order to interchangably use NIC drivers. +-- order to interchangeably use NIC drivers. driver = Intel function Intel:new (conf) From 299a5a8692f0803901c19352f96c0caa8338da49 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Wed, 26 Jul 2017 17:47:52 +0200 Subject: [PATCH 078/109] Add config defaults for txq and rxq --- src/apps/intel_mp/intel_mp.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index f85e908e88..178d6debb7 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -279,8 +279,8 @@ Intel = { txcounter = {}, rate_limit = {default=0}, priority = {default=1.0}, - txq = {}, - rxq = {}, + txq = {default=0}, + rxq = {default=0}, mtu = {default=9014}, linkup_wait = {default=120}, linkup_wait_recheck = {default=0.1}, From eaab2efb41f8de9eb2e20630bc3220568927aabb Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 2 Aug 2017 00:41:31 -0700 Subject: [PATCH 079/109] Shuffle code and refactor check_vmdq method --- src/apps/intel_mp/intel_mp.lua | 75 ++++++++++++++++------------------ 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 178d6debb7..9dadc4b178 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -340,32 +340,6 @@ function Intel:new (conf) self.max_q = byid.max_q - -- VMDq checks - if self.vmdq then - assert(byid.driver == Intel82599, "VMDq only supported on 82599") - assert(self.macaddr, "MAC address must be set in VMDq mode") - - -- for VMDq, make rxq/txq relative to the pool number - assert(self.rxq >= 0 and self.rxq < 2, "rxqueue must be in 0..1") - self.rxq = self.rxq + 2 * self.poolnum - assert(self.txq >= 0 and self.txq < 1, "txqueue must be in 0..1") - self.txq = self.txq + 2 * self.poolnum - - -- max queue number is different in VMDq mode - self.max_q = 128 - - if self.driver == "Intel82599" then - assert(self.poolnum < 64, - "Pool overflow: Intel 82599 supports up to 64 VMDq pools") - elseif self.driver == "Intel1g" then - assert(self.poolnum < 8, - "Pool overflow: Intel i350 supports up to 8 VMDq pools") - end - else - assert(not self.macaddr, "VMDq must be set to use MAC address") - assert(not self.mirror, "VMDq must be set to specify mirroring rules") - end - -- Setup device access self.base, self.fd = pci.map_pci_memory_unlocked(self.pciaddress, 0) self.master = self.fd:flock("ex, nb") @@ -374,9 +348,7 @@ function Intel:new (conf) self:init() self.fd:flock("sh") - if self.vmdq then - self:check_vmdq() - end + self:check_vmdq() self:init_tx_q() self:init_rx_q() self:set_MAC() @@ -1159,12 +1131,11 @@ end function Intel1g:set_rxstats () return end function Intel1g:set_txstats () return end -function Intel1g:check_vmdq () - error("unimplemented") -end +function Intel1g:check_vmdq () return end function Intel1g:vmdq_enable () error("unimplemented") end +function Intel1g:select_pool () return end function Intel1g:enable_MAC_for_pool(mac_index) self.r.RAH[mac_index]:set(bits { Ena = 18 + self.poolnum }) @@ -1348,17 +1319,43 @@ function Intel82599:init () self:unlock_sw_sem() end --- helper method for checking that the main process used the same --- VMDq setting if this is a worker process (noop on main) +-- Implements various status checks related to VMDq configuration. +-- Also checks that the main process used the same VMDq setting if +-- this is a worker process function Intel82599:check_vmdq () - if not self.master then - if self.vmdq then - assert(self.r.MRQC:bits(0, 4) == self.mrqc_bits, - "VMDq not set by the main process for this NIC") - else + if not self.vmdq then + assert(not self.macaddr, "VMDq must be set to use MAC address") + assert(not self.mirror, "VMDq must be set to specify mirroring rules") + + if not self.master then assert(self.r.MRQC:bits(0, 4) ~= self.mrqc_bits, "VMDq was set by the main process for this NIC") end + else + assert(self.driver == "Intel82599", "VMDq only supported on 82599") + assert(self.macaddr, "MAC address must be set in VMDq mode") + + -- for VMDq, make rxq/txq relative to the pool number + assert(self.rxq >= 0 and self.rxq < 2, "rxqueue must be in 0..1") + self.rxq = self.rxq + 2 * self.poolnum + assert(self.txq >= 0 and self.txq < 1, "txqueue must be in 0..1") + self.txq = self.txq + 2 * self.poolnum + + -- max queue number is different in VMDq mode + self.max_q = 128 + + if self.driver == "Intel82599" then + assert(self.poolnum < 64, + "Pool overflow: Intel 82599 supports up to 64 VMDq pools") + elseif self.driver == "Intel1g" then + assert(self.poolnum < 8, + "Pool overflow: Intel i350 supports up to 8 VMDq pools") + end + + if not self.master then + assert(self.r.MRQC:bits(0, 4) == self.mrqc_bits, + "VMDq not set by the main process for this NIC") + end end end From 98cecb6390756074c8590e86ee8fb39e8d57fa2f Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 2 Aug 2017 00:50:17 -0700 Subject: [PATCH 080/109] Automatically select available pools in VMDq mode We coordinate between concurrent processes using the same NIC by locking files corresponding to pools in the shm dir --- src/apps/intel_mp/intel_mp.lua | 58 ++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 9dadc4b178..437b2190d2 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -25,6 +25,7 @@ local register = require("lib.hardware.register") local counter = require("core.counter") local macaddress = require("lib.macaddress") local shm = require("core.shm") +local S = require("syscall") -- It's not clear what address to use for EEMNGCTL_i210 DPDK PMD / linux e1000 -- both use 1010 but the docs say 12030 @@ -272,7 +273,7 @@ Intel = { ndescriptors = {default=2048}, vmdq = {default=false}, macaddr = {}, - poolnum = {default=0}, + poolnum = {}, vlan = {}, mirror = {}, rxcounter = {}, @@ -344,6 +345,9 @@ function Intel:new (conf) self.base, self.fd = pci.map_pci_memory_unlocked(self.pciaddress, 0) self.master = self.fd:flock("ex, nb") + -- this needs to happen before register loading for rxq/txq + self:select_pool() + self:load_registers(byid.registers) self:init() @@ -1335,15 +1339,6 @@ function Intel82599:check_vmdq () assert(self.driver == "Intel82599", "VMDq only supported on 82599") assert(self.macaddr, "MAC address must be set in VMDq mode") - -- for VMDq, make rxq/txq relative to the pool number - assert(self.rxq >= 0 and self.rxq < 2, "rxqueue must be in 0..1") - self.rxq = self.rxq + 2 * self.poolnum - assert(self.txq >= 0 and self.txq < 1, "txqueue must be in 0..1") - self.txq = self.txq + 2 * self.poolnum - - -- max queue number is different in VMDq mode - self.max_q = 128 - if self.driver == "Intel82599" then assert(self.poolnum < 64, "Pool overflow: Intel 82599 supports up to 64 VMDq pools") @@ -1423,6 +1418,49 @@ function Intel82599:vmdq_enable () self.r.RTTDCS:clr(bits { ARBDIS=6 }) end +-- In VMDq mode, selects an available pool if one isn't provided by the user. +local pooldir = "intel-mp-pools" +function Intel82599:select_pool() + if not self.vmdq then return end + + -- if the poolnum was set manually in the config, just use that + if not self.poolnum then + local available_pool + + -- we use some (empty) files in the shm directory to track what pools are + -- claimed (pick the first poolnum file that this process can obtain an + -- exclusive lock on) + if not shm.exists(pooldir) then + shm.mkdir(pooldir .. "/" .. self.pciaddress) + end + + for poolnum = 0, 63 do + local path = shm.root.."/"..pooldir.."/"..self.pciaddress.."/"..poolnum + local fd = S.open(path, "creat, rdwr") + if fd:flock("nb, ex") then + available_pool = poolnum + break + end + fd:close() + end + + assert(available_pool, "No free VMDq pools are available") + self.poolnum = available_pool + end + + -- Once we know the pool number, figure out txq and rxq numbers. This + -- needs to be done prior to loading registers. + -- + -- for VMDq, make rxq/txq relative to the pool number + assert(self.rxq >= 0 and self.rxq < 2, "rxqueue must be in 0..1") + self.rxq = self.rxq + 2 * self.poolnum + assert(self.txq >= 0 and self.txq < 1, "txqueue must be in 0..1") + self.txq = self.txq + 2 * self.poolnum + + -- max queue number is different in VMDq mode + self.max_q = 128 +end + function Intel82599:enable_MAC_for_pool (mac_index) self.r.MPSAR[2*mac_index + math.floor(self.poolnum/32)] :set(bits{Ena=self.poolnum%32}) From 6ea7eeb90f3758896111c3494801b197e31fa9c5 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 3 Aug 2017 18:20:03 +0000 Subject: [PATCH 081/109] Add a test where VMDq pools are auto selected --- .../intel_mp/test_10g_2q_blast_vmdq_auto.sh | 20 +++++++++++++++++++ src/apps/intel_mp/testvmdqrecv.snabb | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100755 src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh new file mode 100755 index 0000000000..ce3a44ae8b --- /dev/null +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Test VMDq with automatic pool selection + +SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source2.pcap & +BLAST=$! + +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "90:72:82:78:c9:7a" nil nil 0 > results.0 & +PID1=$! +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 "12:34:56:78:9a:bc" nil nil 1 > results.1 + +wait $PID1 +kill -9 $BLAST + +[[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ +# both queues should see packets +[[ `cat results.0 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] &&\ +[[ `cat results.1 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] + +exit $? diff --git a/src/apps/intel_mp/testvmdqrecv.snabb b/src/apps/intel_mp/testvmdqrecv.snabb index 474bd76502..4ca824e301 100755 --- a/src/apps/intel_mp/testvmdqrecv.snabb +++ b/src/apps/intel_mp/testvmdqrecv.snabb @@ -4,7 +4,7 @@ assert(#args == 5, "testvmdqrecv.snabb pciaddr macaddr vlan poolno qno") local pciaddr = table.remove(args, 1) local macaddr = table.remove(args, 1) local vlan = load("return " .. table.remove(args, 1))() -local poolno = tonumber(table.remove(args,1)) +local poolno = load("return " .. table.remove(args, 1))() local qno = tonumber(table.remove(args,1)) local test = require("apps.intel_mp.testrecv").test From 15e486548a04d6f041d99eef87b3162d47f6051d Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 3 Aug 2017 18:21:09 +0000 Subject: [PATCH 082/109] Revise intel_mp poolnum docs --- src/apps/intel_mp/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index f07c702509..f125656e03 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -49,8 +49,8 @@ specified. — Key **poolnum** -*Optional*. The VMDq pool to associated with, numbered from 0. The default -is 0. +*Optional*. The VMDq pool to associate with, numbered from 0. The default +is to select a pool number automatically. — Key **macaddr** From 9007754644f1bdd02df3e43713dbf92f5ac6f880 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 3 Aug 2017 19:47:37 +0000 Subject: [PATCH 083/109] Add a fine-grained test for intel_mp auto pools --- src/apps/intel_mp/test_10g_vmdq_pool_sel.sh | 69 +++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 src/apps/intel_mp/test_10g_vmdq_pool_sel.sh diff --git a/src/apps/intel_mp/test_10g_vmdq_pool_sel.sh b/src/apps/intel_mp/test_10g_vmdq_pool_sel.sh new file mode 100755 index 0000000000..c43569b105 --- /dev/null +++ b/src/apps/intel_mp/test_10g_vmdq_pool_sel.sh @@ -0,0 +1,69 @@ +#!../../snabb snsh + +-- Snabb test script for checking that pool selection is working +-- as expected across app shutdowns + +local basic_apps = require("apps.basic.basic_apps") +local intel = require("apps.intel_mp.intel_mp") +local pcap = require("apps.pcap.pcap") +local lib = require("core.lib") + +local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") +local pciaddr1 = lib.getenv("SNABB_PCI_INTEL1") + +local c = config.new() + +-- first add two apps in order & observe poolnums +config.app(c, "nicp0", intel.Intel, + { pciaddr = pciaddr1, + vmdq = true, + rxq = 0, txq = 0, + macaddr = "90:72:82:78:c9:7a" }) +config.app(c, "source", basic_apps.Source) + +config.link(c, "source.out0 -> nicp0.input") + +engine.configure(c) +engine.main({ duration = 0.1 }) + +assert(engine.app_table.nicp0.poolnum == 0, "wrong poolnum for nicp0") + +config.app(c, "nicp1", intel.Intel, + { pciaddr = pciaddr1, + vmdq = true, + rxq = 0, txq = 0, + macaddr = "90:72:82:78:c9:7b" }) +config.link(c, "source.out1 -> nicp1.input") + +engine.configure(c) +engine.main({ duration = 0.1 }) + +assert(engine.app_table.nicp1.poolnum == 1, "wrong poolnum for nicp1") + +-- now try removing the first app, then add a new one to use pool 0 +local c = config.new() + +config.app(c, "nicp1", intel.Intel, + { pciaddr = pciaddr1, + vmdq = true, + rxq = 0, txq = 0, + macaddr = "90:72:82:78:c9:7b" }) +config.app(c, "source", basic_apps.Source) +config.link(c, "source.out1 -> nicp1.input") + +engine.configure(c) +engine.main({ duration = 0.1 }) + +config.app(c, "nicp2", intel.Intel, + { pciaddr = pciaddr1, + vmdq = true, + rxq = 0, txq = 0, + macaddr = "90:72:82:78:c9:7b" }) +config.link(c, "source.out2 -> nicp2.input") + +engine.configure(c) +engine.main({ duration = 0.1 }) + +assert(engine.app_table.nicp1.poolnum == 1, "wrong poolnum for nicp1") +-- pool 0 should be freed by nicp0 being stopped +assert(engine.app_table.nicp2.poolnum == 0, "wrong poolnum for nicp2") From ddf3e26296aeab959aa8eb9b2e3c9054f1741595 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 3 Aug 2017 19:49:25 +0000 Subject: [PATCH 084/109] Fix pool lock cleanup for intel_mp --- src/apps/intel_mp/intel_mp.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 437b2190d2..8a1382dd16 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -720,6 +720,13 @@ function Intel:stop () self:unset_MAC() self:unset_VLAN() self:unset_mirror() + if self.poolfd then + -- we need to explicitly unlock this in case multiple instances + -- are running on the same process and we can't rely on process + -- termination to free the lock + self.poolfd:flock("un") + self.poolfd:close() + end end self:unset_tx_rate() if self.fd:flock("nb, ex") then @@ -1436,12 +1443,11 @@ function Intel82599:select_pool() for poolnum = 0, 63 do local path = shm.root.."/"..pooldir.."/"..self.pciaddress.."/"..poolnum - local fd = S.open(path, "creat, rdwr") - if fd:flock("nb, ex") then + self.poolfd = S.open(path, "creat, rdwr") + if self.poolfd:flock("nb, ex") then available_pool = poolnum break end - fd:close() end assert(available_pool, "No free VMDq pools are available") From 5596eabddb5656ae18a407f2871891a075fd859c Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 4 Aug 2017 23:36:10 +0000 Subject: [PATCH 085/109] Minor fixes in intel_mp vmdq code --- src/apps/intel_mp/intel_mp.lua | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 8a1382dd16..69163dba83 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1345,14 +1345,7 @@ function Intel82599:check_vmdq () else assert(self.driver == "Intel82599", "VMDq only supported on 82599") assert(self.macaddr, "MAC address must be set in VMDq mode") - - if self.driver == "Intel82599" then - assert(self.poolnum < 64, - "Pool overflow: Intel 82599 supports up to 64 VMDq pools") - elseif self.driver == "Intel1g" then - assert(self.poolnum < 8, - "Pool overflow: Intel i350 supports up to 8 VMDq pools") - end + assert(self.poolnum < 64, "Pool overflow: Intel 82599 supports up to 64 VMDq pools") if not self.master then assert(self.r.MRQC:bits(0, 4) == self.mrqc_bits, @@ -1460,7 +1453,7 @@ function Intel82599:select_pool() -- for VMDq, make rxq/txq relative to the pool number assert(self.rxq >= 0 and self.rxq < 2, "rxqueue must be in 0..1") self.rxq = self.rxq + 2 * self.poolnum - assert(self.txq >= 0 and self.txq < 1, "txqueue must be in 0..1") + assert(self.txq >= 0 and self.txq < 2, "txqueue must be in 0..1") self.txq = self.txq + 2 * self.poolnum -- max queue number is different in VMDq mode From e9b81537572ab2cd08e7606983654cf076dea47d Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 4 Aug 2017 23:37:23 +0000 Subject: [PATCH 086/109] Move comment to avoid conflict with newline --- src/apps/intel_mp/test_10g_2q_blast_vmdq.sh | 2 +- src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh index 31baaed21e..f15f88886d 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq.sh @@ -12,8 +12,8 @@ SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 wait $PID1 kill -9 $BLAST -[[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ # both queues should see packets +[[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ [[ `cat results.0 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] &&\ [[ `cat results.1 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] diff --git a/src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh b/src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh index ce3a44ae8b..11b17bd1a8 100755 --- a/src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh +++ b/src/apps/intel_mp/test_10g_2q_blast_vmdq_auto.sh @@ -12,8 +12,8 @@ SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testvmdqrecv.snabb $SNABB_PCI_INTEL0 wait $PID1 kill -9 $BLAST -[[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ # both queues should see packets +[[ `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 ]] &&\ [[ `cat results.0 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] &&\ [[ `cat results.1 | grep -m 1 fpb | awk '{print $9}'` -gt 0 ]] From 19e6434df646f7ce9cba7f9b5425027461add3f3 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 4 Aug 2017 23:40:19 +0000 Subject: [PATCH 087/109] Rename some test files .sh -> .snabb --- .../{test_10g_rate_limit.sh => test_10g_rate_limit.snabb} | 0 .../intel_mp/{test_10g_txq_stop.sh => test_10g_txq_stop.snabb} | 0 .../{test_10g_vmdq_mirror.sh => test_10g_vmdq_mirror.snabb} | 0 .../{test_10g_vmdq_pool_sel.sh => test_10g_vmdq_pool_sel.snabb} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/apps/intel_mp/{test_10g_rate_limit.sh => test_10g_rate_limit.snabb} (100%) rename src/apps/intel_mp/{test_10g_txq_stop.sh => test_10g_txq_stop.snabb} (100%) rename src/apps/intel_mp/{test_10g_vmdq_mirror.sh => test_10g_vmdq_mirror.snabb} (100%) rename src/apps/intel_mp/{test_10g_vmdq_pool_sel.sh => test_10g_vmdq_pool_sel.snabb} (100%) diff --git a/src/apps/intel_mp/test_10g_rate_limit.sh b/src/apps/intel_mp/test_10g_rate_limit.snabb similarity index 100% rename from src/apps/intel_mp/test_10g_rate_limit.sh rename to src/apps/intel_mp/test_10g_rate_limit.snabb diff --git a/src/apps/intel_mp/test_10g_txq_stop.sh b/src/apps/intel_mp/test_10g_txq_stop.snabb similarity index 100% rename from src/apps/intel_mp/test_10g_txq_stop.sh rename to src/apps/intel_mp/test_10g_txq_stop.snabb diff --git a/src/apps/intel_mp/test_10g_vmdq_mirror.sh b/src/apps/intel_mp/test_10g_vmdq_mirror.snabb similarity index 100% rename from src/apps/intel_mp/test_10g_vmdq_mirror.sh rename to src/apps/intel_mp/test_10g_vmdq_mirror.snabb diff --git a/src/apps/intel_mp/test_10g_vmdq_pool_sel.sh b/src/apps/intel_mp/test_10g_vmdq_pool_sel.snabb similarity index 100% rename from src/apps/intel_mp/test_10g_vmdq_pool_sel.sh rename to src/apps/intel_mp/test_10g_vmdq_pool_sel.snabb From c00adf8c656251b46567da0f49082c70896f2701 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 8 Aug 2017 21:27:56 +0000 Subject: [PATCH 088/109] Minor improvements to pool selection code Adds comments and simplifies the code slightly --- src/apps/intel_mp/intel_mp.lua | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 69163dba83..43ffe26022 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1419,6 +1419,10 @@ function Intel82599:vmdq_enable () end -- In VMDq mode, selects an available pool if one isn't provided by the user. +-- +-- This method runs before registers are loaded, because the rxq/txq registers +-- depend on the pool number prior to loading. As a result, we can't use the +-- lock_sw_sem() method to protect the critical section and use flock() instead. local pooldir = "intel-mp-pools" function Intel82599:select_pool() if not self.vmdq then return end @@ -1427,16 +1431,14 @@ function Intel82599:select_pool() if not self.poolnum then local available_pool - -- we use some (empty) files in the shm directory to track what pools are - -- claimed (pick the first poolnum file that this process can obtain an - -- exclusive lock on) - if not shm.exists(pooldir) then - shm.mkdir(pooldir .. "/" .. self.pciaddress) - end - + -- We use some shared memory to track which pool numbers are claimed + -- using flock() to avoid conflicts. The contents of the memory doesn't + -- matter since we only care about the lock state. for poolnum = 0, 63 do - local path = shm.root.."/"..pooldir.."/"..self.pciaddress.."/"..poolnum - self.poolfd = S.open(path, "creat, rdwr") + local path = "/"..pooldir.."/"..self.pciaddress.."/"..poolnum + shm.create(path, "uint8_t") + self.poolfd = S.open(shm.root .. path, "rdwr") + if self.poolfd:flock("nb, ex") then available_pool = poolnum break From ee0ce1d87ad27e236f1a26a729b403d034317984 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 9 Aug 2017 23:32:45 +0000 Subject: [PATCH 089/109] Protect against race conditions in VMDq config This fixes race conditions in which two intel_mp apps could end up using the same VLAN or MAC index (a TOCTOU bug). It was difficult to trigger in a realistic situation, but was possible to trigger when some delays were added in the code. --- src/apps/intel_mp/intel_mp.lua | 10 +++- src/apps/intel_mp/test_10g_vmdq_race.snabb | 68 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100755 src/apps/intel_mp/test_10g_vmdq_race.snabb diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 43ffe26022..73ea61808a 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -791,6 +791,10 @@ function Intel:add_receive_MAC (mac) -- scan to see if the MAC is already recorded or find the -- first free MAC index + -- + -- the lock protects the critical section so that driver apps on + -- separate processes do not use conflicting registers + self:lock_sw_sem() for idx=1, self.max_mac_addr do local valid = self.r.RAH[idx]:bits(31, 1) @@ -807,6 +811,7 @@ function Intel:add_receive_MAC (mac) end end end + self:unlock_sw_sem() assert(mac_index, "Max number of MAC addresses reached") @@ -832,8 +837,8 @@ function Intel:add_receive_VLAN (vlan) assert(vlan>=0 and vlan<4096, "bad VLAN number") local vlan_index, first_empty - -- scan to see if the VLAN is already recorded or find the - -- first free VLAN index + -- works the same as add_receive_MAC + self:lock_sw_sem() for idx=0, self.max_vlan-1 do local valid = self.r.PFVLVF[idx]:bits(31, 1) @@ -846,6 +851,7 @@ function Intel:add_receive_VLAN (vlan) break end end + self:unlock_sw_sem() if not vlan_index and first_empty then vlan_index = first_empty diff --git a/src/apps/intel_mp/test_10g_vmdq_race.snabb b/src/apps/intel_mp/test_10g_vmdq_race.snabb new file mode 100755 index 0000000000..32cc52e371 --- /dev/null +++ b/src/apps/intel_mp/test_10g_vmdq_race.snabb @@ -0,0 +1,68 @@ +#!../../snabb snsh + +-- Snabb test script that tests against race conditions in setting +-- VMDq parameters like MAC and VLAN + +local C = require("ffi").C +local intel = require("apps.intel_mp.intel_mp") +local lib = require("core.lib") +local worker = require("core.worker") + +local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") + +-- launch two worker processes each using VMDq with MAC addresses +-- and different VLAN tags and ensure that the chosen indices for +-- MAC & VLAN do not overlap. +-- +-- It's difficult for this test to fail unless delays are introduced +-- to deliberately trigger race conditions in the driver code (and +-- the locks disabled). +worker.start("worker0", [[ + local intel = require("apps.intel_mp.intel_mp") + local lib = require("core.lib") + local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") + local c = config.new() + config.app(c, "nic0", intel.Intel, + { pciaddr = pciaddr0, + vmdq = true, + poolnum = 0, + rxq = 0, txq = 0, + vlan = 0, + macaddr = "00:11:22:33:44:55" }) + engine.configure(c) + engine.main({ duration = 1 }) + assert(engine.app_table.nic0.r.RAH[1]:bits(31, 1) == 1) + assert(engine.app_table.nic0.r.PFVLVF[0]:bits(31, 1) == 1) +]]) + +worker.start("worker1", [[ + local intel = require("apps.intel_mp.intel_mp") + local lib = require("core.lib") + local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") + local c = config.new() + config.app(c, "nic1", intel.Intel, + { pciaddr = pciaddr0, + vmdq = true, + poolnum = 1, + rxq = 0, txq = 0, + vlan = 1, + macaddr = "55:44:33:22:11:00" }) + engine.configure(c) + engine.main({ duration = 1 }) + assert(engine.app_table.nic1.r.RAH[2]:bits(31, 1) == 1) + assert(engine.app_table.nic1.r.PFVLVF[1]:bits(31, 1) == 1) +]]) + +-- loop until all workers are done +while true do + local live = false + for w, s in pairs(worker.status()) do + live = live or s.alive + end + + if live then + C.sleep(0.1) + else + break + end +end From 9f3074d59e7bf28d1a6f6ca5e276fac37a89ed5f Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Thu, 10 Aug 2017 21:31:47 +0000 Subject: [PATCH 090/109] Add test ensuring MAC/VLAN indices are set right --- .../intel_mp/test_10g_vmdq_reconfig_mac.snabb | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 src/apps/intel_mp/test_10g_vmdq_reconfig_mac.snabb diff --git a/src/apps/intel_mp/test_10g_vmdq_reconfig_mac.snabb b/src/apps/intel_mp/test_10g_vmdq_reconfig_mac.snabb new file mode 100755 index 0000000000..72281224a3 --- /dev/null +++ b/src/apps/intel_mp/test_10g_vmdq_reconfig_mac.snabb @@ -0,0 +1,80 @@ +#!../../snabb snsh + +-- Snabb test script for checking that the MAC & VLAN indices +-- are selected correctly after an intel_mp instance is shut +-- down and restarted with a different config. +-- +-- This test exists to test the bug that was fixed in commit +-- 721f10bb0c3e076f79c54086fefd554851ac9679 + +local basic_apps = require("apps.basic.basic_apps") +local intel = require("apps.intel_mp.intel_mp") +local pcap = require("apps.pcap.pcap") +local lib = require("core.lib") + +local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") + +local c = config.new() + +-- first add two apps in order with different MACs and VLANs +config.app(c, "nicp0", intel.Intel, + { pciaddr = pciaddr0, + vmdq = true, + poolnum = 0, + rxq = 0, txq = 0, + vlan = 42, + macaddr = "00:11:22:33:44:55" }) +config.app(c, "source", basic_apps.Source) + +config.link(c, "source.out0 -> nicp0.input") + +engine.configure(c) +engine.main({ duration = 0.1 }) + +config.app(c, "nicp1", intel.Intel, + { pciaddr = pciaddr0, + vmdq = true, + poolnum = 1, + rxq = 0, txq = 0, + vlan = 43, + macaddr = "55:44:33:22:11:00" }) +config.link(c, "source.out1 -> nicp1.input") + +engine.configure(c) +engine.main({ duration = 0.1 }) + +-- then shut down the first one and start a new one on the same +-- pool as nicp1 +local c = config.new() + +config.app(c, "nicp1", intel.Intel, + { pciaddr = pciaddr0, + vmdq = true, + poolnum = 1, + rxq = 0, txq = 0, + vlan = 43, + macaddr = "55:44:33:22:11:00" }) +config.app(c, "source", basic_apps.Source) +config.link(c, "source.out1 -> nicp1.input") + +config.app(c, "nicp2", intel.Intel, + { pciaddr = pciaddr0, + vmdq = true, + poolnum = 1, + rxq = 1, txq = 1, + vlan = 43, + macaddr = "55:44:33:22:11:00" }) +config.link(c, "source.out2 -> nicp2.input") + +engine.configure(c) +engine.main({ duration = 0.1 }) + +-- MAC addresses are never disabled by intel_mp (or intel10g) +-- so both stay enabled. +-- TODO: this is issue #1205 (https://github.com/snabbco/snabb/issues/1205) +-- and these checks may need to change when that is resolved +assert(engine.app_table.nicp1.r.RAH[1]:bits(31, 1) == 1) +assert(engine.app_table.nicp2.r.RAH[2]:bits(31, 1) == 1) +-- only the second VLAN register should be enabled +assert(engine.app_table.nicp1.r.PFVLVF[0]:bits(31, 1) == 0) +assert(engine.app_table.nicp2.r.PFVLVF[1]:bits(31, 1) == 1) From b0b0daa563cc66c7e534abd614bd1d483942bc71 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 15 Aug 2017 21:56:42 +0000 Subject: [PATCH 091/109] Adjust sleep time and add `wait` to intel_mp test --- src/apps/intel_mp/test_10g_come_and_go.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/test_10g_come_and_go.sh b/src/apps/intel_mp/test_10g_come_and_go.sh index 9c538f1516..ce1a071945 100755 --- a/src/apps/intel_mp/test_10g_come_and_go.sh +++ b/src/apps/intel_mp/test_10g_come_and_go.sh @@ -2,12 +2,14 @@ SNABB_SEND_BLAST=true ./testsend.snabb $SNABB_PCI_INTEL1 0 source.pcap & BLAST=$! -SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=5 ./testrecv.snabb $SNABB_PCI_INTEL0 0 > results.0 & +SNABB_RECV_SPINUP=2 SNABB_RECV_DURATION=10 ./testrecv.snabb $SNABB_PCI_INTEL0 0 > results.0 & +RECV=$! sleep 1 export SNABB_RECV_DURATION=1 for i in {1..7}; do ./testrecv.snabb $SNABB_PCI_INTEL0 1; done > results.1 sleep 1 kill -9 $BLAST +wait $RECV test `cat results.* | grep "^RXDGPC" | awk '{print $2}'` -gt 10000 exit $? From 76b3c3486f67e07392b7970d031f1f6043dd140d Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 15 Aug 2017 22:04:47 +0000 Subject: [PATCH 092/109] Fix fd cleanup in intel_mp --- src/apps/intel_mp/intel_mp.lua | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 73ea61808a..4e3439f043 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1441,13 +1441,16 @@ function Intel82599:select_pool() -- using flock() to avoid conflicts. The contents of the memory doesn't -- matter since we only care about the lock state. for poolnum = 0, 63 do - local path = "/"..pooldir.."/"..self.pciaddress.."/"..poolnum - shm.create(path, "uint8_t") - self.poolfd = S.open(shm.root .. path, "rdwr") + local path = "/"..pooldir.."/"..self.pciaddress.."/"..poolnum + local ptr = shm.create(path, "uint8_t") + local poolfd = S.open(shm.root .. path, "creat, rdwr") - if self.poolfd:flock("nb, ex") then + if poolfd:flock("nb, ex") then available_pool = poolnum + self.poolfd = poolfd break + else + poolfd:close() end end From f5cb8be72d26e7b246f0ed4420f2d05fd8c428cf Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 28 Aug 2017 08:31:51 -0700 Subject: [PATCH 093/109] Change upstream branch of snabbwall to wingo-next See https://github.com/snabbco/snabb/pull/1202 --- src/doc/branches.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/branches.md b/src/doc/branches.md index 6f55a94577..8aa22a89a2 100644 --- a/src/doc/branches.md +++ b/src/doc/branches.md @@ -166,7 +166,7 @@ The current state of each branch with respect to master is visible here: - See snabbwall.org for more info Maintainer: Collectively maintained by Snabbwall application developers. - Next hop: kbara-next + Next hop: wingo-next #### aarch64 From d936934198510f39889c4d8749e4021fa724ed87 Mon Sep 17 00:00:00 2001 From: Nicola 'tekNico' Larosa Date: Mon, 19 Jun 2017 09:24:15 +0200 Subject: [PATCH 094/109] Add default for number of pools (revised) --- src/apps/intel_mp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index f125656e03..928ad688fb 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -28,7 +28,7 @@ specified but assumed to be broadly applicable. — Key **rxq** *Optional*. The receive queue to attach to, numbered from 0. The default is 0. -When VMDq is enabled, this number is used to index a queue (from 0 to 3) +When VMDq is enabled, this number is used to index a queue (0 or 1) for the selected pool. — Key **txq** From 702d01bc557a394288cde453d8ada6492ac992cd Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 18 Aug 2017 21:54:36 +0000 Subject: [PATCH 095/109] Use conf defaults explicitly for consistency --- src/apps/intel_mp/intel_mp.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 4e3439f043..119bf7f000 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -314,22 +314,22 @@ function Intel:new (conf) path = pci.path(conf.pciaddr), -- falling back to defaults for selftest bypassing config.app ndesc = conf.ndescriptors or self.config.ndescriptors.default, - txq = conf.txq, - rxq = conf.rxq, + txq = conf.txq or self.config.txq.default, + rxq = conf.rxq or self.config.rxq.default, mtu = conf.mtu or self.config.mtu.default, linkup_wait = conf.linkup_wait or self.config.linkup_wait.default, linkup_wait_recheck = conf.linkup_wait_recheck or self.config.linkup_wait_recheck.default, wait_for_link = conf.wait_for_link, - vmdq = conf.vmdq, + vmdq = conf.vmdq or self.config.vmdq.default, poolnum = conf.poolnum, macaddr = conf.macaddr, vlan = conf.vlan, want_mirror = conf.mirror, rxcounter = conf.rxcounter, txcounter = conf.txcounter, - rate_limit = conf.rate_limit, - priority = conf.priority, + rate_limit = conf.rate_limit or self.config.rate_limit.default, + priority = conf.priority or self.config.priority.default } local vendor = lib.firstline(self.path .. "/vendor") From 4f27b28ec61e80dd83236df9e256531e000f0878 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Sat, 19 Aug 2017 00:08:02 +0000 Subject: [PATCH 096/109] Add option to disable rxq/txq in intel_mp By default rxq=0, txq=0 are enabled now, but this adds an "off" option to disabled them. Also adds a test to make sure this works. --- src/apps/intel_mp/README.md | 3 +- src/apps/intel_mp/intel_mp.lua | 4 ++ src/apps/intel_mp/test_10g_rxq_disable.snabb | 48 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100755 src/apps/intel_mp/test_10g_rxq_disable.snabb diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index 928ad688fb..24ed92078e 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -29,11 +29,12 @@ specified but assumed to be broadly applicable. *Optional*. The receive queue to attach to, numbered from 0. The default is 0. When VMDq is enabled, this number is used to index a queue (0 or 1) -for the selected pool. +for the selected pool. Passing `"off"` will disable the receive queue. — Key **txq** *Optional*. The transmit queue to attach to, numbered from 0. The default is 0. +Passing `"off"` will disable the transmit queue. — Key **vmdq** diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 119bf7f000..6696594917 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -332,6 +332,10 @@ function Intel:new (conf) priority = conf.priority or self.config.priority.default } + -- txq/rxq have defaults so nil can't represent off state + if conf.txq == "off" then self.txq = nil end + if conf.rxq == "off" then self.rxq = nil end + local vendor = lib.firstline(self.path .. "/vendor") local device = lib.firstline(self.path .. "/device") local byid = byPciID[tonumber(device)] diff --git a/src/apps/intel_mp/test_10g_rxq_disable.snabb b/src/apps/intel_mp/test_10g_rxq_disable.snabb new file mode 100755 index 0000000000..967dfb89d5 --- /dev/null +++ b/src/apps/intel_mp/test_10g_rxq_disable.snabb @@ -0,0 +1,48 @@ +#!../../snabb snsh + +-- Test to make sure rx/tx queues can be explicitly disabled + +local basic_apps = require("apps.basic.basic_apps") +local intel = require("apps.intel_mp.intel_mp") +local lib = require("core.lib") + +local pciaddr0 = lib.getenv("SNABB_PCI_INTEL0") +local pciaddr1 = lib.getenv("SNABB_PCI_INTEL1") + +local c = config.new() + +config.app(c, "n0", intel.Intel, + { pciaddr = pciaddr0, + rxcounter = 1, + rxq = 0, txq = 0, + wait_for_link = true }) + +config.app(c, "n1", intel.Intel, + { pciaddr = pciaddr1, + rxq = "off", + txq = "off", + wait_for_link = true }) + +config.app(c, "source0", basic_apps.Source) +config.app(c, "source1", basic_apps.Source) + +config.app(c, "sink", basic_apps.Sink) + +config.link(c, "source0.output -> n0.input") +config.link(c, "source1.output -> n1.input") +config.link(c, "n0.output -> sink.input0") +config.link(c, "n1.output -> sink.input1") + +engine.configure(c) +engine.main({ duration = 1 }) + +-- no packets should get queued in either NIC +local n0_stats = engine.app_table.n0:get_rxstats() +assert(n0_stats.bytes == 0, "n0 received packets") + +-- can't call get_rxstats on disabled rxq so check RXDGPC +assert(engine.app_table.n1:rxdmapackets() == 0, + "n1 received packets") +-- also make sure packets *are* going to n1 though not to a queue +assert(engine.app_table.n1:rxbytes() > 0, + "n1 didn't see any traffic") From b9a04a079f79fcaaff681b3c78127f0e538ed203 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Sat, 19 Aug 2017 16:36:13 +0000 Subject: [PATCH 097/109] Explicitly disable rxq/txq for intel_mp test --- src/apps/intel_mp/test_10g_sw_sem.snabb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/test_10g_sw_sem.snabb b/src/apps/intel_mp/test_10g_sw_sem.snabb index 657a938772..36bf309a83 100755 --- a/src/apps/intel_mp/test_10g_sw_sem.snabb +++ b/src/apps/intel_mp/test_10g_sw_sem.snabb @@ -2,7 +2,7 @@ local intel = require("apps.intel_mp.intel_mp") local pci0 = os.getenv("SNABB_PCI_INTEL0") local pci1 = os.getenv("SNABB_PCI_INTEL1") -local nic = intel.Intel:new({pciaddr = pci0}) +local nic = intel.Intel:new({pciaddr = pci0, rxq = "off", txq = "off"}) nic:unlock_sw_sem() nic:lock_sw_sem() From ac2e60ced27c34c532992199c718aa383de45462 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 18 Aug 2017 22:32:03 +0000 Subject: [PATCH 098/109] Update intel_mp README with diagram & methods --- src/apps/intel_mp/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index 24ed92078e..d4fcf691fa 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -6,6 +6,13 @@ be attached to separate instances of the app on different processes. The links are named `input` and `output`. + DIAGRAM: Intel + +-------+ + | | + input ---->* Intel *----> output + | | + +-------+ + ## Caveats If attaching multiple processes to a single NIC, performance appears @@ -13,6 +20,23 @@ better with `engine.busywait = false`. The `intel_mp.Intel` app can drive an Intel 82599 NIC at 14 million pps. +— Method **Intel:get_rxstats** + +Returns a table with the following keys: + +* `counter_id` - Counter id +* `packets` - Number of packets received +* `dropped` - Number of packets dropped +* `bytes` - Total bytes received + +— Method **Intel:get_txstats** + +Returns a table with the following keys: + +* `counter_id` - Counter id +* `packets` - Number of packets sent +* `bytes` - Total bytes sent + ## Configuration — Key **pciaddr** From 790786f1c08b12bf9a1d951f6b84bd9831032f29 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 18 Aug 2017 22:34:14 +0000 Subject: [PATCH 099/109] Update intel_mp README with all ported config options --- src/apps/intel_mp/README.md | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index d4fcf691fa..2113e69b4b 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -86,6 +86,53 @@ is to select a pool number automatically. *Optional*. A twelve-bit integer (0-4095). If set, incoming packets from other VLANs are dropped and outgoing packets are tagged with a VLAN header. +— Key **mirror** + +*Optional*. A table. If set, this app will receive copies of all selected +packets on the physical port. The selection is configured by setting keys +of the *mirror* table. Either *mirror.pool* or *mirror.port* may be set. + +If *mirror.pool* is `true` all pools defined on this physical port are +mirrored. If *mirror.pool* is an array of pool numbers then the specified +pools are mirrored. + +If *mirror.port* is one of "in", "out" or "inout" all incoming and/or +outgoing packets on the port are mirrored respectively. Note that this +does not include internal traffic which does not enter or exit through +the physical port. + +— Key **rxcounter** + +— Key **txcounter** + +*Optional*. Four bit integers (0-15). If set, incoming/outgoing packets +will be counted in the selected statistics counter respectively. Multiple +apps can share a counter. To retrieve counter statistics use +`Intel:get_rxstats()` and `Intel:get_txstats()`. + +— Key **rate_limit** + +*Optional*. Number. Limits the maximum Mbit/s to transmit. Default is 0 +which means no limit. Only applies to outgoing traffic. + +— Key **priority** + +*Optional*. Floating point number. Weight for the *round-robin* algorithm +used to arbitrate transmission when *rate_limit* is not set or adds up to +more than the line rate of the physical port. Default is 1.0 (scaled to +the geometric middle of the scale which goes from 1/128 to 128). The +absolute value is not relevant, instead only the ratio between competing +apps controls their respective bandwidths. Only applies to outgoing +traffic. + +For example, if two apps without *rate_limit* set have the same +*priority*, both get the same output bandwidth. If the priorities are +3.0/1.0, the output bandwidth is split 75%/25%. Likewise, 1.0/0.333 or +1.5/0.5 yield the same result. + +Note that even a low-priority app can use the whole line rate unless other +(higher priority) apps are using up the available bandwidth. + — Key **rsskey** *Optional*. The rsskey is a 32 bit integer that seeds the hash used to From aa81c5465ed7c048d31a0f651bcfb6026bbdb6a7 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 23 Aug 2017 12:09:11 -0700 Subject: [PATCH 100/109] Fix documented max pools/queues in intel_mp README --- src/apps/intel_mp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/intel_mp/README.md b/src/apps/intel_mp/README.md index 2113e69b4b..0d6a564e74 100644 --- a/src/apps/intel_mp/README.md +++ b/src/apps/intel_mp/README.md @@ -194,5 +194,5 @@ Each chipset supports a differing number of receive / transmit queues: * Intel1g i210 supports 4 receive and 4 transmit queues, 0-3 The Intel82599 supports both VMDq and RSS with 32/64 pools and 4/2 RSS queues for -each pool. This driver only supports configurations with 32 pools/4 queues. +each pool. This driver only supports configurations with 64 pools/2 queues. While the i350 supports VMDq, this driver does not currently support it. From f2c673f4908b18df99e42c74a9112c924b869875 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 30 Aug 2017 12:11:57 +0000 Subject: [PATCH 101/109] Add a reconfig method to intel_mp Adds a reconfig that works like the equivalent method in intel10g. Maybe related to fixing some benchmark failures for snabbnfv iperf. --- src/apps/intel_mp/intel_mp.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 6696594917..b6828ac1b1 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -685,6 +685,37 @@ function Intel:rss_tab_build () end self:rss_tab(tab) end + +-- reconfiguration should not change poolnum or queues +function Intel:reconfig (conf) + self:unset_mirror() + self:unset_VLAN() + self:unset_MAC() + + self.macaddr = conf.macaddr + self.mirror = conf.mirror + self.vlan = conf.vlan + self.rxcounter = conf.rxcounter + self.txcounter = conf.txcounter + self.rate_limit = conf.rate_limit + self.priority = conf.priority + + self:set_MAC() + self:set_mirror() + self:set_VLAN() + self:set_rxstats() + self:set_txstats() + self:set_tx_rate() + + -- TODO: factor this out & share with code in rx/tx init above + self.r.RXDCTL(bits{Enable=25, VME=30}) + self.r.RXDCTL:wait(bits{enable=25}) + self.r.DCA_RXCTRL:clr(bits{RxCTRL=12}) + self.r.DMATXCTL:set(bits{TE=0}) + self.r.TXDCTL:set(bits({Enable=25, SWFLSH=26, hthresh=8}) + 32) + self.r.TXDCTL:wait(bits{Enable=25}) +end + function Intel:stop () if self.rxq then -- 4.5.9 From 5ed8e4fbf956884e7bef508c310a7e13a93b08a2 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 1 Sep 2017 21:29:25 +0000 Subject: [PATCH 102/109] Clear ETQF/ETQS registers on init --- src/apps/intel_mp/intel_mp.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index b6828ac1b1..93adcce85f 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -62,6 +62,8 @@ ALLRXDCTL 0x01028 +0x40*0..63 RW Receive Descriptor Control ALLRXDCTL 0x0D028 +0x40*64..127 RW Receive Descriptor Control DAQF 0x0E200 +0x04*0..127 RW Destination Address Queue Filter FTQF 0x0E600 +0x04*0..127 RW Five Tuple Queue Filter +ETQF 0x05128 +0x04*0..7 RW EType Queue Filter +ETQS 0x0EC00 +0x04*0..7 RW EType Queue Select MPSAR 0x0A600 +0x04*0..255 RW MAC Pool Select Array PFUTA 0X0F400 +0x04*0..127 RW PF Unicast Table Array PFVLVF 0x0F100 +0x04*0..63 RW PF VM VLAN Pool Filter @@ -1351,6 +1353,8 @@ function Intel82599:init () self.r.RTTDT2C[i](0) self.r.RTTPT2C[i](0) self.r.RTRPT4C[i](0) + self.r.ETQF[i](0) + self.r.ETQS[i](0) end self.r.HLREG0(bits{ @@ -1423,8 +1427,6 @@ function Intel82599:vmdq_enable () -- enable vlan filter (4.6.7, 7.1.1.2) self.r.VLNCTRL:set(bits { VFE=30 }) - -- intel10g zeroes out ETQF,ETQS here but they are init to 0 - -- RTRUP2TC/RTTUP2TC cleared above in init -- DMA TX TCP max allowed size requests (set to 1MB) From c91f00442a67e11e51a0d67e0f72ee06858bcee8 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Fri, 1 Sep 2017 21:29:48 +0000 Subject: [PATCH 103/109] Fix RXPBSIZE initialization The bits method takes an offset and a length, not an offset and an end offset. --- src/apps/intel_mp/intel_mp.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 93adcce85f..f3e80a4d97 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -1331,12 +1331,12 @@ function Intel82599:init () self.r.VLNCTRL(0x8100) -- explicity set default self.r.RXCSUM(0) -- turn off all checksum offload - self.r.RXPBSIZE[0]:bits(10,19, 0x200) - self.r.TXPBSIZE[0]:bits(10,19, 0xA0) + self.r.RXPBSIZE[0]:bits(10,10, 0x200) + self.r.TXPBSIZE[0]:bits(10,10, 0xA0) self.r.TXPBTHRESH[0](0xA0) for i=1,7 do - self.r.RXPBSIZE[i]:bits(10,19, 0) - self.r.TXPBSIZE[i]:bits(10,19, 0) + self.r.RXPBSIZE[i]:bits(10,10, 0) + self.r.TXPBSIZE[i]:bits(10,10, 0) self.r.TXPBTHRESH[i](0) end From 6823705896e2e5fe7d5abb181214922e49cc0278 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 5 Sep 2017 22:51:30 +0000 Subject: [PATCH 104/109] Set packet buffer size to max (16KB) via SRRCTL --- src/apps/intel_mp/intel_mp.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index f3e80a4d97..c481be6641 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -460,9 +460,8 @@ function Intel:init_rx_q () end self.r.SRRCTL(0) self.r.SRRCTL:set(bits { - -- Set packet buff size to 0b1010 kbytes - BSIZEPACKET1 = 1, - BSIZEPACKET3 = 3, + -- Set packet buff size to 0b10000 kbytes (max) + BSIZEPACKET4 = 4, -- Drop packets when no descriptors Drop_En = self:offset("SRRCTL", "Drop_En") }) From ee98e2f67ad38fb5a251bd48d7cd8b2a5bc8b5de Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Sat, 9 Sep 2017 00:25:41 +0000 Subject: [PATCH 105/109] Only sync stats in push if rxq is disabled --- src/apps/intel_mp/intel_mp.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index c481be6641..8c0f707a15 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -596,7 +596,9 @@ function Intel:push () end self.r.TDT(self.tdt) - -- same code as in pull, we repeat it in case this app only enables Tx + -- same code as in pull, but we only call it in case the rxq + -- is disabled for this app + if self.rxq and self.output["output"] then return end if self.run_stats and self.sync_timer() then self:sync_stats() end From ecb74d385b82214261cdb5724026f2fbc94860f9 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Sat, 9 Sep 2017 00:50:24 +0000 Subject: [PATCH 106/109] Cache functions imported from link module --- src/apps/intel_mp/intel_mp.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 8c0f707a15..062b95b238 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -26,6 +26,7 @@ local counter = require("core.counter") local macaddress = require("lib.macaddress") local shm = require("core.shm") local S = require("syscall") +local transmit, receive, empty = link.transmit, link.receive, link.empty -- It's not clear what address to use for EEMNGCTL_i210 DPDK PMD / linux e1000 -- both use 1010 but the docs say 12030 @@ -569,8 +570,8 @@ function Intel:push () if li == nil then return end -- assert(li, "intel_mp:push: no input link") - while not link.empty(li) and self:ringnext(self.tdt) ~= self.tdh do - local p = link.receive(li) + while not empty(li) and self:ringnext(self.tdt) ~= self.tdh do + local p = receive(li) -- NB: see comment in intel10g for why this is commented out, -- the rest of the loop body goes in an else branch --if p.length > self.mtu then @@ -614,7 +615,7 @@ function Intel:pull () while band(self.rxdesc[self.rdt].status, 0x01) == 1 and pkts < engine.pull_npackets do local p = self.rxqueue[self.rdt] p.length = self.rxdesc[self.rdt].length - link.transmit(lo, p) + transmit(lo, p) local np = packet.allocate() self.rxqueue[self.rdt] = np From f858e4857f5a75f29108bf54b2849de0f6e35a28 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Mon, 11 Sep 2017 23:45:37 +0000 Subject: [PATCH 107/109] Enable VM TX loopback in VMDq mode --- src/apps/intel_mp/intel_mp.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 062b95b238..e1c2c24270 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -74,6 +74,7 @@ PFMRVLAN 0x0F610 +0x04*0..7 RW PF Mirror Rule VLAN PFMRVM 0x0F630 +0x04*0..7 RW PF Mirror Rule Pool PFVFRE 0x051E0 +0x04*0..1 RW PF VF Receive Enable PFVFTE 0x08110 +0x04*0..1 RW PF VF Transmit Enable +PFVMTXSW 0x05180 +0x04*0..1 RW PF VM Tx Switch Loopback Enable PFVFSPOOF 0x08200 +0x04*0..7 RW PF VF Anti Spoof Control PFVMVIR 0x08000 +0x04*0..63 RW PF VM VLAN Insert Register PFVML2FLT 0x0F000 +0x04*0..63 RW PF VM L2 Control Register @@ -525,6 +526,8 @@ function Intel:init_tx_q () -- 4.5.10 self.r.RTTDT1C(0x80) -- enables packet Tx for this VF's pool self.r.PFVFTE[math.floor(self.poolnum/32)]:set(bits{VFTE=self.poolnum%32}) + -- enable TX loopback + self.r.PFVMTXSW[math.floor(self.poolnum/32)]:clr(bits{LLE=self.poolnum%32}) end if self.r.DMATXCTL then From 033f657dcaf5aa7eefb2bb14b534bc12e247447d Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 12 Sep 2017 00:57:31 +0000 Subject: [PATCH 108/109] Revert "Add a reconfig method to intel_mp" This reverts commit b3ff7af130ad9cf0316e9451a6c30cc4ce558090. It's unclear that this commit actually improved performance on the iperf test, so try disabling it again. --- src/apps/intel_mp/intel_mp.lua | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index e1c2c24270..8c5ef05ff2 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -692,37 +692,6 @@ function Intel:rss_tab_build () end self:rss_tab(tab) end - --- reconfiguration should not change poolnum or queues -function Intel:reconfig (conf) - self:unset_mirror() - self:unset_VLAN() - self:unset_MAC() - - self.macaddr = conf.macaddr - self.mirror = conf.mirror - self.vlan = conf.vlan - self.rxcounter = conf.rxcounter - self.txcounter = conf.txcounter - self.rate_limit = conf.rate_limit - self.priority = conf.priority - - self:set_MAC() - self:set_mirror() - self:set_VLAN() - self:set_rxstats() - self:set_txstats() - self:set_tx_rate() - - -- TODO: factor this out & share with code in rx/tx init above - self.r.RXDCTL(bits{Enable=25, VME=30}) - self.r.RXDCTL:wait(bits{enable=25}) - self.r.DCA_RXCTRL:clr(bits{RxCTRL=12}) - self.r.DMATXCTL:set(bits{TE=0}) - self.r.TXDCTL:set(bits({Enable=25, SWFLSH=26, hthresh=8}) + 32) - self.r.TXDCTL:wait(bits{Enable=25}) -end - function Intel:stop () if self.rxq then -- 4.5.9 From be89a9d4011fa86f9529132c7c6094dc7c989165 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 18 Sep 2017 13:29:47 +0200 Subject: [PATCH 109/109] intel_mp app relies on lib.parse to supply default values The previous code was using the "conf.foo or default" idiom even after core.app supplied default values, which in effect disallows false non-default boolean configurations. --- src/apps/intel_mp/intel_mp.lua | 20 +++++++++----------- src/apps/intel_mp/test_10g_rss_tab.snabb | 14 +++++++++----- src/apps/intel_mp/test_10g_sw_sem.snabb | 6 +++++- src/apps/intel_mp/test_1g_rss_tab.snabb | 14 +++++++++----- src/apps/intel_mp/test_1g_sw_sem.snabb | 6 +++++- src/apps/intel_mp/testup.snabb | 8 +++++++- 6 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/apps/intel_mp/intel_mp.lua b/src/apps/intel_mp/intel_mp.lua index 8c5ef05ff2..4daf58694a 100644 --- a/src/apps/intel_mp/intel_mp.lua +++ b/src/apps/intel_mp/intel_mp.lua @@ -316,24 +316,22 @@ function Intel:new (conf) r = {}, pciaddress = conf.pciaddr, path = pci.path(conf.pciaddr), - -- falling back to defaults for selftest bypassing config.app - ndesc = conf.ndescriptors or self.config.ndescriptors.default, - txq = conf.txq or self.config.txq.default, - rxq = conf.rxq or self.config.rxq.default, - mtu = conf.mtu or self.config.mtu.default, - linkup_wait = conf.linkup_wait or self.config.linkup_wait.default, - linkup_wait_recheck = - conf.linkup_wait_recheck or self.config.linkup_wait_recheck.default, + ndesc = conf.ndescriptors, + txq = conf.txq, + rxq = conf.rxq, + mtu = conf.mtu, + linkup_wait = conf.linkup_wait, + linkup_wait_recheck = conf.linkup_wait_recheck, wait_for_link = conf.wait_for_link, - vmdq = conf.vmdq or self.config.vmdq.default, + vmdq = conf.vmdq, poolnum = conf.poolnum, macaddr = conf.macaddr, vlan = conf.vlan, want_mirror = conf.mirror, rxcounter = conf.rxcounter, txcounter = conf.txcounter, - rate_limit = conf.rate_limit or self.config.rate_limit.default, - priority = conf.priority or self.config.priority.default + rate_limit = conf.rate_limit, + priority = conf.priority } -- txq/rxq have defaults so nil can't represent off state diff --git a/src/apps/intel_mp/test_10g_rss_tab.snabb b/src/apps/intel_mp/test_10g_rss_tab.snabb index a5f11d06f2..8f08223044 100755 --- a/src/apps/intel_mp/test_10g_rss_tab.snabb +++ b/src/apps/intel_mp/test_10g_rss_tab.snabb @@ -2,19 +2,23 @@ local intel = require("apps.intel_mp.intel_mp") local pci0 = os.getenv("SNABB_PCI_INTEL0") local pci1 = os.getenv("SNABB_PCI_INTEL1") -local nic = intel.Intel:new({ pciaddr = pci0 }) +local parse = require("core.lib").parse +local function new_intel (arg) + return intel.Intel:new(parse(arg, intel.Intel.config)) +end +local nic = new_intel({ pciaddr = pci0 }) local tab = nic:rss_tab() assert(#tab == 0) assert(tab[0]) -local nic0 = intel.Intel:new({pciaddr = pci0, rxq = 0}) -local nic1 = intel.Intel:new({pciaddr = pci0, rxq = 1}) +local nic0 = new_intel({pciaddr = pci0, rxq = 0}) +local nic1 = new_intel({pciaddr = pci0, rxq = 1}) tab = nic:rss_tab() assert(#tab == 1) assert(tab[0]) assert(tab[1]) -local nic2 = intel.Intel:new({pciaddr = pci0, rxq = 2}) -local nic3 = intel.Intel:new({pciaddr = pci0, rxq = 3}) +local nic2 = new_intel({pciaddr = pci0, rxq = 2}) +local nic3 = new_intel({pciaddr = pci0, rxq = 3}) tab = nic:rss_tab() assert(#tab == 3) assert(tab[2]) diff --git a/src/apps/intel_mp/test_10g_sw_sem.snabb b/src/apps/intel_mp/test_10g_sw_sem.snabb index 36bf309a83..d603fa45ae 100755 --- a/src/apps/intel_mp/test_10g_sw_sem.snabb +++ b/src/apps/intel_mp/test_10g_sw_sem.snabb @@ -2,7 +2,11 @@ local intel = require("apps.intel_mp.intel_mp") local pci0 = os.getenv("SNABB_PCI_INTEL0") local pci1 = os.getenv("SNABB_PCI_INTEL1") -local nic = intel.Intel:new({pciaddr = pci0, rxq = "off", txq = "off"}) +local parse = require("core.lib").parse +local function new_intel (arg) + return intel.Intel:new(parse(arg, intel.Intel.config)) +end +local nic = new_intel({pciaddr = pci0, rxq = "off", txq = "off"}) nic:unlock_sw_sem() nic:lock_sw_sem() diff --git a/src/apps/intel_mp/test_1g_rss_tab.snabb b/src/apps/intel_mp/test_1g_rss_tab.snabb index 0fb11b7ae4..9a9ca3814c 100755 --- a/src/apps/intel_mp/test_1g_rss_tab.snabb +++ b/src/apps/intel_mp/test_1g_rss_tab.snabb @@ -2,19 +2,23 @@ local intel = require("apps.intel_mp.intel_mp") local pci0 = os.getenv("SNABB_PCI_INTEL1G0") local pci1 = os.getenv("SNABB_PCI_INTEL1G1") -local nic = intel.Intel:new({ pciaddr = pci0 }) +local parse = require("core.lib").parse +local function new_intel (arg) + return intel.Intel:new(parse(arg, intel.Intel.config)) +end +local nic = new_intel({ pciaddr = pci0 }) local tab = nic:rss_tab() assert(#tab == 0) assert(tab[0]) -local nic0 = intel.Intel:new({pciaddr = pci0, rxq = 0}) -local nic1 = intel.Intel:new({pciaddr = pci0, rxq = 1}) +local nic0 = new_intel({pciaddr = pci0, rxq = 0}) +local nic1 = new_intel({pciaddr = pci0, rxq = 1}) tab = nic:rss_tab() assert(#tab == 1) assert(tab[0]) assert(tab[1]) -local nic2 = intel.Intel:new({pciaddr = pci0, rxq = 2}) -local nic3 = intel.Intel:new({pciaddr = pci0, rxq = 3}) +local nic2 = new_intel({pciaddr = pci0, rxq = 2}) +local nic3 = new_intel({pciaddr = pci0, rxq = 3}) tab = nic:rss_tab() assert(#tab == 3) assert(tab[2]) diff --git a/src/apps/intel_mp/test_1g_sw_sem.snabb b/src/apps/intel_mp/test_1g_sw_sem.snabb index fe5558e256..3fbb928c47 100755 --- a/src/apps/intel_mp/test_1g_sw_sem.snabb +++ b/src/apps/intel_mp/test_1g_sw_sem.snabb @@ -2,7 +2,11 @@ local intel = require("apps.intel_mp.intel_mp") local pci0 = os.getenv("SNABB_PCI_INTEL1G0") local pci1 = os.getenv("SNABB_PCI_INTEL1G1") -local nic = intel.Intel:new({pciaddr = pci0}) +local parse = require("core.lib").parse +local function new_intel (arg) + return intel.Intel:new(parse(arg, intel.Intel.config)) +end +local nic = new_intel({pciaddr = pci0}) nic:unlock_sw_sem() nic:lock_sw_sem() diff --git a/src/apps/intel_mp/testup.snabb b/src/apps/intel_mp/testup.snabb index 2279a43729..b31ec6a2e5 100755 --- a/src/apps/intel_mp/testup.snabb +++ b/src/apps/intel_mp/testup.snabb @@ -7,6 +7,12 @@ local qno = tonumber(table.remove(args,1)) local intel = require("apps.intel_mp.intel_mp") local C = require("ffi").C -local nic = intel.Intel:new({ pciaddr=pciaddr, rxq = qno, ndescriptors = 2048, wait_for_link = true }) +local parse = require("core.lib").parse +local function new_intel (arg) + return intel.Intel:new(parse(arg, intel.Intel.config)) +end + +local nic = new_intel( + { pciaddr=pciaddr, rxq = qno, ndescriptors = 2048, wait_for_link = true }) print(nic:link_status()) main.exit(0)