LINUX.ORG.RU

Kernel BUG


0

0

В логе:
----------------------------------------------------------------
kernel BUG at mm/rmap.c:487!
invalid operand: 0000 [#2]
PREEMPT SMP
EIP is at page_remove_rmap+0x39/0x50
..................
<1>Fixing recursive fault but reboot is needed!
----------------------------------------------------------------

Ошибка происходит в функции page_remove_rmap в строке
BUG_ON(page_mapcount(page)).

Я так понимаю, что это связано с моей какой-то некорректной работой со страницами, скорей всего их резервированием, поэтому привожу куски кода работы с выделением памяти:

1. Отображение PCI-регистров в пространство процесса:
volatile static struct page *start_page_addr, *conf_page_addr;
phys_addr=pci_resource_start(dev, 3);
base_addr=(unsigned int*)ioremap_nocache(phys_addr, 256<<2);
conf_page_addr=virt_to_page(base_addr);
SetPageReserved(conf_page_addr);
............. Работаю
При завершении работы:
ClearPageReserved(conf_page_addr);

2. Выделение памяти для данных:
npag = (((Data_Size)<<2)/(PAGE_SIZE)) + 1;
dma_addr=(unsigned int*)pci_alloc_consistent(dev[LID],((DataSize)<<2),dma_addr_t*) &dma_buff_phys);
start_page_addr = virt_to_page(dma_addr);
for(i=0;i<npag;i++) {SetPageReserved(start_page_addr+i);}
............. Работаю
При завершении работы:
for(i=0;i<npag;i++) {ClearPageReserved(start_page_addr+i);}
pci_free_consistent((struct pci_dev *)dev, ((Data_Size)<<2),dma_addr, dma_buff_phys);

Непонятно, почему возникает ошибка. Вроде делаю все правильно, смотрел в исходниках сетевух - практически тоже самое. Подскажите, как правильно сделать (что исправить), и , если можно, привидите кусок кода работающего и ткните, где об этом почитать можно. LDD читал,
.../Documentation читал, но что-то не совсем получается. Ошибка,кстати, не постояноо выскакивает, а где-то раз на 5-10 пусков.



> Ошибка происходит в функции page_remove_rmap в строке
> BUG_ON(page_mapcount(page)).

ошибка в том, что эта функция вообще не должна видеть
ваши Reserved страницы.

вы уже пару раз здесь спрашивали (если не ошибаюсь) об
mmap в user-space, но, похоже, ответы вы игнорируете.

в любом случае, по приведенному фрагменту кода понять
ничего нельзя.

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

> вы уже пару раз здесь спрашивали (если не ошибаюсь)

Не ошибаетесь. Но конкретных ответов так и не получил. Может плохо спрашивал. Попробую еще:

Нужно выделить область памяти для приема/передачи данных по DMA.
В ядре:
1. Выделяю память по IOCTL (процесс вызывает ioctl и передает размер массива данных - Data_Size):
npag = (((Data_Size)<<2)/(PAGE_SIZE)) + 1; Количество необходимых страниц
dma_addr=(unsignedint*)pci_alloc_consistent(dev[LID],((DataSize)<<2),
dma_addr_t*) &dma_buff_phys); Получаю начальный адресс
start_page_addr = virt_to_page(dma_addr);
for(i=0;i<npag;i++) {SetPageReserved(start_page_addr+i);} Резервирую страницы.
2. В процессе:
dma_buff=(unsigned int *) mmap(0, (Data_Size)<<2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)dma_off);
где, dma_off = dma_buff_phys, переданный физ. адрес из ядра.

В ядре обработчик mmap():
off = vma->vm_pgoff << PAGE_SHIFT;
vsize = vma->vm_end - vma->vm_start;
physical = off; vma->vm_flags |= VM_RESERVED;
io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), vsize, vma->vm_page_prot);

Все. Сейчас я беру dma_buff и пишу/читаю.
По окончании работы, в ядре делаю:
for(i=0;i<npag;i++) {ClearPageReserved(start_page_addr+i);}
pci_free_consistent(dev, ((Data_Size)<<2),dma_addr, dma_buff_phys);

