IT/디바이스드라이버

20. 다중 프로세스 환경의 디바이스 드라이버

피치 크러쉬 2015. 11. 10. 10:38
300x250


20. 다중 프로세스 환경의 디바이스 드라이버.pptx


20. 다중 프로세스 환경의 디바이스 드라이버


목차

1. 단일 프로세스를 위한 디바이스 드라이버

2. 프로세스별 관련 처리

3. 비선점형 커널의 경우

4. 선점형 커널의 경우


1. 단일 프로세스를 위한 디바이스 드라이버


개요

다중 프로세스 환경의 디바이스 드라이버
리눅스는 다중 프로세스 환경을 제공 함

문제점
드라이버 제작시 여러 프로세스가 동시에 접근할 가능성이 있음

해결책
재진입 가능한 함수 형태로 디바이스 드라이버를 제작

디바이스 파일을 열었을 때 각 프로세스에 따른 처리 구현


단일 프로세스의 경우

하나의 프로세스만 사용하는 시스템
e.g., 임베디드 시스템
다중 프로세스를 고려할 필요 없음
실행 중 다른 프로세스에서의 접근 문제 해결 방법
드라이버를 프로세스 하나가 독점하게 만듦
디바이스를 열었을때(open()) 관리

static xxx_reopen = 0;
int xxx_open (struct inode *inode, struct file *filp)
{
  if(xxx_reopen) return –EBUSY;

  xxx_reopen = 1;
  :
  return 0;
}

int xxx_release(struct inode *inode, struct file *filp)
{

  :
  xxx_reopen = 0;

  return 0;

}




2. 프로세스별 관련 처리

여러 프로세스를 사용하는 시스템

프로세스별 데이터 관리
문제점
재진입 문제
입출력 처리를 위한 데이터구조의 접근
해결책
프로세스마다 데이터를 따로 관리하는 것이 좋
Open()함수로부터 전달된 file ->private_data 필드를 이용



프로세스별 데이터 관리


프로세스 재진입
문제점
하나의 디바이스 드라이버를 여러 프로세스에서 사용할 경우 문제 발생
A(밑의)xxx_read()를 수행중 => B프로세스가 xxx_read()를 시도
 => 변수의 초기화 => 원래 목적을 이루지 못함.
원인
전역변수의 사용

int xxx_cnt = 0;
ssize_t xxx_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
  xxx_cnt = 0;
  while(xxx_cnt <10)

  {
  interruptible_sleep_on(&waitQueue_read);
  }

  return 0;
}

해결방법
함수 내부에서 전역변수 사용 변경
int xxx_cnt = 0;
ssize_t xxx_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
  int local_cnt = 0;
  int old_cnt = xxx_cnt;


 
while(local_cnt  < 10)
  {
  interruptible_sleep_on(&waitQueue_read
);
  local_cnt += (xxx_cnt – old_cnt);

  }
  return 0;
}


3. 비선점형 커널의 디바이스 드라이버

4. 선점형 커널의 디바이스 드라이버

선점형 커널의 I/O 처리
I/O처리의 연속성 문제


프로세스 재진입
해결책
선점형 커널의 특성을 정지시키거나 다시 부여하는 함수를 사용
#include <linux/preempt.h> 내부의
preempt_enable() : 선점 카운터 감소
preempt_disable() : 선점 카운터 증가
get_cpu() : smp_processor_id() + preempt_disable()
put_cpu() : preempt_enable()

(smp_processor_id()는 현재 실행중인 CPU 번호를 반환)


선점형 커널의 재진입 처리
해결책
프로세스 재진입과 관련하여 준수할 내용
하드웨어 관련 제어 변수들은 전역 변수로 만든다
부 번호에 관련되어 사전에 할당되는 구조체들은 전역변수로 만든다
단독으로 사용되는 인터럽트 서비스에서 사용하는 변수들을 전역변수로 만든다

함수 내부에서만 사용되는 변수들은 지역 변수로 만든다
프로세스마다 따로 관리해야 하는 변수들은 file -> private_data 필드 변수에 할당한다

하드웨어와 연동되는 대기 큐는 전역변수로 만든다
프로세스에 연동되는 대기 큐는 file -> private_data 필드 변수에 할당한다

디바이스 드라이버 전체에 대해 동일하게 동작하는 데이터 구조들은 전역 변수로 만든다








반응형