커널이 시스템 호출을 처리하는 동안 잠자기 상태일 수 있는 경우 실행은 어떻게 시스템 호출로 돌아가나요?

커널이 시스템 호출을 처리하는 동안 잠자기 상태일 수 있는 경우 실행은 어떻게 시스템 호출로 돌아가나요?

나는 Robert Love의 "Linux Kernel Development"를 읽고 있었는데 그는 시스템 호출이 프로세스의 맥락에서 실행되고 잠자기 상태가 될 수 있다고 썼습니다. 현재 포인터는 시스템 호출을 발행한 프로세스인 현재 작업을 가리킵니다.

내가 이해하지 못하는 것은 시스템 호출이 잠자기 상태일 때 실행이 어떻게 시스템 호출로 돌아가는가입니다. 프로세스 컨텍스트에서 실행 중인 경우 깨우고 다시 예약할 수 있지만 사용자 프로세스는 커널 공간에서 실행할 수 없습니다. 시스템 호출이 호출되면 커널은 해당 시스템 호출을 실행하기 위한 작업/프로세스를 생성합니까? 사용자 공간의 시스템 호출로 인해 트랩이 커널 모드로 전환되고 해당 시스템 호출이 실행된다는 것을 알고 있지만, 이 글을 읽기 전에는 시스템 호출이 잠자기 및 일정 변경이 불가능하다고 가정했지만 그렇게 할 수 있어야 하는 이유를 이해합니다.

답변1

핵심 부분은 이렇습니다.

사용자 프로세스는 커널 공간에서 실행될 수 없습니다

이것은 정확하지 않습니다. Robert Love가 시스템 호출이 프로세스 컨텍스트에서 실행된다고 쓴 것은 기본적으로 프로세스가 시스템 호출을 실행하기 위해 커널 모드에서 실행되고 있음을 의미합니다. 커널이 시스템 호출을 처리할 때 여전히 호출 프로세스인 프로세스에서 실행 중입니다. 일정을 변경하기로 결정하면 프로세스가 일시 중지되고 예약된 다른 프로세스 중에서 실행이 계속됩니다.

일시 중단된 프로세스가 재개되면 커널 모드에서 시스템 호출을 계속 실행합니다.

2.6 스케줄링의 큰 변화 중 하나는 이전에는 사용자 모드에서만 프로세스를 중단할 수 있다는 점입니다. 이제는 사용자 모드에서만 프로세스를 중단할 수 있습니다. 선점형 커널을 사용하면 커널 모드에서 프로세스가 중단될 수도 있습니다(커널 코드의 중요한 부분에서 수행되는 선점을 비활성화하지 않는 한).

답변2

사용자 프로세스는 커널 공간에서 실행될 수 없으므로 독자를 혼동하지 마십시오. 작업이 무엇이든, read(), ioctl() 또는 기타 다른 작업이든 libc를 거쳐 "syscall" 어셈블리 명령(x86_64)으로 끝납니다. 이로 인해 커널 공간에 대한 브리지인 sw 인터럽트가 발생하고 핸들러가 완료되면 제어권을 사용자 공간으로 반환합니다.

관련 정보