Все. Больше с памятью я ничего не делаю!!!!
Вопросы:
1. Правильно ли я делаю выделение, резервирование и отображение памяти ? Если что-то не так, то подскажите, что и где и , если не трудно, покажите как надо и где почитать.
2. Может не все делаю. Что-то еще может надо. ТОж подскажите что.
3. Может надо еще какой-нибудь фрагмент кода привести, пояснить что-нибудь, что конкретно Вы понять не можете ???

Спасибо.





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

> что конкретно Вы понять не можете ???

я ничего ваабще с таким форматированием понять
не могу.

ну зачем вы еще и замусориваете ваш пост ненужными
деталями, его и так невозможно читать.

> Выделяю память по IOCTL (процесс вызывает ioctl и передает
> размер массива данных - Data_Size):

ключевая деталь?

> for(i=0;i<npag;i++) {SetPageReserved(start_page_addr+i);}
> Резервирую страницы.

а что бы это еще могло означать, по вашему?

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

> я ничего ваабще с таким форматированием понять не могу.

Ну не знаю. У меня в броузере все нормально видно, каждая ф-ция с новой строчки, все рядами и колоннами.

> ну зачем вы еще и замусориваете ваш пост ненужными
деталями, его и так невозможно читать.

Вы сказали, что вам ничего не понятно, поэтому я и пытаюсь объяснить наиболее подробно. Если бы вы сказали, что вам не понято то-то и то-то или уточнить что-то конкретно, тогда и я бы конкретно ответил и не было бы мусора.

> ключевая деталь?

процесс вызывает ioctl и передает размер массива данных - Data_Size драйверу, который и выделяет память заданного размера.

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

Вот наверное та отформатировать,

Нужно выделить область памяти для приема/передачи данных по DMA.
В ядре:
1. Выделяю память по IOCTL (процесс вызывает ioctl и передает размер массива данных - Data_Size):
npag = (((Data_Size)<<2)/(PAGE_SIZE)) + 1; Количество необходимых страниц
dma_addr=(unsignedint*)pci_alloc_consistent(dev[LID],((DataSize)<<2),
dma_addr_t*) &dma_buff_phys); Получаю начальный адресс
start_page_addr = virt_to_page(dma_addr);
for(i=0;i<npag;i++) {SetPageReserved(start_page_addr+i);} Резервирую страницы.
2. В процессе:
dma_buff=(unsigned int *) mmap(0, (Data_Size)<<2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)dma_off);
где, dma_off = dma_buff_phys, переданный физ. адрес из ядра.

В ядре обработчик mmap():
off = vma->vm_pgoff << PAGE_SHIFT;
vsize = vma->vm_end - vma->vm_start;
physical = off; vma->vm_flags |= VM_RESERVED;
io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), vsize, vma->vm_page_prot);

Все. Сейчас я беру dma_buff и пишу/читаю.
По окончании работы, в ядре делаю:
for(i=0;i<npag;i++) {ClearPageReserved(start_page_addr+i);}
pci_free_consistent(dev, ((Data_Size)<<2),dma_addr, dma_buff_phys);

Все. Больше с памятью я ничего не делаю!!!!
Вопросы:
1. Правильно ли я делаю выделение, резервирование и отображение памяти ? Если что-то не так, то подскажите, что и где и , если не трудно, покажите как надо и где почитать.
2. Может не все делаю. Что-то еще может надо. ТОж подскажите что.
3. Может надо еще какой-нибудь фрагмент кода привести, пояснить что-нибудь, что конкретно Вы понять не можете ???

Спасибо. 

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

Вот наверное та отформатировать,

Нужно выделить область памяти для приема/передачи данных по DMA.
В ядре:

