LINUX.ORG.RU

Есть знатоки ядра?


0

1

В функции do_mmap поясните мне приз следующее: [code=c] addr = get_unmapped_area(file, addr, len, pgoff, flags); if (addr & ~PAGE_MASK) return addr;/code] нет ведь никакой гарантии что get_unmapped_area вернет адрес выровненный по границе страницы (типа вот она:) [code=c] ...    for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {

if (TASK_SIZE - len < addr) { if (start_addr != TASK_UNMAPPED_BASE) { start_addr = addr = TASK_UNMAPPED_BASE; goto full_search; } return -ENOMEM; } if (!vma || addr + len <= vma->vm_start) { mm->free_area_cache = addr + len; return addr; } addr = vma->vm_end; }[/code] и никакой гарантии что этот vma->vm_end выровнен нет.

После вызова get_unmapped_area как понимать следующий код: [code=c] munmap_back: vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); if (vma && vma->vm_start < addr + len) { if (do_munmap(mm, addr, len)) return -ENOMEM; goto munmap_back; }[/code] иными словами с чего бы вдруг найденная область начала перекрываться с другими (вроде как get_unmapped_area это исключает).

Заранее спасибо за внимание.

Есть знатоки ядра? В функции do_mmap поясните мне приз следующее:

 
   addr = get_unmapped_area(file, addr, len, pgoff, flags); 
   if (addr & ~PAGE_MASK) return addr;/code] 
нет ведь никакой гарантии что get_unmapped_area вернет адрес выровненный по границе страницы (типа вот она:) 

 ...    
   for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {

   if (TASK_SIZE - len < addr) 
   { 
      if (start_addr != TASK_UNMAPPED_BASE) 
      {
         start_addr = addr = TASK_UNMAPPED_BASE; 
         goto full_search; 
      } 
      return -ENOMEM; 
   } 
   if (!vma || addr + len <= vma->vm_start) 
   { 
      mm->free_area_cache = addr + len; 
      return addr; 
   } addr = vma->vm_end; }

и никакой гарантии что этот vma->vm_end выровнен нет.

После вызова get_unmapped_area как понимать следующий код:

 
munmap_back: 
   vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); 
   if (vma && vma->vm_start < addr + len) 
   { 
      if (do_munmap(mm, addr, len)) return -ENOMEM; 
      goto munmap_back; 
   }
иными словами с чего бы вдруг найденная область начала перекрываться с другими (вроде как get_unmapped_area это исключает).

Заранее спасибо за внимание.

ЗЫ: сорри формат съехал

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

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

Ты лучше весь код приведи и версию укажи.

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

> нет ведь никакой гарантии что get_unmapped_area вернет

адрес выровненный


нет. может вообще вернуть -ENOMEM, к примеру.

с чего бы вдруг найденная область начала перекрываться с другими


MAP_FIXED

idle ★★★★★ ()

offtop: а не эта ли тема вспыла в истории про Линуса, flash и glibc?

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

MAP_FIXED - не понял можешь пояснить?

нет. может вообще вернуть -ENOMEM, к примеру. - в чм потаенный смысл делать проверку на выравнивание и возвращать адресс если он не выровнен (ведь область нужного размера дефакто найдена но не распределена!)???

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

> MAP_FIXED - не понял можешь пояснить?

хмм. что пояснить-то? спрашивалось: «с чего бы вдруг
найденная область начала перекрываться с другими».

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

кроме того, есть и другие причины посмотреть на
соседние vma - vma_merge().

в чм потаенный смысл делать проверку на выравнивание

и возвращать адресс если он не выровнен



а что, нужно игнорировать ошибку? ну сами подумайте
чуть-чуть.

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

Ошибку игнорировать нельзя, но сам по себе невыровненный адрес не есть ошибка где тождественное равно между невыровненным адресом и -ENOMEM?

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

> Ошибку игнорировать нельзя,

в чем вопрос тогда? вот мы ее и возвращаем.

но сам по себе невыровненный адрес не есть ошибка


уффф. ну, почитайте этот код немножко. он простой!
get_unmapped_area() возвращает либо корректный
(выровненный) adddress, либо ошибку.

где тождественное равно между невыровненным адресом и -ENOMEM?


караул. нету его. ENOMEM был упомянут для примера.
там может быть EINVAL и др.

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

>get_unmapped_area() возвращает либо корректный (выровненный) adddress Это сам придумал или кто подсказал? с какого [code=c]addr = vma->vm_end;[/code] стал выровненым, пруфлинк в студию!

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

> Это сам придумал или кто подсказал?

дяденька, а повежливее нельзя?

кто из нас тут задает вопросы, на которые я трачу
свое время?

какого addr = vma->vm_end стал выровненым


с такого. я бы ответил, но надоело. теперь сами
разбирайтесь. hint: судя по вопросу, вы вообще не
понимаете, что такое vm_end.

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