mirror of
https://github.com/openvswitch/ovs
synced 2025-08-23 10:28:00 +00:00
125 lines
3.5 KiB
C
125 lines
3.5 KiB
C
|
/*
|
||
|
* Copyright (c) 2021 Intel Corporation.
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at:
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#include <config.h>
|
||
|
|
||
|
#include "dpif-netdev-private-dpif.h"
|
||
|
#include "dpif-netdev-private-thread.h"
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "openvswitch/dynamic-string.h"
|
||
|
#include "openvswitch/vlog.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
VLOG_DEFINE_THIS_MODULE(dpif_netdev_impl);
|
||
|
|
||
|
enum dpif_netdev_impl_info_idx {
|
||
|
DPIF_NETDEV_IMPL_SCALAR,
|
||
|
DPIF_NETDEV_IMPL_AVX512
|
||
|
};
|
||
|
|
||
|
/* Actual list of implementations goes here. */
|
||
|
static struct dpif_netdev_impl_info_t dpif_impls[] = {
|
||
|
/* The default scalar C code implementation. */
|
||
|
[DPIF_NETDEV_IMPL_SCALAR] = { .input_func = dp_netdev_input,
|
||
|
.probe = NULL,
|
||
|
.name = "dpif_scalar", },
|
||
|
|
||
|
#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__)
|
||
|
/* Only available on x86_64 bit builds with SSE 4.2 used for OVS core. */
|
||
|
[DPIF_NETDEV_IMPL_AVX512] = { .input_func = dp_netdev_input_outer_avx512,
|
||
|
.probe = dp_netdev_input_outer_avx512_probe,
|
||
|
.name = "dpif_avx512", },
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
static dp_netdev_input_func default_dpif_func;
|
||
|
|
||
|
dp_netdev_input_func
|
||
|
dp_netdev_impl_get_default(void)
|
||
|
{
|
||
|
/* For the first call, this will be NULL. Compute the compile time default.
|
||
|
*/
|
||
|
if (!default_dpif_func) {
|
||
|
int dpif_idx = DPIF_NETDEV_IMPL_SCALAR;
|
||
|
|
||
|
/* Configure-time overriding to run test suite on all implementations. */
|
||
|
#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__)
|
||
|
#ifdef DPIF_AVX512_DEFAULT
|
||
|
dp_netdev_input_func_probe probe;
|
||
|
|
||
|
/* Check if the compiled default is compatible. */
|
||
|
probe = dpif_impls[DPIF_NETDEV_IMPL_AVX512].probe;
|
||
|
if (!probe || !probe()) {
|
||
|
dpif_idx = DPIF_NETDEV_IMPL_AVX512;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
VLOG_INFO("Default DPIF implementation is %s.\n",
|
||
|
dpif_impls[dpif_idx].name);
|
||
|
default_dpif_func = dpif_impls[dpif_idx].input_func;
|
||
|
}
|
||
|
|
||
|
return default_dpif_func;
|
||
|
}
|
||
|
|
||
|
/* This function checks all available DPIF implementations, and selects the
|
||
|
* returns the function pointer to the one requested by "name".
|
||
|
*/
|
||
|
static int32_t
|
||
|
dp_netdev_impl_get_by_name(const char *name, dp_netdev_input_func *out_func)
|
||
|
{
|
||
|
ovs_assert(name);
|
||
|
ovs_assert(out_func);
|
||
|
|
||
|
uint32_t i;
|
||
|
|
||
|
for (i = 0; i < ARRAY_SIZE(dpif_impls); i++) {
|
||
|
if (strcmp(dpif_impls[i].name, name) == 0) {
|
||
|
/* Probe function is optional - so check it is set before exec. */
|
||
|
if (dpif_impls[i].probe) {
|
||
|
int probe_err = dpif_impls[i].probe();
|
||
|
if (probe_err) {
|
||
|
*out_func = NULL;
|
||
|
return probe_err;
|
||
|
}
|
||
|
}
|
||
|
*out_func = dpif_impls[i].input_func;
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
int32_t
|
||
|
dp_netdev_impl_set_default_by_name(const char *name)
|
||
|
{
|
||
|
dp_netdev_input_func new_default;
|
||
|
|
||
|
int32_t err = dp_netdev_impl_get_by_name(name, &new_default);
|
||
|
|
||
|
if (!err) {
|
||
|
default_dpif_func = new_default;
|
||
|
}
|
||
|
|
||
|
return err;
|
||
|
|
||
|
}
|