When you are writing a linux application that needs either kernel to userspace communications or userspace to kernel communications, the typical answer is to use ioctl and sockets.
当您编写需要内核到用户空间通信或用户空间到内核通信的 Linux 应用程序时,典型的答案是使用 ioctl 和套接字。
This is a simple mechanism for sending information down from userspace into the kernel to make requests for info, or to direct the kernel to perform an operation on behalf of the userspace application.
这是一种简单的机制,用于将信息从用户空间向下发送到内核以发出信息请求,或指示内核代表用户空间应用程序执行操作。
A good example of this type of communications between a userspace application and the kernel can be found in the venerable ethtool
config application. Here the tool itself is a userspace application that communicates via sockets to the kernel. The kernel contains the API that the application uses to perform the communications.
用户空间应用程序和内核之间这种类型的通信的一个很好的例子可以在古老的 ethtool 配置应用程序中找到。这里的工具本身是一个用户空间应用程序,它通过套接字与内核进行通信。内核包含应用程序用来执行通信的 API。
Setting a NICs channels 设置网卡通道
Let’s look at an example usecase of ethtool with a modern multi-queue network interface (NIC). Modern NICs have the hardware and ability to use multiple channels for sending & receiving packets. These take advantage of multi-core CPUs to balance the load of transmitting (Tx) and receiving (Rx) traffic. Historically all the traffic (and associated interrupts) was handled by a single core, spreading the workload across multiple cores can significantly improve performance.
让我们看一下带有现代多队列网络接口 (NIC) 的 ethtool 的示例用例。现代 NIC 具有使用多个通道发送和接收数据包的硬件和能力。它们利用多核 CPU 来平衡传输 (Tx) 和接收 (Rx) 流量的负载。从历史上看,所有流量(和相关中断)都由单个内核处理,将工作负载分散到多个内核可以显着提高性能。
How would we set the combined
channel number on a NIC that supports the feature using ioctl
?
我们如何在支持使用 ioctl 的功能的 NIC 上设置组合通道号?
代码语言:javascript复制#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <linux/ethtool.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <linux/sockios.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
typedef struct example_ethtools_channels example_ethtools_channels_t;
struct example_ethtools_channels
{
unsigned int num_rx_channels; /**< Number of rx channels */
unsigned int num_tx_channels; /**< Number of tx channels */
unsigned int num_other_channels; /**< Number of other channels */
unsigned int num_combined_channels; /**< Number of combined channels */
};
size_t string_strlcpy(char *dst, const char *src, size_t size)
{
size_t len;
len = strlen(src);
if (len > size)
len = size;
memcpy(dst, src, len);
dst[len] = '