1. Выделяю память по IOCTL (процесс вызывает ioctl и передает размер массива данных - Data_Size):
    npag = (((Data_Size)<<2)/(PAGE_SIZE)) + 1; Количество необходимых страниц
    dma_addr=(unsignedint*)pci_alloc_consistent(dev[LID],((DataSize)<<2),
dma_addr_t*) &dma_buff_phys); Получаю начальный адресс
    start_page_addr = virt_to_page(dma_addr);
    for(i=0;i<npag;i++) { SetPageReserved(start_page_addr+i); } Резервирую страницы.

2. В процессе:
    dma_buff=(unsigned int *) mmap(0, (Data_Size)<<2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)dma_off);
    где, dma_off = dma_buff_phys, переданный физ. адрес из ядра.

В ядре обработчик mmap():
    off = vma->vm_pgoff << PAGE_SHIFT;
    vsize = vma->vm_end - vma->vm_start;
    physical = off; vma->vm_flags |= VM_RESERVED;
    io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), vsize, vma->vm_page_prot);

Все. Сейчас я беру dma_buff и пишу/читаю.

По окончании работы, в ядре делаю:
    for(i=0;i<npag;i++) {ClearPageReserved(start_page_addr+i);}
    pci_free_consistent(dev, ((Data_Size)<<2),dma_addr, dma_buff_phys);

Все. Больше с памятью я ничего не делаю!!!!

Вопросы:
1. Правильно ли я делаю выделение, резервирование и отображение памяти ? Если что-то не так, то подскажите, что и где и , если не трудно, покажите как надо и где почитать.
2. Может не все делаю. Что-то еще может надо. ТОж подскажите что.
3. Может надо еще какой-нибудь фрагмент кода привести, пояснить что-нибудь, что конкретно Вы понять не можете ???

Спасибо. 

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

я здесь многое не понимаю, напр зачем Data_Size
умножается на 4 и с чего это вы вдруг решили, что
npag нужно считать именно таким (явно неправильным)
образом.

> (dma_addr_t*) &dma_buff_phys

ну неправильно это, это opaque handle, нельзя предполагать,
что это физический адрес, да и не нужен он вам здесь...

> В ядре обработчик mmap():
> off = vma->vm_pgoff << PAGE_SHIFT;
> physical = off;

поздравляю. вы решили сделать новую (расширенную) реализацию
/dev/mem, только не очень правильную.

вам нужно передавать offset "внутри" вашего dma буфера, и
проверять что не вышли за его границы. про физический его
адрес user-level не должен знать ничего.

очень может быть, что здесь и проблема, куда-то вы промахиваетесь.

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

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

> я здесь многое не понимаю, напр зачем Data_Size умножается на 4

Т.к. размер передается не в байтах, а в 32-битных словах.

> и с чего это вы вдруг решили, что npag нужно считать именно таким >(явно неправильным)образом.

Я не решил, а предположил, что надо так:
Если у меня NNN байт, а размер страницы PAGE_SIZE, то я тупо предполагаю, что мне понадобиться NNN/PAGE_SIZE+1 страница. Ну подскажите тогда, как правильно или хотя бы намекните, а то прямо говорить вы как-то нехотите :)))

> поздравляю. вы решили сделать новую (расширенную) реализацию
> /dev/mem, только не очень правильную.

Опять же :))) намекните куда двинуться, чтоб было правильно ну и не 
/dev/mem.

> про физический его адрес user-level не должен знать ничего

А он ничего и не знает
off = vma->vm_pgoff << PAGE_SHIFT;
physical = off; vma->vm_flags |= VM_RESERVED;
io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), vsize, vma->vm_page_prot);
У меня здесь off прямо и передается, физического адресса здесь нет.
Это вся ф-ци mmap, больше ничего нет!

> вам нужно передавать offset "внутри" вашего dma буфера

Совсем не понял. Если я пишу в DMA буфер из юзер процесса write(fd,dma_buff,SIZE), то откуда мне брать dma_buff. Как внутри передать ???

> в дальнейшем приводите код полностью.

Я вам все полностью привел: ф-цию mmap, как в ядре так и в юзер процесее. И выделение памяти в ядре для DMA. Ни о каких страницах кода и речи нет.... :)))

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

