1 # Copyright 2015-2016 Intel Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 """VSPERF VSwitch implementation using DPDK and vhost ports
22 from src.ovs import OFBridge
23 from src.dpdk import dpdk
24 from conf import settings
25 from conf import get_test_param
26 from vswitches.ovs import IVSwitchOvs
28 class OvsDpdkVhost(IVSwitchOvs):
29 """ Open vSwitch with DPDK support
31 Generic OVS wrapper functionality in src.ovs is maximally used. This
32 class wraps DPDK system configuration along with DPDK specific OVS
35 The method docstrings document only considerations specific to this
36 implementation. For generic information of the nature of the methods,
41 super(OvsDpdkVhost, self).__init__()
42 self._logger = logging.getLogger(__name__)
46 # legacy DPDK configuration through --dpdk option of vswitchd
47 if self.old_dpdk_config():
48 vswitchd_args = ['--dpdk'] + settings.getValue('VSWITCHD_DPDK_ARGS')
49 if self._vswitchd_args:
50 self._vswitchd_args = vswitchd_args + ['--'] + self._vswitchd_args
52 self._vswitchd_args = vswitchd_args
55 """ Configure vswitchd DPDK options through ovsdb if needed
57 dpdk_config = settings.getValue('VSWITCHD_DPDK_CONFIG')
58 if dpdk_config and not self.old_dpdk_config():
59 # enforce calls to ovs-vsctl with --no-wait
60 tmp_br = OFBridge(timeout=-1)
61 for option in dpdk_config:
62 tmp_br.set_db_attribute('Open_vSwitch', '.',
63 'other_config:' + option, dpdk_config[option])
66 """See IVswitch for general description
68 Activates DPDK kernel modules, ovsdb and vswitchd.
71 super(OvsDpdkVhost, self).start()
72 # old style OVS <= 2.5.0 multi-queue enable
73 vswitch_dpdk_multi_queues = \
74 int(get_test_param('vswitch_dpdk_multi_queues', 0))
75 if vswitch_dpdk_multi_queues:
76 settings.setValue('VSWITCH_DPDK_MULTI_QUEUES', \
77 vswitch_dpdk_multi_queues)
78 if settings.getValue('OVS_OLD_STYLE_MQ') and \
79 int(settings.getValue('VSWITCH_DPDK_MULTI_QUEUES')):
80 tmp_br = OFBridge(timeout=-1)
81 tmp_br.set_db_attribute(
82 'Open_vSwitch', '.', 'other_config:' +
83 'n-dpdk-rxqs', settings.getValue('VSWITCH_DPDK_MULTI_QUEUES'))
86 """See IVswitch for general description
88 Kills ovsdb and vswitchd and removes DPDK kernel modules.
91 super(OvsDpdkVhost, self).stop()
94 def add_switch(self, switch_name, params=None):
95 """See IVswitch for general description
97 switch_params = ['--', 'set', 'bridge', switch_name, 'datapath_type=netdev']
99 switch_params = switch_params + params
101 super(OvsDpdkVhost, self).add_switch(switch_name, switch_params)
102 if settings.getValue('VSWITCH_AFFINITIZATION_ON') == 1:
103 # Sets the PMD core mask to VSWITCH_PMD_CPU_MASK
104 # for CPU core affinitization
105 self._bridges[switch_name].set_db_attribute('Open_vSwitch', '.',
106 'other_config:pmd-cpu-mask',
107 settings.getValue('VSWITCH_PMD_CPU_MASK'))
109 def add_phy_port(self, switch_name):
110 """See IVswitch for general description
112 Creates a port of type dpdk.
113 The new port is named dpdk<n> where n is an integer starting from 0.
115 bridge = self._bridges[switch_name]
116 dpdk_count = self._get_port_count('type=dpdk')
117 port_name = 'dpdk' + str(dpdk_count)
118 params = ['--', 'set', 'Interface', port_name, 'type=dpdk']
121 if int(settings.getValue('VSWITCH_DPDK_MULTI_QUEUES')) and \
122 not settings.getValue('OVS_OLD_STYLE_MQ'):
123 params += ['options:n_rxq={}'.format(
124 settings.getValue('VSWITCH_DPDK_MULTI_QUEUES'))]
125 of_port = bridge.add_port(port_name, params)
126 return (port_name, of_port)
128 def add_vport(self, switch_name):
129 """See IVswitch for general description
131 Creates a port of type dpdkvhost
132 The new port is named dpdkvhost<n> where n is an integer starting
135 bridge = self._bridges[switch_name]
136 vhost_count = self._get_port_count('type=dpdkvhostuser')
137 port_name = 'dpdkvhostuser' + str(vhost_count)
138 params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhostuser']
140 if int(settings.getValue('VSWITCH_DPDK_MULTI_QUEUES')) and \
141 not settings.getValue('OVS_OLD_STYLE_MQ'):
142 params += ['options:n_rxq={}'.format(
143 settings.getValue('VSWITCH_DPDK_MULTI_QUEUES'))]
144 of_port = bridge.add_port(port_name, params)
146 return (port_name, of_port)
149 def old_dpdk_config():
150 """Checks if ovs-vswitchd uses legacy dpdk configuration via --dpdk option
152 :returns: True if legacy --dpdk option is supported, otherwise it returns False
155 ovs_vswitchd_bin = settings.getValue('TOOLS')['ovs-vswitchd']
157 subprocess.check_output(ovs_vswitchd_bin + r' --help | grep "\-\-dpdk"', shell=True)
159 except subprocess.CalledProcessError: