소켓 API는 SO_INCOMING_CPU
다음에 자세히 설명된 옵션을 제공합니다.매뉴얼 페이지:
SO_INCOMING_CPU (gettable since Linux 3.19, settable since Linux 4.4) Sets or gets the CPU affinity of a socket. Expects an integer flag. int cpu = 1; setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, sizeof(cpu)); Because all of the packets for a single stream (i.e., all packets for the same 4-tuple) arrive on the single RX queue that is associated with a particular CPU, the typical use case is to employ one listening process per RX queue, with the incoming flow being handled by a listener on the same CPU that is handling the RX queue. This provides optimal NUMA behavior and keeps CPU caches hot.
UDP 소켓을 생성하고 인터페이스와 데이터에 바인딩하는 서버가 있습니다 recv()
. 이 소켓을 얻고 싶습니다 SO_INCOMING_CPU
. 그게 가능합니까?
테스트 프로그램을 작성했는데 테스트 프로그램이 항상 -1을 반환합니다.
디버깅 을 했는데 문제가 소켓과 관련이 printk()
없는 것 같습니다 .inet_daddr
https://github.com/torvalds/linux/blob/v4.20-rc2/net/ipv4/udp.c#L1870
나는 이것이 의미가 있다고 생각합니다. UDP는 연결이 없으므로 소켓은 모든 주소에서 패킷을 수신할 수 있습니다. 소켓의 CPU 선호도는 4-튜플의 함수이므로 소켓이 반드시 고정된 CPU 선호도를 가질 필요는 없다는 내용을 어딘가에서 읽은 것 같습니다.
그런데 udp.c에 CPU Affinity를 초기화하는 코드가 있다는 걸 생각하면 뭔가 빠진 게 있지 않을까 싶었습니다.
SO_INCOMING_CPU
서버 측 UDP 소켓을 사용할 수 있는 방법이 있습니까 ?
내가 언급한 (약간 엉성한) 테스트 프로그램은 다음과 같습니다.
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
int main()
{
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("Error opening socket");
return 0;
}
struct sockaddr_in myaddr;
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(4242);
if (bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
#define BUFSIZE 20
unsigned char buf[BUFSIZE]; /* receive buffer */
struct sockaddr_in remaddr; /* remote address */
socklen_t addrlen = sizeof(remaddr); /* length of addresses */
int recvlen = recvfrom(sockfd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
sleep(1);
int cpu = 0;
socklen_t len = sizeof(cpu);
int ret = getsockopt(sockfd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, &len);
// Sample Output: Incoming CPU is -1 (ret = 0, recvlen = 5)
printf("Incoming CPU is %d (ret = %d, recvlen = %d)\n", cpu, ret, recvlen);
}