LINUX.ORG.RU

Memory


0

0

Можно ли в user_space выделить блок памяти функцией malloc, а потом по user_space адресу этого блока в модуле ядра получить физический адрес user_space блока, сделать для него SetPageReserved, и после передать физический адрес блока для mmap? P. S. Неначем попробовать пока. Спасибо.


лучше не надо, будет плохо. и для какого (кем выполняемого)
mmap вы собираетесь его передавать? и зачем?

похоже, вам нужна get_user_pages().

idle ★★★★★
()

Долго пытался понять, чего хочет автор. Могу только констатировать, что у меня не получилось.

Есть желание страницу процесса открыть в другом процессе через mmap() на /dev/mem? А зачем?

Murr ★★
()
Ответ на: комментарий от Murr

Извиняюсь за туманность формулирвки. Задача состоит в следующем: (Этот вариант реализован) 1) Нужно выделить память для DMA в режиме Bus mastering на PCI шине. Сейчас память выделяется в ядре. Процесс через ioctl сообщает модулю ядра о желании получить данные по DMA. Модуль выделяет блоки памяти и передает адреса этих блоков назад процессу. После чего процесс делает для этих блоков mmap(). После запускает DMA и считывает данные напрямую из этих блоков.

2) Меня интересует второй вариант (о котором я уже писал вначале), когда память для блоков выделяется в user_space, а драйвер только делает для нее SetPageReserved, остальное как и в 1). Ядро 2.4.х. Спасибо.

karak
() автор топика
Ответ на: комментарий от karak

> Модуль выделяет блоки памяти и передает адреса этих блоков
> назад процессу.

вообще-то, он не должен передавать адрес процессу, он долже
нпередавать файл/смещение.

> а драйвер только делает для нее SetPageReserved

еще раз - не делайте этого, будет плохо. и еще раз еще раз:
get_user_pages(). не забывайте только, что это память не
непрерывна с точки зрения физических адресов.

посмотрите как работает direct IO.

idle ★★★★★
()
Ответ на: комментарий от idle

>передавать файл/смещение
Согласен. Это и имелось ввиду. Выделял память pci_alloc_consistent(),
а она вроде как непрерывный сегмент выделяет.

> не забывайте только, что это память не непрерывна с точки зрения 
> физических адресов

Т. е. получается что malloc() выделяет виртуально непрерывный блок, который физически может (и скорее всего разрывен) и => я протру 
что-то важное...
    
Кстати не посмотрите код, для резервирования страниц в памяти от swapping. А то после 10-20 запусков pci_alloc_consistent() говорит
что нет больше памяти. Код прилагаю. Спасибо.

static int lock_pages( void *va, u32 size )
{
	int j=0; 
	
	struct page *start_page_addr = virt_to_page( va );
		
	spin_lock(&init_mm.page_table_lock);
	for (j=0; j < (size >> PAGE_CACHE_SHIFT); j++) {
		SetPageReserved((start_page_addr+j));
		//printk("<0> start_page_addr[%i] = 0x%X\n", j, (int)(start_page_addr+j) );
	}
	spin_unlock(&init_mm.page_table_lock);	
	//set lock status;
		
	return 0;	
} 

//--------------------------------------------------------------------

static int unlock_pages( void *va, u32 size )
{
	int j=0; 
	
	struct page *start_page_addr = virt_to_page( va );
	
	spin_lock(&init_mm.page_table_lock);		
	for (j=0; j < (size >> PAGE_CACHE_SHIFT); j++) {
		ClearPageReserved((start_page_addr+j));
		//printk("<0> start_page_addr[%i] = 0x%X\n", j, (int)(start_page_addr+j) );
	}
	spin_unlock(&init_mm.page_table_lock);
	//clear lock status

	return 0;	
}

karak
() автор топика
Ответ на: комментарий от karak

ну почему вы так упорно цепляеетесь за SetPageReserved ???

ну не тот это интерефейс! все (ну, почти), что вы можете
получить - это временно остановить ->count счетчик, вам
это _не_ надо.


>	spin_lock(&init_mm.page_table_lock);

при чем здесь init_mm? вам нужен task->mm, и не забудьте
про mm semaphore.

>	for (j=0; j < (size >> PAGE_CACHE_SHIFT); j++) {

перепрыгиваете через vma, это неправильно.

>		SetPageReserved((start_page_addr+j));

c чего вы взяли, что эта страница имеет хоть какое-то
отношение к вашему процессу ???

даже если бы имела, что будет после того, как процесс
сделает fork() ?  даже если вы начнете правильно находить
страницы, что если процесс _только_ что сделал fork()
и страница write protected для cow?

да миллион еще причин, почему это неверно, дальше не читал.

idle ★★★★★
()
Ответ на: комментарий от idle

idle:
>ну почему вы так упорно цепляеетесь за SetPageReserved ???
>ну не тот это интерефейс!
 Если честно, то кроме LDD я ничего не читал, ну еще немного 
исходники просматривал, поэтому прошу Вас помочь в этом, т.к.
я не знаю какой должен быть интерфейс. Ядро у меня 2.4.х.

>и не забудьте про mm semaphore
 Что нужно с ним сделать?

>перепрыгиваете через vma, это неправильно.
 Если подскажете какой-нибудь пример, где это реализовано
так как нужно, буду очень признателен.
 Еще раз спасибо.

karak
() автор топика
Ответ на: комментарий от karak

Я детально не вчитывался. Если идея такая: выделить память, пометить ее reserved, организовать на ней ввод-вывод, через экспортируемый драйвером mmap интерфейс сделать remap pages, то по идее это работать будет.

Только зачем так сложно? Чтобы избежать синхронности direct I/O?

Murr ★★
()
Ответ на: комментарий от karak

> поэтому прошу Вас помочь в этом, т.к. я не знаю какой должен
> быть интерфейс.

ну ведь я уже вам 3 раза говорил, get_user_pages() !!!

она специально для этого и сделана. она гарантирует что
все страницы в диапазоне populated (как это по-русски?),
что их не стащит swapper, что write в этот регион не
вызовет COW и так далее.

я не могу понять, что вам не понятно.

другое дело, что я согласен с тем, что Murr говорит.
зачем все это делать? пусть лучше драйвер управляет dma
буфером и предоставляет доступ через mmap.

idle ★★★★★
()
Ответ на: комментарий от idle

Вариант о котором говорит Murr мной реализован. 
Попробую разобраться с
get_user_pages(). Но мне кажется что в 2.4.х этого
интерфейса нет. Если есть пример использования
get_user_pages(), то буду очень признателен. 

   Еще раз Спасибо...

karak
() автор топика
Ответ на: комментарий от Murr

Murr:
Идея такая, она даже работает. Мы как-то обсуждали 
с Вами вопрос выделения боьшого объема памяти для DMA. 
Это все оттуда и пляшет.

karak
() автор топика
Ответ на: комментарий от karak

get_user_pages в 2.4 есть. И в упомянутом generic direct I/O есть даже пример его применения. ;) Ищите аккуратно в mm. ;)

Murr ★★
()
Ответ на: комментарий от Murr

Я сначала написал... а потом посмотрел :-)) 
Даже начинаю понимать что-то. А поподробнее
о generic direct I/O можете рассказть или
указать где это посмотреть можно?
  Спасибо.

karak
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.