2009-05-31 5 views
5

에 가장 적합한 리눅스 커널 잠금 장치의 새로운 기능 :나는이 시나리오에 대한 잠금 문제를 해결하기 위해 필요한 특정 시나리오

  1. 멀티 CPU 시스템.
  2. 모든 CPU는 공통 (소프트웨어) 리소스를 사용합니다.
  3. 리소스에 대한 읽기 전용 액세스는 매우 일반적입니다. (들어오는 네트워크 패킷 처리)
  4. 쓰기 액세스가 훨씬 덜 빈다. (꽤 많은 설정 변경 만 가능).

현재 read_lock_bh, write_lock_bh (스핀 록) 메커니즘을 사용합니다. 문제는 CPU가 많을수록 라이터 컨텍스트에서 소프트 락업이 더 많이 발생한다는 것입니다.

this book, 의 동시성 장을 읽었지만 스핀 록을 사용할 때 독자 또는 작성자가 우선 순위를 얻게되는지 여부를 이해할 수 없습니다.

그래서 질문은 다음과 같습니다

  1. 우선 순위를 그들의 리더/라이터/아무도 리눅스 스핀 록 메커니즘주지합니까?
  2. 내 현재 솔루션을 사용하면서 잠금을 얻으려고 시도 할 때마다 필자의 시나리오에서 그러한 잠김을 피하기 위해 사용할 수있는 더 나은 메커니즘이 있습니까? 아니면 작가에게 우선 순위를 부여 할 수있는 방법일까요?

감사합니다, Nir 씨

+0

이 질문에 대한 답을 모르겠지만 "Linux 커널 이해하기"책에는 이런 유형의 정보가 많이 있습니다. 정말로 훌륭한 책입니다. 커널 작업을하는 사람은 누구나 읽을 수 있어야합니다. – Zifre

+0

커널 동시성 내부에 대해 많이 알지는 못하지만 리더기/기록기 카운팅으로 자신 만의 롤링을 구현하고 writer-wait에서 잠금을 설정할 수 있습니다. –

+0

@Nir 4 년 만에 드디어 답을 받아 줘서 다행입니다. –

답변

5

여기에는 Essential Linux Device Drivers의 직접적인 인용문이 나와 있습니다. 그것은 당신이 관심이 무엇을 할 수 끝에 RCU를 다루는 부분을 보인다.

리더 라이터 잠금

또 다른 전문 동시성 규제 메커니즘 스핀 락의 리더 라이터 변종이다. 중요 섹션의 사용이 별도의 스레드가 공유 데이터 구조를 읽거나 쓸 수 있지만 을 수행하지 않는 경우 이러한 잠금은 자연스럽게 맞습니다. 다중 판독기 스레드는 중요한 영역 내부에서 동시에 허용됩니다. 다음과 같이 리더 스핀 록이 정의 :

rwlock_t myrwlock = RW_LOCK_UNLOCKED; 

read_lock(&myrwlock);    /* Acquire reader lock */ 
/* ... Critical Region ... */ 
read_unlock(&myrwlock);   /* Release lock */ 

그러나 작가 스레드가 임계 영역을 입력하면, 다른 독자 또는 작가 스레드 내부에 허용되지 않습니다. 작가 스핀 락을 사용하려면이 작성합니다 리더 라이터 스핀 록의 실제 예를 들어 net/ipx/ipx_route.c에서 IPX 라우팅 코드 현재

rwlock_t myrwlock = RW_LOCK_UNLOCKED; 

write_lock(&myrwlock);   /* Acquire writer lock */ 
/* ... Critical Region ... */ 
write_unlock(&myrwlock); /* Release lock */ 

봐. ipx_routes_lock이라는 읽기/쓰기 기 록은 IPX 라우팅 테이블을 동시 액세스로부터 보호합니다.패킷을 전달하기 위해 라우팅 테이블을 검색해야하는 스레드 은 판독기 잠금을 요청합니다. 추가해야 할 스레드 또는 라우팅 테이블에서 항목을 삭제하면 작성자 잠금이 획득됩니다. 일반적으로 라우팅 테이블 조회보다 훨씬 많은 라우팅 테이블 조회 인스턴스가 있기 때문에 성능이 향상됩니다.

