본문 바로 가기

CS/Linux8

리눅스는 어떻게 TLB Flush를 최적화할까? 들어가며오늘은 TLB(Translation Lookaside Buffer), 그리고 컨텍스트 스위칭(Context Switch) 과정에서 발생하는 TLB Flush 최적화에 대한 주제로 글을 작성했습니다. 애플리케이션의 성능을 이야기할 때 흔히 DB 쿼리, API 응답 속도 등을 떠올리지만, 그 아래에는 운영체제와 하드웨어가 벌이는 수많은 최적화 노력이 숨어있습니다. 오늘은 그중 하나인 TLB 최적화의 여정을 리눅스 커널 코드와 인텔 CPU 아키텍처 문서를 통해 함께 따라가 보겠습니다.😤 이론 배경: 가상 메모리와 TLB본격적인 이야기에 앞서, 몇 가지 핵심 개념을 가볍게 짚고 넘어가겠습니다.가상 메모리(Virtual Memory)와 페이징(Paging)현대 운영체제는 각 프로세스에게 독립적인 메모리 ..
[Linux] epoll의 내부 동작 방식 들어가며전통적인 select나 poll 방식은 감시할 파일 디스크립터(FD)가 많아질수록 성능이 저하되는 O(N)의 한계를 가집니다. 하지만 epoll은 이러한 단점을 극복하고, 감시 대상의 수에 관계없이 O(1)의 시간 복잡도로 이벤트 발생을 감지할 수 있게 해줍니다. 이번 시간에는 리눅스의 대표적인 I/O 멀티플렉싱 메커니즘, epoll의 내부 동작 원리를 함께 살펴보겠습니다. 먼저 recv()는 어떻게 잠들고 깨어날까? 를 보고 오시면 비슷한 메커니즘 이기때문에, 더 잘이해가 갈 수 있습니다. 커널 코드의 모든 세부사항을 다루기보다는, epoll이 어떤 아이디어로 설계되었고, 주요 함수들이 어떻게 상호작용하는지 명확하게 이해하는 것을 목표로 합니다.😃 이론: epoll, 무엇이 다른가?epoll의..
[Linux] recv()는 어떻게 잠들고 깨어날까? 들어가며소켓 프로그래밍에 대해 공부를 하다 recv 함수의 동작 방식에 대해 궁금증이 생겼습니다. recv 를 하는 아래와 같은 코드를 한번 봅시다.while ((str_len = recv(client_sock, buffer, BUFFER_SIZE - 1, 0)) > 0) { buffer[str_len] = '\0'; printf("Received from client: %s\n", buffer);}이 코드를 실행하면, recv() 함수는 CPU를 전부 점유하며 무한 루프를 돌지 않습니다. 기본적으로 블로킹(blocking) 상태로 동작하며, CPU를 점유하지 않고 마치 "잠들어" 있는 것처럼 대기합니다. 그러다가 소켓에 데이터가 도착하면, recv() 함수는 "깨어나서" 데이터를 읽어 st..
[Linux] 네트워크 커널 스택: 리눅스 커널 네트워크 패킷 수신 여정 #3 들어가며이전 글에서는 NAPI(New API)를 통해 네트워크 인터페이스 카드(NIC)에서 수신한 패킷이 커널의 네트워크 스택으로 본격적으로 진입하기 직전까지의 과정을 살펴보았습니다. 이번 글에서는, 패킷이 커널 네트워크 스택의 상위 계층으로 전달되어 최종적으로 TCP 애플리케이션 레벨 소켓의 수신 버퍼(receive buffer)에 안착하기까지의 여정을 상세히 추적해 보겠습니다.리눅스 커널의 실제 소스 코드를 기반으로 설명하지만, 방대한 코드를 모두 담을 수는 없어 많은 부분을 생략하고 개념적으로 추상화했습니다. 따라서 각 함수나 로직의 더욱 깊은 내부 동작이 궁금하시다면, 본문에 링크된 소스 코드를 직접 보시는 것을 강력히 추천합니다.환경- 커널: 리눅스 5.15- 프로토콜: TCP/IPv4- 상황:..
[Linux] Ring Buffer 에서 NAPI: 리눅스 커널 네트워크 패킷 수신 여정 #2 들어가며지난 글에서는 NIC로 들어온 패킷이 CPU와 직접 통신하지 않고 Ring Buffer라는 중간 저장소로 먼저 전송되는 과정에 대해 이야기했습니다. 이번 글에서는 Ring Buffer에 도착한 패킷이 어떤 과정을 거쳐 리눅스 커널의 네트워크 스택으로 전달되는지 그 여정을 함께 따라가 보겠습니다.리눅스 커널 코드를 직접 살펴보며 그 흐름을 파악할 것이지만, 방대한 코드의 모든 세부 사항을 다루기보다는 핵심적인 흐름을 이해하는 데 초점을 맞출 예정입니다. 따라서 많은 생략과 추상화가 포함되어 있음을 미리 알려드립니다. 글을 읽으시면서 더 깊은 의문이나 궁금증이 생긴다면, 직접 커널 코드를 추적 해보시는 것을 강력히 추천합니다!환경- NIC : Intel X710 시리즈- 커널 : Linux 5.15 ..
[Linux] NIC에서 링 버퍼까지: 리눅스 커널 네트워크 패킷 수신 여정 #1 들어가며우리가 매일 사용하는 서버 애플리케이션은 수많은 네트워크 요청을 처리합니다. 그렇다면 이 요청들, 즉 네트워크 패킷은 서버의 네트워크 카드(NIC)에 도착해서부터 우리가 작성한 애플리케이션 코드까지 어떤 경로를 거쳐 전달될까요?위 그림은 패킷이 NIC에서 애플리케이션까지 도달하는 전체 여정을 추상화한 것입니다. 이번 글에서는 첫 번째 관문, NIC에서 커널 메모리의 링 버퍼(Ring Buffer)까지 데이터가 이동하는 과정에 대해 자세히 살펴보겠습니다.환경- NIC : Intel X710 시리즈- 커널 : Linux 5.15☕️ 핵심 구성 요소: NIC, DMA, 그리고 링 버퍼데이터 수신 과정을 이해하기 위해 먼저 세 가지 핵심 구성 요소를 알아야 합니다.NIC (Network Interface..
[Linux] 페이지 테이블 구조 리눅스에서 페이지 테이블이 어떻게 구성되어 있는지 알아보자.환경리눅스 커널 5.15 버전, x86_64 기준🌵 페이지 테이블 구조테이블 매핑 방식은 4가지가 존재한다.직접 매핑연관 매핑집합-연관 매핑역매핑해시형 테이블 구조그중, 리눅스는 직접 매핑방식 중, 계층적 페이지 테이블을 사용한다.계층적 페이지 테이블은 아래 그림을 보면 직관적으로 이해 할 수 있다.64bit 를 나누어서, 각각을 offset 으로 사용하는 방식이다.리눅스에서는 디폴트로 다음과 같이 4단계로 페이지 테이블을 구성한다.PGD (Page Global Directory)PUD (Page Upper Directory)PMD (Page Middle Directory)PTE (Page Table Entry)pgtable_64_types.h..
시스템 콜과 표준 라이브러리 관계 파헤치기: glibc는 어떻게 시스템 콜을 호출할까? 들어가며"표준 라이브러리는 커널 기능을 사용하기 위한 것" "시스템 콜은 커널 기능을 위한 인터페이스"라는 말을 모두 들어보셨을 겁니다. 언뜻 보면 비슷해 보이는 두 개념, 과연 어떤 차이가 있고 어떻게 연결되어 있을까요? 저도 이 부분이 헷갈려서 직접 파헤쳐 보기로 했습니다."표준 라이브러리는 시스템 콜을 좀 더 편리하게 사용할 수 있게 해준다" 정도로 알고 있었지만, 실제로는 좀 더 구체적인 역할을 하고 있었습니다. 리눅스에서 시스템 콜을 호출하려면 특정 레지스터에 값을 설정해야 하는데, 이러한 복잡한 작업을 glibc와 같은 표준 라이브러리가 대신 처리해줍니다.이제 대표적인 표준 라이브러리인 glibc의 read 함수가 실제로 어떻게 시스템 콜을 호출하는지 살펴보겠습니다.📌 TL;DR (요약)✅ ..