> > я здесь многое не понимаю, напр зачем Data_Size умножается на 4
>
> Т.к. размер передается не в байтах, а в 32-битных словах.

ну и зачем же вам портить вид и без того небезупречного кода?
ну вот зачем функции alloc() или как она у вас наызвается знать,
что размер передается в словах? она должна работать с количеством
байт или страниц. это лирика, конечно, но желания смотреть на код
не прибавляет.

> > и с чего это вы вдруг решили, что npag нужно считать именно таким > >(явно неправильным)образом.
>
> Я не решил, а предположил, что надо так:
> Если у меня NNN байт, а размер страницы PAGE_SIZE, то я тупо
> предполагаю, что мне понадобиться NNN/PAGE_SIZE+1 страница. Ну
> подскажите тогда, как правильно или хотя бы намекните, а то прямо
> говорить вы как-то нехотите :)))

намекаю. пусть NNN == PAGE_SIZE. pci_alloc_consistent() вернет
вам именно эту одну страничку. а по вашей замечательной логике
npag будет == 2, и вы поставите Reserved странице, которая к
вашему драйверу никакого отношения не имеет. ну ведь это же
просто арифметика, ..., ладно не буду ничего говорить.

> > про физический его адрес user-level не должен знать ничего
>
> А он ничего и не знает
> off = vma->vm_pgoff << PAGE_SHIFT;
> physical = off; vma->vm_flags |= VM_RESERVED;
> io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), vsize, vma->vm_page_prot);
> У меня здесь off прямо и передается, физического адресса здесь нет.

ну а off откуда ????????? у вас ->vm_pgoff указывает (фактически)
физический адрес памяти, на который делается mmap! то есть, процесс
может легко сделать mmap на любую область памяти в системе!
а вы должны разрешать ему доступ только к вашему буферу, и ->vm_pgoff
(последний параметр user-space mmap) должен указывать смещение
в этом буфере.

> Я вам все полностью привел: ф-цию mmap, как в ядре так и в юзер
> процесее.

а где тогда проверки на ошибки?

> Ни о каких страницах кода и речи нет.... :)))

ну так и покажите их полностью, будет же намного легче читать.

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

>  пусть NNN == PAGE_SIZE. pci_alloc_consistent() вернет вам именно эту > одну страничку

А пусть NNN<PAGE_SIZE,  или NNN/PAGE_SIZE=1.2, тогда что, еще кучу проверок вводить ? Я со всоим подсчетом страниц "пролетаю" тока когда NNN=k*PAGE_SIZE, ну и что? эта одна лишняя страничка мне как-то жизнь испортит ? Просто мне показалось, что так как-то удобней. Хотя, если это Fatal ERROR, тогда.... :)

> поздравляю. вы решили сделать новую (расширенную) реализацию
> /dev/mem, только не очень правильную.

Судя по поздравлениям :) я пошел не тем путем в способе выделения и отображения памяти в user-space, наверное устаревшим. Ну так намекните на другой, более правильный и современный. Ядро у меня 2.6.14, так что думаю все новые веяния уловлю :)

>  ->vm_pgoff указывает (фактически)
> физический адрес памяти, на который делается mmap! ......

Т.е. на всю доступную физ. память в системе ?

> а вы должны разрешать ему доступ только к вашему буферу, и 
>  ->vm_pgoff (последний параметр user-space mmap) должен указывать 
> смещение  в этом буфере.

Так откуда мне брать это смещение !!!???? Я его сейчас беру из 
pci_alloc_consistent(dev,((DataSize)<<2), (dma_addr_t*) &dma_buff_phys); 
т.е. dma_buff_phys передаю в user-level и там использую в mmap в качестве offset'a.

