hs-test: support for multiple rx/tx af_packet queues 36/43136/8
authorFlorin Coras <[email protected]>
Tue, 10 Jun 2025 05:14:30 +0000 (01:14 -0400)
committerFlorin Coras <[email protected]>
Thu, 12 Jun 2025 09:30:49 +0000 (05:30 -0400)
Type: test

Change-Id: I13d12ea2558fa6ef3849a69a85d970256af52031
Signed-off-by: Florin Coras <[email protected]>
extras/hs-test/infra/netconfig.go
extras/hs-test/infra/suite_ldp.go
extras/hs-test/infra/vppinstance.go

index d263b4b..c8c2719 100644 (file)
@@ -177,6 +177,18 @@ func (n *NetInterface) configureUpState() error {
        return nil
 }
 
+func (n *NetInterface) configureMultiQueue() error {
+       // TODO multiqueue for tap
+       if n.Type() != Veth {
+               return nil
+       }
+       err := linkSetMultiQueue(n.Name())
+       if err != nil {
+               return fmt.Errorf("set multiqueue failed: %v", err)
+       }
+       return nil
+}
+
 func (n *NetInterface) configureNetworkNamespace() error {
        if n.NetworkNamespace != "" {
                err := linkSetNetns(n.name, n.NetworkNamespace)
@@ -212,6 +224,10 @@ func (n *NetInterface) configure() error {
                return err
        }
 
+       if err := n.configureMultiQueue(); err != nil {
+               return err
+       }
+
        if err := n.configureNetworkNamespace(); err != nil {
                return err
        }
@@ -392,6 +408,16 @@ func linkSetNetns(ifName, ns string) error {
        return nil
 }
 
+func linkSetMultiQueue(ifName string) error {
+       cmd := exec.Command("ethtool", "-L", ifName, "rx", "4", "tx", "4")
+       fmt.Println("configuring multiqueue for interface:", cmd.String())
+       err := cmd.Run()
+       if err != nil {
+               return fmt.Errorf("error configuring multiqueue '%s: %v", ifName, err)
+       }
+       return nil
+}
+
 func newCommand(s []string, ns string) *exec.Cmd {
        return appendNetns(s, ns)
 }
index 78c9e14..76f4289 100644 (file)
@@ -136,7 +136,9 @@ func (s *LdpSuite) SetupServerVpp(serverContainer *Container) {
        serverVpp := serverContainer.VppInstance
        s.AssertNil(serverVpp.Start())
 
-       idx, err := serverVpp.createAfPacket(s.Interfaces.Server, false)
+       numCpus := uint16(len(serverContainer.AllocatedCpus))
+       numWorkers := uint16(max(numCpus-1, 1))
+       idx, err := serverVpp.createAfPacket(s.Interfaces.Server, false, WithNumRxQueues(numWorkers), WithNumTxQueues(numCpus))
        s.AssertNil(err, fmt.Sprint(err))
        s.AssertNotEqual(0, idx)
 }
@@ -145,7 +147,9 @@ func (s *LdpSuite) setupClientVpp(clientContainer *Container) {
        clientVpp := clientContainer.VppInstance
        s.AssertNil(clientVpp.Start())
 
-       idx, err := clientVpp.createAfPacket(s.Interfaces.Client, false)
+       numCpus := uint16(len(clientContainer.AllocatedCpus))
+       numWorkers := uint16(max(numCpus-1, 1))
+       idx, err := clientVpp.createAfPacket(s.Interfaces.Client, false, WithNumRxQueues(numWorkers), WithNumTxQueues(numCpus))
        s.AssertNil(err, fmt.Sprint(err))
        s.AssertNotEqual(0, idx)
 }
index ec32f85..7acf8ae 100644 (file)
@@ -321,7 +321,21 @@ func (vpp *VppInstance) WaitForApp(appName string, timeout int) {
        vpp.getSuite().AssertNil(1, "Timeout while waiting for app '%s'", appName)
 }
 
-func (vpp *VppInstance) createAfPacket(veth *NetInterface, IPv6 bool) (interface_types.InterfaceIndex, error) {
+type AfPacketOption func(*af_packet.AfPacketCreateV3)
+
+func WithNumRxQueues(numRxQueues uint16) AfPacketOption {
+       return func(cfg *af_packet.AfPacketCreateV3) {
+               cfg.NumRxQueues = numRxQueues
+       }
+}
+
+func WithNumTxQueues(numTxQueues uint16) AfPacketOption {
+       return func(cfg *af_packet.AfPacketCreateV3) {
+               cfg.NumTxQueues = numTxQueues
+       }
+}
+
+func (vpp *VppInstance) createAfPacket(veth *NetInterface, IPv6 bool, opts ...AfPacketOption) (interface_types.InterfaceIndex, error) {
        var ipAddress string
        var err error
 
@@ -362,6 +376,10 @@ func (vpp *VppInstance) createAfPacket(veth *NetInterface, IPv6 bool) (interface
                createReq.HwAddr = veth.HwAddress
        }
 
+       // Apply all optional configs
+       for _, opt := range opts {
+               opt(createReq)
+       }
        vpp.getSuite().Log("create af-packet interface " + veth.Name())
        if err := vpp.ApiStream.SendMsg(createReq); err != nil {
                vpp.getSuite().HstFail()