을 사용하여 커널 모듈에 큰 메모리를 할당하려고합니다 vmalloc()
. 64GB 램을 사용하는 64 비트 Linux (3.10.0-514.2.2.el7.x86_64)에서 2GB 이상의 메모리를 할당 할 수 없습니다.
다음은 관련 코드 부분입니다.
...
static int logical_block_size = 512;
module_param(logical_block_size, int, 0);
static int nsectors = 1024; /* How big the drive is */
module_param(nsectors, int, 0);
...
/*
* The internal representation of our device.
*/
static struct sbd_device {
unsigned long size;
spinlock_t lock;
u8 *data;
struct gendisk *gd;
} Device;
...
static int __init sbd_init(void) {
/*
* Set up our internal device.
*/
Device.size = nsectors * logical_block_size;
spin_lock_init(&Device.lock);
Device.data = vmalloc(Device.size);
...
를 통해 할당 할 수있는 메모리 크기에 제한이 vmalloc
있습니까? 커널 모듈에 많은 양의 메모리를 할당하는 다른 방법이 있습니까?
여기에서 코드를 참조하십시오. 주석의 Simple Block Driver 는 질문에 답하는 데 필수적입니다.
그 이유는 16 엑사 바이트 의 데이터 를 할당하려고하기 때문입니다 . 이 계산 sbd_init()
은 이유입니다.
Device.size = nsectors * logical_block_size;
Device.size는 unsigned long
모듈 매개 변수 nsectors
이며 logical_block_size
정수입니다.
이제 locgical_block_size를로 설정 1024
하고 nsectors를로 설정 하면 2097152
(총 2GB 공간) 계산이 부호있는 정수 로 수행 되므로 결과는 다음과 같습니다.
1024 * 2097152 = -2147483648
이것이 암시 적으로 unsigned long
(Device.size에 대한 할당에 의해 ) 캐스트되면 결과는 (아마도) 물리적 메모리와 vmalloc 예약 영역 (linux x86_64에서 32TB)을 약간 초과하는으로 18446744071562067968
전달됩니다 vmalloc()
.
해결책은 다음과 같이 계산을 수행하는 것입니다 unsigned long
.
Device.size = (unsigned long) nsectors * logical_block_size;
그러면 예상대로 작동합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다