그래서 저는 Python 프런트엔드를 작성하는 데 필요한 사용자 정의 커널 모듈을 사용하고 있습니다. 커널 모듈이 작동하고 여기에 프레임버퍼 장치 파일을 추가합니다 /dev/fb1
. 잘 읽고 쓸 수 있습니다. 저는 Python의 mmap
모듈을 사용하여 장치 버퍼를 매핑했는데 잘 작동하는 것 같습니다.
이제 나는 numpy를 구현하려고 하고 있으며 numpy의 memmap 함수를 사용하고 있습니다. 내 가정은 그것이 비슷한 방식으로 작동해야 한다는 것입니다. 문제는 numpy의 memmap 기능을 사용하여 장치 파일을 열면 커널이 중단된다는 것입니다.
처음 파일을 열었을 때 했던 작업은 다음과 같습니다.
self.surface = np.memmap(dev, dtype=np.uint16, mode='r+', shape=(320,240))
프로세스가 중단되고 killall python
파일 리소스를 열어 두는 경우를 제외하고는 Python을 종료할 수 없습니다. 파일을 다시 열기 위한 후속 액세스는 무기한 중단됩니다. 다음을 수행하십시오.
f = open('/dev/fb1', 'r+b')
나는 이것을 dmesg로 얻습니다
[ 1081.480104] INFO: task python2.6:2834 blocked for more than 120 seconds.
[ 1081.480109] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 1081.480113] python2.6 D 0000000100004eec 0 2834 1 0x00000004
[ 1081.480118] ffff88020a175db8 0000000000000086 0000000000000000 0000000000015980
[ 1081.480122] ffff88020a175fd8 0000000000015980 ffff88020a175fd8 ffff88022b69adc0
[ 1081.480127] 0000000000015980 0000000000015980 ffff88020a175fd8 0000000000015980
[ 1081.480131] Call Trace:
[ 1081.480142] [<ffffffff81049b17>] ? mutex_spin_on_owner+0x97/0xc0
[ 1081.480148] [<ffffffff81589477>] __mutex_lock_slowpath+0xf7/0x180
[ 1081.480151] [<ffffffff8158935b>] mutex_lock+0x2b/0x50
[ 1081.480157] [<ffffffff812f3bcf>] fb_release+0x1f/0x60
[ 1081.480161] [<ffffffff81154825>] __fput+0xf5/0x210
[ 1081.480164] [<ffffffff81154965>] fput+0x25/0x30
[ 1081.480168] [<ffffffff81123d35>] remove_vma+0x45/0x90
[ 1081.480171] [<ffffffff81126179>] do_munmap+0x309/0x3a0
[ 1081.480174] [<ffffffff81126266>] sys_munmap+0x56/0x80
[ 1081.480180] [<ffffffff8100a0f2>] system_call_fastpath+0x16/0x1b
[ 1081.480183] INFO: task ipython:2856 blocked for more than 120 seconds.
[ 1081.480185] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 1081.480187] ipython D ffff880256e92018 0 2856 1841 0x00000000
[ 1081.480191] ffff88022341fb58 0000000000000086 ffffffff81625f10 0000000000015980
[ 1081.480196] ffff88022341ffd8 0000000000015980 ffff88022341ffd8 ffff88022b7c16e0
[ 1081.480200] 0000000000015980 0000000000015980 ffff88022341ffd8 0000000000015980
[ 1081.480204] Call Trace:
[ 1081.480207] [<ffffffff81589477>] __mutex_lock_slowpath+0xf7/0x180
[ 1081.480210] [<ffffffff8158935b>] mutex_lock+0x2b/0x50
[ 1081.480214] [<ffffffff812f3cd8>] fb_open+0xc8/0x200
[ 1081.480217] [<ffffffff8115657d>] ? cdev_get+0x2d/0xb0
[ 1081.480221] [<ffffffff81156e6a>] chrdev_open+0x10a/0x200
[ 1081.480225] [<ffffffff810878a1>] ? in_group_p+0x31/0x40
[ 1081.480228] [<ffffffff81156d60>] ? chrdev_open+0x0/0x200
[ 1081.480232] [<ffffffff811512c5>] __dentry_open+0xe5/0x330
[ 1081.480237] [<ffffffff81260e4f>] ? security_inode_permission+0x1f/0x30
[ 1081.480240] [<ffffffff81151624>] nameidata_to_filp+0x54/0x70
[ 1081.480244] [<ffffffff8115e398>] finish_open+0xe8/0x1d0
[ 1081.480248] [<ffffffff8116701f>] ? dput+0xdf/0x1b0
[ 1081.480251] [<ffffffff8115f7f6>] do_last+0x86/0x460
[ 1081.480254] [<ffffffff81161b2b>] do_filp_open+0x21b/0x660
[ 1081.480259] [<ffffffff8112117f>] ? handle_mm_fault+0x32f/0x440
[ 1081.480263] [<ffffffff8116d33a>] ? alloc_fd+0x10a/0x150
[ 1081.480266] [<ffffffff81151069>] do_sys_open+0x69/0x170
[ 1081.480270] [<ffffffff811511b0>] sys_open+0x20/0x30
[ 1081.480273] [<ffffffff8100a0f2>] system_call_fastpath+0x16/0x1b
제 질문은 시스템 호출을 수동으로 종료할 수 있습니까?입니다. 아니면 어떻게든 뮤텍스를 잠금 해제할 수 있나요? 아니면 오류가 알려주는 내용을 완전히 놓치고 있습니다.
이상하게도 memmap 호출만으로도 프레임 버퍼가 손상되고 내 모니터에 쓰레기가 기록됩니다. 나는 장치 파일을 잘 처리하지 못하는 것이 numpy라고 생각합니다.
고쳐 쓰다:
이것은 ps -l의 출력입니다. 첫 번째 파이썬은 원래 numpy 호출을 실행한 파이썬입니다 memmap
(적어도 저는 확신합니다). 두 번째 ipython은 첫 번째 프로세스가 중단된 후 간단한 일반 Python 공개 호출을 실행하는 것입니다.
0 D 1000 2834 1 0 80 0 - 22101 fb_rel ? 00:00:00 python2.6
0 D 1000 2856 1841 0 80 0 - 15065 fb_ope pts/1 00:00:00 ipython
답변1
스택 추적은 이전 Python 명령이 스핀 잠금에 걸려 종료 시 뮤텍스를 해제하려고 시도했음을 보여줍니다(치명적인 오류 포함). POSIX에서는 뮤텍스를 입력한 스레드와 다른 스레드에서 뮤텍스를 해제할 수 없다고 명시합니다. 다음 단계는 종료 시 뮤텍스가 유지되도록 하는 리소스가 무엇인지 알아내는 것입니다. 에서:
linux-source-2.6.38/kernel/mutex.c:
69 * The mutex must later on be released by the same task that
70 * acquired it. Recursive locking is not allowed. The task
71 * may not exit without first unlocking the mutex. Also, kernel
72 * memory where the mutex resides mutex must not be freed with
73 * the mutex still locked. The mutex must first be initialized
74 * (or statically defined) before it can be locked. memset()-ing
75 * the mutex to 0 is not allowed.
Python을 추적하거나 드라이버에서 dtrace를 활성화하여 시작할 수 있습니다.