From e50f1ffdff3a7198f76c3cf45655f5fc2929006c Mon Sep 17 00:00:00 2001 From: Tariq Ibrahim Date: Tue, 20 Jun 2023 22:13:10 -0700 Subject: [PATCH] [tuning]add ability to set tx queue len Signed-off-by: Tariq Ibrahim --- plugins/meta/tuning/tuning.go | 40 +++++++- plugins/meta/tuning/tuning_test.go | 148 ++++++++++++++++++++++++++++- 2 files changed, 186 insertions(+), 2 deletions(-) diff --git a/plugins/meta/tuning/tuning.go b/plugins/meta/tuning/tuning.go index 20946e66c..043cf990d 100644 --- a/plugins/meta/tuning/tuning.go +++ b/plugins/meta/tuning/tuning.go @@ -53,6 +53,7 @@ type TuningConf struct { Mac string `json:"mac,omitempty"` Promisc bool `json:"promisc,omitempty"` Mtu int `json:"mtu,omitempty"` + TxQLen int `json:"txQLen,omitempty"` Allmulti *bool `json:"allmulti,omitempty"` RuntimeConfig struct { @@ -69,6 +70,7 @@ type IPAMArgs struct { Promisc *bool `json:"promisc,omitempty"` Mtu *int `json:"mtu,omitempty"` Allmulti *bool `json:"allmulti,omitempty"` + TxQLen *int `json:"txQLen,omitempty"` } // configToRestore will contain interface attributes that should be restored on cmdDel @@ -77,6 +79,7 @@ type configToRestore struct { Promisc *bool `json:"promisc,omitempty"` Mtu int `json:"mtu,omitempty"` Allmulti *bool `json:"allmulti,omitempty"` + TxQLen int `json:"txQLen,omitempty"` } // MacEnvArgs represents CNI_ARG @@ -136,6 +139,10 @@ func parseConf(data []byte, envArgs string) (*TuningConf, error) { if conf.Args.A.Allmulti != nil { conf.Allmulti = conf.Args.A.Allmulti } + + if conf.Args.A.TxQLen != nil { + conf.TxQLen = *conf.Args.A.TxQLen + } } return &conf, nil @@ -204,6 +211,14 @@ func changeAllmulti(ifName string, val bool) error { return netlink.LinkSetAllmulticastOff(link) } +func changeTxQLen(ifName string, txQLen int) error { + link, err := netlink.LinkByName(ifName) + if err != nil { + return fmt.Errorf("failed to get %q: %v", ifName, err) + } + return netlink.LinkSetTxQLen(link, txQLen) +} + func createBackup(ifName, containerID, backupPath string, tuningConf *TuningConf) error { config := configToRestore{} link, err := netlink.LinkByName(ifName) @@ -224,6 +239,9 @@ func createBackup(ifName, containerID, backupPath string, tuningConf *TuningConf config.Allmulti = new(bool) *config.Allmulti = (link.Attrs().RawFlags&unix.IFF_ALLMULTI != 0) } + if tuningConf.TxQLen != 0 { + config.TxQLen = link.Attrs().TxQLen + } if _, err := os.Stat(backupPath); os.IsNotExist(err) { if err = os.MkdirAll(backupPath, 0o600); err != nil { @@ -292,6 +310,13 @@ func restoreBackup(ifName, containerID, backupPath string) error { } } + if config.TxQLen != 0 { + if err = changeTxQLen(ifName, config.TxQLen); err != nil { + err = fmt.Errorf("failed to restore transmit queue length: %v", err) + errStr = append(errStr, err.Error()) + } + } + if len(errStr) > 0 { return fmt.Errorf(strings.Join(errStr, "; ")) } @@ -346,7 +371,7 @@ func cmdAdd(args *skel.CmdArgs) error { } } - if tuningConf.Mac != "" || tuningConf.Mtu != 0 || tuningConf.Promisc || tuningConf.Allmulti != nil { + if tuningConf.Mac != "" || tuningConf.Mtu != 0 || tuningConf.Promisc || tuningConf.Allmulti != nil || tuningConf.TxQLen != 0 { if err = createBackup(args.IfName, args.ContainerID, tuningConf.DataDir, tuningConf); err != nil { return err } @@ -377,6 +402,12 @@ func cmdAdd(args *skel.CmdArgs) error { return err } } + + if tuningConf.TxQLen != 0 { + if err = changeTxQLen(args.IfName, tuningConf.TxQLen); err != nil { + return err + } + } return nil }) if err != nil { @@ -483,6 +514,13 @@ func cmdCheck(args *skel.CmdArgs) error { args.IfName, tuningConf.Allmulti, allmulti) } } + + if tuningConf.TxQLen != 0 { + if tuningConf.TxQLen != link.Attrs().TxQLen { + return fmt.Errorf("Error: Tuning configured Transmit Queue Length of %s is %d, current value is %d", + args.IfName, tuningConf.TxQLen, link.Attrs().TxQLen) + } + } return nil }) if err != nil { diff --git a/plugins/meta/tuning/tuning_test.go b/plugins/meta/tuning/tuning_test.go index 60ed13bb2..e9c5404f0 100644 --- a/plugins/meta/tuning/tuning_test.go +++ b/plugins/meta/tuning/tuning_test.go @@ -125,6 +125,7 @@ var _ = Describe("tuning plugin", func() { *beforeConf.Promisc = (link.Attrs().Promisc != 0) beforeConf.Allmulti = new(bool) *beforeConf.Allmulti = (link.Attrs().RawFlags&unix.IFF_ALLMULTI != 0) + beforeConf.TxQLen = link.Attrs().TxQLen return nil }) Expect(err).NotTo(HaveOccurred()) @@ -487,6 +488,148 @@ var _ = Describe("tuning plugin", func() { Expect(err).NotTo(HaveOccurred()) }) + It(fmt.Sprintf("[%s] configures and deconfigures tx queue len with ADD/DEL", ver), func() { + conf := []byte(fmt.Sprintf(`{ + "name": "test", + "type": "iplink", + "cniVersion": "%s", + "mtu": 20000, + "prevResult": { + "interfaces": [ + {"name": "dummy0", "sandbox":"netns"} + ], + "ips": [ + { + "version": "4", + "address": "10.0.0.2/24", + "gateway": "10.0.0.1", + "interface": 0 + } + ] + } + }`, ver)) + + args := &skel.CmdArgs{ + ContainerID: "dummy", + Netns: originalNS.Path(), + IfName: IFNAME, + StdinData: conf, + } + + err := originalNS.Do(func(ns.NetNS) error { + defer GinkgoRecover() + + r, _, err := testutils.CmdAddWithArgs(args, func() error { + return cmdAdd(args) + }) + Expect(err).NotTo(HaveOccurred()) + + result, err := types100.GetResult(r) + Expect(err).NotTo(HaveOccurred()) + + Expect(result.Interfaces).To(HaveLen(1)) + Expect(result.Interfaces[0].Name).To(Equal(IFNAME)) + Expect(result.IPs).To(HaveLen(1)) + Expect(result.IPs[0].Address.String()).To(Equal("10.0.0.2/24")) + + link, err := netlink.LinkByName(IFNAME) + Expect(err).NotTo(HaveOccurred()) + Expect(link.Attrs().TxQLen).To(Equal(20000)) + + if testutils.SpecVersionHasCHECK(ver) { + n := &TuningConf{} + err = json.Unmarshal(conf, &n) + Expect(err).NotTo(HaveOccurred()) + + confString, err := buildOneConfig(ver, n, r) + Expect(err).NotTo(HaveOccurred()) + + args.StdinData = confString + + err = testutils.CmdCheckWithArgs(args, func() error { + return cmdCheck(args) + }) + Expect(err).NotTo(HaveOccurred()) + } + + err = testutils.CmdDel(originalNS.Path(), + args.ContainerID, "", func() error { return cmdDel(args) }) + Expect(err).NotTo(HaveOccurred()) + + link, err = netlink.LinkByName(IFNAME) + Expect(err).NotTo(HaveOccurred()) + Expect(link.Attrs().TxQLen).To(Equal(beforeConf.TxQLen)) + + return nil + }) + Expect(err).NotTo(HaveOccurred()) + }) + + It(fmt.Sprintf("[%s] configures and deconfigures tx queue len from args with ADD/DEL", ver), func() { + conf := []byte(fmt.Sprintf(`{ + "name": "test", + "type": "iplink", + "cniVersion": "%s", + "args": { + "cni": { + "txQLen": 20000 + } + }, + "prevResult": { + "interfaces": [ + {"name": "dummy0", "sandbox":"netns"} + ], + "ips": [ + { + "version": "4", + "address": "10.0.0.2/24", + "gateway": "10.0.0.1", + "interface": 0 + } + ] + } + }`, ver)) + + args := &skel.CmdArgs{ + ContainerID: "dummy", + Netns: originalNS.Path(), + IfName: IFNAME, + StdinData: conf, + } + + err := originalNS.Do(func(ns.NetNS) error { + defer GinkgoRecover() + + r, _, err := testutils.CmdAddWithArgs(args, func() error { + return cmdAdd(args) + }) + Expect(err).NotTo(HaveOccurred()) + + result, err := types100.GetResult(r) + Expect(err).NotTo(HaveOccurred()) + + Expect(result.Interfaces).To(HaveLen(1)) + Expect(result.Interfaces[0].Name).To(Equal(IFNAME)) + Expect(result.IPs).To(HaveLen(1)) + Expect(result.IPs[0].Address.String()).To(Equal("10.0.0.2/24")) + + link, err := netlink.LinkByName(IFNAME) + Expect(err).NotTo(HaveOccurred()) + Expect(link.Attrs().TxQLen).To(Equal(20000)) + + err = testutils.CmdDel(originalNS.Path(), + args.ContainerID, "", func() error { return cmdDel(args) }) + Expect(err).NotTo(HaveOccurred()) + + link, err = netlink.LinkByName(IFNAME) + Expect(err).NotTo(HaveOccurred()) + Expect(link.Attrs().TxQLen).To(Equal(beforeConf.TxQLen)) + + return nil + }) + Expect(err).NotTo(HaveOccurred()) + }) + It(fmt.Sprintf("[%s] configures and deconfigures mac address (from conf file) with ADD/DEL", ver), func() { mac := "c2:11:22:33:44:55" conf := []byte(fmt.Sprintf(`{ @@ -780,7 +923,7 @@ var _ = Describe("tuning plugin", func() { Expect(err).NotTo(HaveOccurred()) }) - It(fmt.Sprintf("[%s] configures and deconfigures mac address, promisc mode and MTU (from conf file) with custom dataDir", ver), func() { + It(fmt.Sprintf("[%s] configures and deconfigures mac address, promisc mode, MTU and tx queue len (from conf file) with custom dataDir", ver), func() { conf := []byte(fmt.Sprintf(`{ "name": "test", "type": "iplink", @@ -788,6 +931,7 @@ var _ = Describe("tuning plugin", func() { "mac": "c2:11:22:33:44:77", "promisc": true, "mtu": 4000, + "txQLen": 20000, "dataDir": "/tmp/tuning-test", "prevResult": { "interfaces": [ @@ -834,6 +978,7 @@ var _ = Describe("tuning plugin", func() { Expect(link.Attrs().HardwareAddr).To(Equal(hw)) Expect(link.Attrs().Promisc).To(Equal(1)) Expect(link.Attrs().MTU).To(Equal(4000)) + Expect(link.Attrs().TxQLen).To(Equal(20000)) Expect("/tmp/tuning-test/dummy_dummy0.json").Should(BeAnExistingFile()) @@ -862,6 +1007,7 @@ var _ = Describe("tuning plugin", func() { Expect(link.Attrs().HardwareAddr.String()).To(Equal(beforeConf.Mac)) Expect(link.Attrs().MTU).To(Equal(beforeConf.Mtu)) Expect(link.Attrs().Promisc != 0).To(Equal(*beforeConf.Promisc)) + Expect(link.Attrs().TxQLen != 0).To(Equal(beforeConf.TxQLen)) return nil })