1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

lib/socket: autodetect RSS using ETHTOOL_GRXRINGS

This is also used as part of 'ethtool -n rdma14' and
'ethtool -x rdma14'.

;#> ethtool -n rdma14
8 RX rings available
rxclass: Cannot get RX class rule count: Operation not supported
RX classification rule retrieval failed

;#> ethtool -x rdma14
RX flow hash indirection table for rdma14 with 8 RX ring(s):
    0:      0     1     2     3     4     5     6     7
    8:      0     1     2     3     4     5     6     7
RSS hash key:
Operation not supported
RSS hash function:
    toeplitz: on
    xor: off
    crc32: off

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Stefan Metzmacher 2020-05-07 11:06:03 +02:00
parent 4ccb581609
commit d39636acea

View File

@ -170,6 +170,42 @@ static void query_iface_speed_from_name(const char *name, uint64_t *speed)
}
*speed = ((uint64_t)ethtool_cmd_speed(&ecmd)) * 1000 * 1000;
done:
(void)close(fd);
}
static void query_iface_rx_queues_from_name(const char *name,
uint64_t *rx_queues)
{
int ret = 0;
struct ethtool_rxnfc rxcmd;
struct ifreq ifr;
int fd;
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (fd == -1) {
DBG_ERR("Failed to open socket.");
return;
}
if (strlen(name) >= IF_NAMESIZE) {
DBG_ERR("Interface name too long.");
goto done;
}
ZERO_STRUCT(ifr);
strlcpy(ifr.ifr_name, name, IF_NAMESIZE);
ifr.ifr_data = (void *)&rxcmd;
ZERO_STRUCT(rxcmd);
rxcmd.cmd = ETHTOOL_GRXRINGS;
ret = ioctl(fd, SIOCETHTOOL, &ifr);
if (ret == -1) {
goto done;
}
*rx_queues = rxcmd.data;
done:
(void)close(fd);
}
@ -217,6 +253,7 @@ static int _get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
/* Loop through interfaces, looking for given IP address */
for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) {
uint64_t if_speed = 1000 * 1000 * 1000; /* 1Gbps */
uint64_t rx_queues = 1;
if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
continue;
@ -278,9 +315,13 @@ static int _get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
#ifdef HAVE_ETHTOOL
query_iface_speed_from_name(ifptr->ifa_name, &if_speed);
query_iface_rx_queues_from_name(ifptr->ifa_name, &rx_queues);
#endif
ifaces[total].linkspeed = if_speed;
ifaces[total].capability = FSCTL_NET_IFACE_NONE_CAPABLE;
if (rx_queues > 1) {
ifaces[total].capability |= FSCTL_NET_IFACE_RSS_CAPABLE;
}
if (strlcpy(ifaces[total].name, ifptr->ifa_name,
sizeof(ifaces[total].name)) >=