Вот привожу код:
------------------------- user-level ----------------------------
int main(int argc, char *argv[]) {
struct dma_st srv_dma_st; Структура параметров DMA (размер, направление и т.д.) Передается драйверу.

srv_dma_st.nnblk = nnBlk;
srv_dma_st.blkSz = blkSz;
dmap = (unsigned int)&srv_dma_st;

if((err=ioctl(fd, SETT_DMA, &dmap))<0) {printf("SRV : ERROR : SETUP DMA \n"); smsg=-1;}
      else{................. 

}
------------------------------------------------------------------
Сейчас обработчик  ioctl(... SETT_DMA, .....) 
***************** kernel**********************
  case SETT_DMA:
    get_user(srvp,(unsigned int*)arg); 
    mod_dma_stp = (struct dma_st *)srvp;
    copy_from_user(mod_dma_stp, (struct dma_st*)mod_dma_stp, 16);
    npag = (((mod_dma_stp->blkSz)<<2)/(PAGE_SIZE)) + 1;
    trn_dir = mod_dma_stp->dir;
    dma_addr =  (unsigned int*)pci_alloc_consistent(dev, ((mod_dma_stp->blkSz)<<2),(dma_addr_t*) &dma_buff_phys);
    start_page_addr = virt_to_page(dma_addr);
    for(i=0;i<npag;i++) {SetPageReserved(start_page_addr+i);}
    mod_dma_stp->dma_bf = dma_buff_phys; 
    result = copy_to_user(mod_dma_stp, mod_dma_stp, 16);
//------- Последние 2 строчки - передача полученного физ. адреса процессу, для использования в mmap в качестве offset
********************************************
Далее в user-level
------------------------- user-level ----------------------------
.....
     else{
	  dma_buff = (unsigned int *) mmap(0, (srv_dma_st.blkSz)<<2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)srv_dma_st.dma_bf);
if(dma_buff==-1) {return -1;}

Вот и все дальше контроллер программирую и делаю - 
 read/write(fd, dma_buff, SIZE)
------------------------------------------------------------------






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

Ах да, mmap в ядре забыл
***************** kernel**********************
static int drv_mmap (struct file *filp, struct vm_area_struct *vma) {

  unsigned long physical, off, vsize, psize;

  off = vma->vm_pgoff << PAGE_SHIFT;
  vsize = vma->vm_end - vma->vm_start;
  physical = off; vma->vm_flags |= VM_RESERVED; mmap_flg = 0;
  psize = physical - off;
  if(io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), vsize, vma->vm_page_prot)) {return  -EAGAIN;}
  return 0;
}
********************************************

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

во-первых, ваше сообщение я читаю с большим трудом, т.к. все уползает за пределы экрана. больше я не буду читать вас если вы не будете форматировать. и код в том числе, я отказываюсь понимать if (10000_chars_expression) { ... }

> > пусть NNN == PAGE_SIZE. pci_alloc_consistent() вернет вам именно > > эту одну страничку > > А пусть NNN<PAGE_SIZE, или NNN/PAGE_SIZE=1.2, тогда что, еще > кучу проверок вводить

да как хотите делайте! я вам сказал, что код не правильный, вы спросили почему. я обьяснил. вообще-то, pci_alloc_consistent() вернет вам 2 ** get_order(size) страниц. но вы можете считать только те, что используете,

npag = (size + PAGE_SZIE - 1) / PAGE_SIZE;

я прошу прощения за то, что начинаю раздражаться, но если вы такой простой вещи не можете сделать, как вам обьяснить более сложные?

> эта одна лишняя страничка мне как-то жизнь испортит ? > Хотя, если это Fatal ERROR, тогда.... :)

ДА!!! это вполне FATAL error и может разрушить, хотя будет проявляться не всегда.

> Так откуда мне брать это смещение !!!???? Я его сейчас беру из > pci_alloc_consistent(dev,((DataSize)<<2), (dma_addr_t*) &dma_buff_phys); > т.е. dma_buff_phys передаю в user-level и там использую в mmap в качестве offset'a.

в последний раз попытаюсь обьяснить. не передавайте его в user level, а просто запомните. а mmap() пусть передает offset == 0.

тут я вообще перестал что-то понимать:

