16기 리눅스 커널 스터디 C조 main.c 의 start kernel 소스 분석중
cgroup_init_early(); 호출 부분
linux/kernel/cgroup/cgroup.c
int __init cgroup_init_early(void) 함수를 살펴보다가
RCU_INIT_POINTER(init_task.cgroups, &init_css_set);
함수 내부의
rcu_check_sparse(p, __rcu);
/home/kim/linux-1/include/linux/rcupdate.h 부분의 매크로를 살펴보는 도중에
#define rcu_check_sparse(p, space) \
((void)(((typeof(*p) space *)p) == p))
(typeof(*p) space *) 부분에서
1. space * 부분이 잘 이해가 되지 않습니다.
2. bool 값을 void 로 캐스팅하는 것이 RCU_INIT_POINTER 함수의 기능에서 어떤 맥락인지 문의드립니다.
그리고 kernel/cgroup/cgroup.c
static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)mutex_lock(&cgroup_mutex);
함수 부분에서
mutex_lock(&cgroup_mutex);
...
mutex_unlock(&cgroup_mutex);
3. 뮤텍스 락/언락 하는 부분이 나오는데, 해당 부분에서 뮤텍스를 사용하는 이유가 궁금합니다.
.
안녕하세요? 문c블로그(http://jake.dothome.co.kr)의 문영일입니다.
1. space * 부분이 잘 이해가 되지 않습니다.
-> 컴파일 타임에 에러 체크를 하기 위해 사용되는 sparse 정적 분석 툴입니다.
gcc 기능을 사용하여 체크를 하는 것으로 런타임 시에는 영향을 주지 않습니다.
RCU를 사용할 때 space 인자에는 __rcu가 사용됩니다. 이 매크로는 다음과 같은 gcc 명령을 사용합니다.
rcu를 사용하는 주소들은 일반 포인터와 다른 주소 공간을 사용하는 것으로 명시하여 컴파일 타임에
사용자가 실수로 다른 주소 공간을 사용하는 포인터를 rcu에서 사용하는 경우 에러를 발생하게 합니다.
# define __rcu __attribute__((noderef, address_space(4)))
참고: http://jake.dothome.co.kr/sparse/
2. bool 값을 void 로 캐스팅하는 것이 RCU_INIT_POINTER 함수의 기능에서 어떤 맥락인지 문의드립니다.
-> 위의 sparse 정적 툴은 런타임에 영향을 주지 않습니다. 그냥 컴파일 타임에 체크만 하려는 목적이므로,
void로 처리합니다.
3. 뮤텍스 락/언락 하는 부분이 나오는데, 해당 부분에서 뮤텍스를 사용하는 이유가 궁금합니다.
-> cgroup_init_subsys() 함수는 cgroup_init_early() 와 cgroup_init() 두 곳에서 사용됩니다.
그 중 cgroup_init()은 인터럽트가 enable된 상황에서도 사용되고 스케줄러가 동작 중인 상태에서도
사용됩니다. 따라서 자료 구조 보호 목적으로 mutex lock을 사용한다고 생각하시면 됩니다.
참고: http://jake.dothome.co.kr/mutex/
수고하세요.