일반 스핀 락과 마찬가지로, 독자 작가 잠금 장치는 IRQ에 해당하는이 변종을 - 즉, read_lock_irqsave(), read_lock_irqrestore(), write_lock_irqsave()write_lock_irqrestore(). 이러한 기능의 의미는 일반 스핀 록의 기능과 유사합니다.

2.6 커널에 도입 된 시퀀스 잠금 또는 seqlocks는 판독기가 독자보다 선호되는 판독기 기록기 잠금입니다. 이것은 변수에 대한 쓰기 조작이 읽기 액세스보다 많은 경우에 유용합니다. 예를 들어이 장의 앞부분에서 설명한 jiffies_64 변수입니다. Writer 스레드는 내부에있을 수있는 독자를 중요한 부분으로 기다리지 않습니다. 이 때문에, 리더 스레드가 임계 영역 내부에 자신의 항목이 를 실패하고 다시 시도해야 할 수도 있음을 발견 할 수 있습니다

u64 get_jiffies_64(void) /* Defined in kernel/time.c */ 
{ 
    unsigned long seq; 
    u64 ret; 
    do { 
     seq = read_seqbegin(&xtime_lock); 
     ret = jiffies_64; 
    } while (read_seqretry(&xtime_lock, seq)); 
    return ret; 
} 

작가가 write_seqlock()write_sequnlock()을 사용하여 중요한 지역을 보호합니다.

2.6 커널라는 또 다른 메커니즘을 도입 읽기 복사 업데이트 (RCU), 하는 수율이 개선 성능을 때 리더까지 작가 능가하다. 기본 아이디어는 판독기 스레드가 잠금없이 실행될 수 있다는 것입니다. 작성자 스레드는 더 복잡합니다. 이들은 데이터 구조의 복사본에 대한 업데이트 작업을 수행하고 독자가 보는 포인터를 바꿉니다. 원래의 복사본은 모든 CPU의 다음 컨텍스트 스위치가 으로 바뀔 때까지 모든 진행중인 읽기 작업이 완료되도록 유지됩니다. 지금까지 논의 된 프리미티브를 사용하는 것보다 RCU를 사용하는 것이 더 복잡하므로 작업에 적합한 도구라고 확신하는 경우에만 사용해야합니다. RCU 데이터 구조 및 인터페이스 함수는 include/linux/rcupdate.h에 정의되어 있습니다. Documentation/RCU/*에는 충분한 문서가 있습니다.

RCU 사용 예의 경우 fs/dcache.c을 참조하십시오. Linux에서 각 파일은 디렉터리 항목 (dentry라는 구조체에 저장 됨), 메타 데이터 정보 (inode에 저장 됨) 및 실제 데이터 (데이터 블록에 저장 됨)과 연결됩니다. 파일을 실행할 때마다 파일 경로의 구성 요소가 파싱되고 에 해당하는 덴트 리를 얻습니다. dentries는 dcache라는 데이터 구조에 캐시 된 채 유지되어 은 향후 작업 속도를 높입니다. dcache 룩업의 수는 dcache 업데이트보다 훨씬 많기 때문에 dcache에 대한 참조는 RCU 프리미티브를 사용하여 보호됩니다.

0

잠금을 보유하는 동안 당신이 할 일이 당신이 정상 뮤텍스, 비 독자 작가를 시도 할 수 있습니다 작은 경우. 더 효율적입니다.

+0

멀티 CPU 머신을 가지고 있다는 점이 그리워합니다. 이렇게하면 단일 CPU 시스템만큼 유용합니다. – Nir

3

RCU가 처리하도록 설계된 사용 사례가 아닌가요? 그것의 쓰기에 좋은 기록을 위해 http://lwn.net/Articles/262464/를보십시오.

+0

제가 언급 한 책에서 RCU에 관해 읽었습니다. 문제는 제가 이해하는 바와 같이 한 명의 작가를 위해 설계된 것입니다. 나는 더 가질 수있다. 게다가, 나는 그것이 작동하기 위해서 내 아키텍쳐를 바꾸어야한다고 생각한다. 그래도 고마워. (모두 업데이트 한 다음 포인터 만 교체하십시오.) – Nir

관련 문제