> Вот и все дальше контроллер программирую и делаю - > read/write(fd, dma_buff, SIZE)

зачем вам тогда mmap() ?

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

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

Не знаю!!! У меня все нормально видно. Preformatted text делаю.

> и код в том числе, я отказываюсь понимать if (10000_chars_expression) { }

Первый раз вижу, я такого не писал!!!

>  npag = (size + PAGE_SZIE - 1) / PAGE_SIZE;

ну так раскройте скобки npag=(NNN-1)/PAGE_SIZE + 1, фактически тоже 
самое, что и я писал. Хотя да, согласен, -1 необходимо!!!

> в последний раз попытаюсь обьяснить. не передавайте его в user level, а 
> просто запомните. а mmap() пусть передает offset == 0.

Это я уже понял. Просто хочу разобраться. Как я понял  vma->vm_pgoff 
это физ. адресс доступной мне памяти. Его я маплю. Дальше я в него 
делаю memcpy, т.е. записываю в него данные. Так вот вопрос: какое 
отношение эта замапленная память имеет отношение к памяти, выделенн-
ой   pci_alloc_consistent ??? И как дальше этот offset использовать ? 

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

>> и код в том числе, я отказываюсь понимать if (10000_chars_expression) { }

>Первый раз вижу, я такого не писал!!!

по моемому ему не понравилось

if(io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), vsize, vma->vm_page_prot)) {return -EAGAIN;}

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

все, я сдаюсь :) 

> > npag = (size + PAGE_SZIE - 1) / PAGE_SIZE;
> ну так раскройте скобки npag=(NNN-1)/PAGE_SIZE + 1, фактически
> тоже самое, что и я писал.

да конечно тоже самое, просто результат разный, и может
привести к краху системы. не о чем беспокоиться.

вы лучше сами скобки раскройте. по вашему (1 + 1) / 2
даст тот же результат, что и 1/2 + 1/2 ? пожалуйста,
не поленитесь, напишите тестовую программу.

> Это я уже понял. Просто хочу разобраться. Как я понял  vma->vm_pgoff
> это физ. адресс доступной мне памяти.

это параметр offset от mmap().

> Так вот вопрос: какое отношение эта замапленная память имеет
> отношение к памяти, выделенной   pci_alloc_consistent ???

я думал, эту память вы и пытаетесь mmap'ить. если нет, то я
вообще уже запутался.

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

Еще раз пробую. Не понимаю, что с форматированием происходит? 

Ах да, mmap в ядре забыл
***************** kernel**********************
static int drv_mmap (struct file *filp, struct vm_area_struct *vma) {

  unsigned long physical, off, vsize, psize;

  off = vma->vm_pgoff << PAGE_SHIFT;
  vsize = vma->vm_end - vma->vm_start;
  physical = off; vma->vm_flags |= VM_RESERVED; mmap_flg = 0;
  psize = physical - off;
  if(io_remap_pfn_range(vma, vma->vm_start, ((physical)>>PAGE_SHIFT), 
vsize, vma->vm_page_prot))
 {return  -EAGAIN;}
  return 0;
}
********************************************

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

по моемому тоже самое только в профиль

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

> вы лучше сами скобки раскройте. по вашему (1 + 1) / 2
> даст тот же результат, что и 1/2 + 1/2 ?

Нет конечно! Но я так и не делаю!
npag = ((mod_dma_stp->blkSz-1)/(PAGE_SIZE)) + 1;
Я вам код уже приводил!

> я думал, эту память вы и пытаетесь mmap'ить. если нет, то я
> вообще уже запутался.

Я уже приводил много раз вам код как я делаю. Лучще б вы внимательно
посмотрели, а не сразу бы говорили, что все не правильно и не
понятно. Что не правильно - я и сам знаю. Былоб правильно - не спрашивал
бы  :) Вот еще раз как я делаю:
В юзер процессе вызываю mmap:
dma_buff=mmap(0, (Data_Size), ..., ..., fd, 0);
В ядре ф-ция mmap:
    offset = vma->vm_pgoff << PAGE_SHIFT;
    vsize = vma->vm_end - vma->vm_start;
    vma->vm_flags |= VM_RESERVED;
    io_remap_pfn_range(vma, vma->vm_start, ((offset)>>PAGE_SHIFT), 
size, vma->vm_page_prot);
Т.е. как вы видите я здесь адреса, переданные ф-цией
dma_addr = pci_alloc_consistent(dev, SIZE, &dma_buff_phys);
не использую. Так вот и вопрос: Как использовать эти адресса 
в mmap ф-ции ядра, чтоб отобразить их в user-space ?
я думаю может так.
 offset = vma->vm_pgoff << PAGE_SHIFT;
 offset += dma_buff_phys;
ну и далее  io_remap_pfn_range(...).  Ну или еще как. Подскажите.
Ну конкретней спросить уже не могу :)


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

ну все, senjy, вы меня разозлили :)

> > вы лучше сами скобки раскройте. по вашему (1 + 1) / 2
> > даст тот же результат, что и 1/2 + 1/2 ?
>
> Нет конечно! Но я так и не делаю!
> npag = ((mod_dma_stp->blkSz-1)/(PAGE_SIZE)) + 1;
> Я вам код уже приводил!

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

> > я думал, эту память вы и пытаетесь mmap'ить. если нет, то я
> > вообще уже запутался.
>
> Я уже приводил много раз вам код как я делаю. Лучще б вы внимательно
> посмотрели, а не сразу бы говорили, что все не правильно и не
> понятно.

вот это вы все к чему, senjy? чтобы усилить мою мотивацию к чтению
вашего потока сознания?

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

и почему бы вам не ответить: вы именно на эту память хотите иметь
mmap или нет, вместо того, чтобы возмущенно чирикать? ведь это не
мне, это вам нужно.

ну-с, давайте посмотрим внимательно...

> В юзер процессе вызываю mmap:
> dma_buff=mmap(0, (Data_Size), ..., ..., fd, 0);

как же так? раньше-то было:
> mmap(0, ..., fd, (off_t)dma_off);

и куда же тогда внимательно смотреть?

> В ядре ф-ция mmap:
> ...
> Т.е. как вы видите я здесь адреса, переданные ф-цией
> dma_addr = pci_alloc_consistent(dev, SIZE, &dma_buff_phys);
> не использую.

вижу, и уже который день пытаюсь вам втолковать, что _должны_
использовать.

> Так вот и вопрос: Как использовать эти адресса 
> в mmap ф-ции ядра, чтоб отобразить их в user-space ?
> я думаю может так.
> offset = vma->vm_pgoff << PAGE_SHIFT;
> offset += dma_buff_phys;

ну а я о чем вам говорил??? ну вы почитайте, что я вам писал!
только offset'ом это называть странно, и физический адрес
вам не нужен, лучше уж:

	pfn = page_to_pfn(virt_to_page(dma_addr));
	remap_pfn_range(..., pfn, ...);

> Ну конкретней спросить уже не могу :)

ну конкретнее ответить уже невозможно. больше не буду и пытаться.

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

> вижу, и уже который день пытаюсь вам втолковать, что _должны_
> использовать.

Вот в этом все ваши ответы и состоят. Ключевое слово
здесь ДОЛЖНЫ использовать. Это разве ответ ???
Понятно, если вы не хотите помочь, то не отвечаете и ... все.
А тут какие-то ремарки непонятные, типа "ничего не понятно",
"все не правильно". Да, если б я знал как сделать,
то не спрашивал бы у вас наверное.

> вам не нужен, лучше уж:
> pfn = page_to_pfn(virt_to_page(dma_addr));
> remap_pfn_range(..., pfn, ...);

Вот первый конкретный ответ!!! Спасибо! Еслиб вы хоть 
названия ф-ций приводили и то было б больше толка.
А так не хотите помогать - не надо! Но тогда лучше уж молчите,
а не бросайте нервные реплики.

Спасибо за "помощь"!!!

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