LINUX.ORG.RU

[kernel] .mmap, выравнивание

 


0

1

Доброго времени суток!

У меня вопрос про выравнивание памяти, которая отдается в user-space. В Remap PCI memory в user-space ttnl писал про отступ от начала страницы, конорый нужно компенсировать в юзер-спейсе, но мне нужно так, чтобы память отдавалась _уже_ выровненной.

Когда засыпал подумал о том, что может быть можно сделать выделяя память с vmalloc, на которую (может быть) можно замапить pci_resource_start, но сейчас думаю, что тогда все как-то сумбурно и не факт, что так делают (тем более, что я исходниках ядра я подобной «техники» не нашел). Вот и решил спросить у умных людей, как можно выравнять память полученную pci_resource_start? Заранее спасибо :)

Ответ на: комментарий от ttnl

что лишний раз подтверждает фразу «все гениальное просто» :)

спасибо больше! :)

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

тем не менее, не осилил :(

по незнанию решил, что будет просто, но ни добавление смещения, ни отнимание к vm_start или vm_start и vm_end приводят к ошибкам при маппировании из юзер-спейса...

вот текст .mmap с закомментированными строчками, приводящими к краху системы::

static int mkopci_mmap(struct file *filp, struct vm_area_struct *vma)
{
    mkopci_device_t *dev = filp->private_data;
    unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

    if(dev->core.c_bar == -1) {
        printk(KERN_ERR "mkopci: invalid c_bar number\n");
        return -EINVAL;
    }   

    if (vma->vm_pgoff != 0)
        return -EINVAL;

//  vma->vm_start += dev->core.mem_base[dev->core.c_bar] & ~PAGE_MASK;
//  vma->vm_end += dev->core.mem_base[dev->core.c_bar] & ~PAGE_MASK;

    if (PAGE_ALIGN(dev->core.mem_size[dev->core.c_bar]) != PAGE_ALIGN(vma->vm_end - vma->vm_start)) {
        printk("mkopci: PAGE_ALIGN error\n");
        return -EINVAL;
    }   

    printk("mem_base = 0x%lx    vm_start = 0x%lx\n", dev->core.mem_base[dev->core.c_bar], vma->vm_start);
    if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC))
        vma->vm_flags |= VM_IO;
    vma->vm_flags |= VM_RESERVED | VM_LOCKED;

    if (remap_pfn_range(vma, vma->vm_start,
                            virt_to_phys(bus_to_virt(dev->core.mem_base[dev->core.c_bar])) >> PAGE_SHIFT,
                            dev->core.mem_size[dev->core.c_bar], pgprot_noncached(vma->vm_page_prot)))  {
        printk("mkopci: EAGAIN\n");
        return -EAGAIN;
    }   

    return 0;
}

или Вы имели в виду совсем другое?

metawishmaster ★★★★★
() автор топика
Ответ на: тем не менее, не осилил :( от metawishmaster

Ну смотрите, в функции mmap_region есть такой комментарий:

 /* Can addr have changed?? * * Answer: Yes, several device drivers can do it in their * f_op->mmap method. -DaveM */ 

vm_end менять не надо. vm_start - в самом конце функции, уже после remap_pfn_range

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

видимо, не судьба... сейчас сделал, как Вы и сказали:

    ...
    if (remap_pfn_range(vma, vma->vm_start,
                            virt_to_phys(bus_to_virt(dev->core.mem_base[dev->core.c_bar])) >> PAGE_SHIFT,
                            dev->core.mem_size[dev->core.c_bar], pgprot_noncached(vma->vm_page_prot)))  {
        printk("mkopci: EAGAIN\n");
        return -EAGAIN;
    }
    vma->vm_start += (dev->core.mem_base[dev->core.c_bar] & ~PAGE_MASK);
    return 0;
}
но если удается увидель где падает, то unmap_vmas... а работает только тем способом, что добавлять смещение в юзерспейсе...

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

ниже вывод dmesg'a после падения там несколько первых строчек строчек выводит мой драйвер, а потом «[42493.091606] rtltest:14177 freeing invalid memtype feafd000-feafdc00», что странно - нет памяти размером 0xC00, зато есть такое смещение и память 4-го BAR'a начинается с 0xfeafdc00

[42430.195688] mkopci: bar 0 base = 0xfeaff000 len = 0x00000080 offset = 0x00000000
[42430.199621] mkopci: bar 1 is IORESOURCE_IO
[42430.203542] mkopci: bar 2 base = 0xfe980000 len = 0x00080000 offset = 0x00000000
[42430.207821] mkopci: bar 3 base = 0xfeaa0000 len = 0x00020000 offset = 0x00000000
[42430.212291] mkopci: bar 4 base = 0xfeafdc00 len = 0x00000100 offset = 0x00000c00
[42430.216422] mkopci: bar 5 base = 0xfeafd400 len = 0x00000100 offset = 0x00000400
[42430.220448] mkopci: irq = 20
[42430.224420] mkopci: device mkopci0 probed
[42430.228994] mkopci: 1 device(s) found
[42430.233091] mkopci: major = 250
[42446.389134] mkopci: device 0 opened in regular mode
[42446.393352] mem_base = 0xfeaff000    vm_start = 0xb7722000
[42446.397612] mem_base = 0xfe980000    vm_start = 0xb7521000
[42446.401852] mem_base = 0xfeaa0000    vm_start = 0xb7501000
[42446.405954] mem_base = 0xfeafdc00    vm_start = 0xb7500000
[42446.410020] mem_base = 0xfeafd400    vm_start = 0xb74ff000
[42493.091606] rtltest:14177 freeing invalid memtype feafd000-feafdc00
[42493.095940] BUG: unable to handle kernel paging request at fffa7000
[42493.099851] IP: [<c10a4d18>] unmap_vmas+0x1a0/0x455
[42493.099851] *pde = 013f3067 *pte = 00000000 
[42493.099851] Oops: 0000 [#1] SMP 
[42493.099851] Modules linked in: mkopci26(O) xt_multiport iptable_filter ip_tables x_tables cpufreq_userspace cpufreq_stats cpufreq_powersave ppdev cpufreq_conservative lp nfsd lockd nfs_acl sunrpc exportfs fuse ext3 jbd w83627hf hwmon_vid loop firewire_sbp2 evdev psmouse shpchp processor button i2c_i801 serio_raw i2c_core pcspkr parport_pc parport thermal_sys pci_hotplug ext4 mbcache jbd2 crc16 sd_mod crc_t10dif ata_generic usbhid hid uhci_hcd sata_promise ehci_hcd sata_sil ata_piix libata scsi_mod firewire_ohci 8139too floppy usbcore firewire_core crc_itu_t skge mii usb_common [last unloaded: mkopci26]
[42493.099851] 
[42493.099851] Pid: 14177, comm: rtltest Tainted: G           O 3.2.9 #2 To Be Filled By O.E.M. To Be Filled By O.E.M./P4C800
[42493.099851] EIP: 0060:[<c10a4d18>] EFLAGS: 00010296 CPU: 1
[42493.099851] EIP is at unmap_vmas+0x1a0/0x455
[42493.099851] EAX: 0000033b EBX: f7213940 ECX: 00000000 EDX: 0000033b
[42493.099851] ESI: fffa7000 EDI: f6f6ff20 EBP: b7800400 ESP: f0fcbd50
[42493.099851]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[42493.099851] Process rtltest (pid: 14177, ti=f0fca000 task=ea5a34d0 task.ti=f0fca000)
[42493.099851] Stack:
[42493.099851]  f0fcbd94 34bb5444 b7500000 b7500000 00000000 ea5a34d0 f5bb9688 f0fcbdc0
[42493.099851]  f19f7600 efdf8b74 efdf8b74 4efca067 00000000 fffa63fc f19f7758 f19f7760
[42493.099851]  f19f775c ffffff7b ffffffec 00000000 f0b5f948 f19f7600 f0fcbdc0 f19f7638
[42493.099851] Call Trace:
[42493.099851]  [<c10a7e37>] ? exit_mmap+0x64/0xa9
[42493.099851]  [<c102c447>] ? mmput+0x39/0xa9
[42493.099851]  [<c102f558>] ? exit_mm+0xdc/0xe4
[42493.099851]  [<c105e9ba>] ? acct_collect+0x77/0x127
[42493.099851]  [<c1030aea>] ? do_exit+0x1fb/0x64e
[42493.099851]  [<c1039df6>] ? dequeue_signal+0xb4/0x126
[42493.099851]  [<c1030f97>] ? do_group_exit+0x5a/0x7d
[42493.099851]  [<c103b94d>] ? get_signal_to_deliver+0x44c/0x45f
[42493.276826]  [<c1049790>] ? timekeeping_get_ns+0x10/0x48
[42493.276826]  [<c10020cd>] ? do_signal+0x2f/0x671
[42493.276826]  [<c104f577>] ? tick_program_event+0x1c/0x1f
[42493.276826]  [<c1045bf4>] ? __remove_hrtimer+0x54/0x71
[42493.276826]  [<c1046083>] ? remove_hrtimer+0x44/0x4d
[42493.276826]  [<c10460cb>] ? hrtimer_cancel+0xa/0x14
[42493.276826]  [<c1275771>] ? do_nanosleep+0x53/0x7f
[42493.276826]  [<c104647e>] ? hrtimer_nanosleep+0x77/0xe4
[42493.276826]  [<c1045c99>] ? update_rmtp+0x57/0x57
[42493.276826]  [<c100272f>] ? do_notify_resume+0x20/0x55
[42493.276826]  [<c12760d6>] ? work_notifysig+0x13/0x19
[42493.276826] Code: 03 3d 00 4a 47 c1 89 f8 e8 e3 97 f7 ff 89 ea c1 ea 0a 81 e2 fc 0f 00 00 8d 14 10 8d 47 1c 89 54 24 34 e8 4c 12 1d 00 8b 74 24 34 <8b> 0e 85 c9 0f 84 83 01 00 00 f7 c1 01 01 00 00 0f 84 20 01 00 
[42493.276826] EIP: [<c10a4d18>] unmap_vmas+0x1a0/0x455 SS:ESP 0068:f0fcbd50
[42493.276826] CR2: 00000000fffa7000
[42493.276826] ---[ end trace 559d8a5eb0afcebc ]---
[42493.276826] Fixing recursive fault but reboot is needed!
[42493.276826] BUG: scheduling while atomic: rtltest/14177/0x00000001
[42493.276826] Modules linked in: mkopci26(O) xt_multiport iptable_filter ip_tables x_tables cpufreq_userspace cpufreq_stats cpufreq_powersave ppdev cpufreq_conservative lp nfsd lockd nfs_acl sunrpc exportfs fuse ext3 jbd w83627hf hwmon_vid loop firewire_sbp2 evdev psmouse shpchp processor button i2c_i801 serio_raw i2c_core pcspkr parport_pc parport thermal_sys pci_hotplug ext4 mbcache jbd2 crc16 sd_mod crc_t10dif ata_generic usbhid hid uhci_hcd sata_promise ehci_hcd sata_sil ata_piix libata scsi_mod firewire_ohci 8139too floppy usbcore firewire_core crc_itu_t skge mii usb_common [last unloaded: mkopci26]
[42493.276826] Pid: 14177, comm: rtltest Tainted: G      D    O 3.2.9 #2
[42493.276826] Call Trace:
[42493.276826]  [<c127480c>] ? __schedule+0x6a/0x584
[42493.276826]  [<c1046ea3>] ? down_trylock+0x1b/0x23
[42493.276826]  [<c102e200>] ? console_trylock+0xa/0x42
[42493.276826]  [<c10309be>] ? do_exit+0xcf/0x64e
[42493.276826]  [<c102e09e>] ? kmsg_dump+0x34/0xab
[42493.276826]  [<c1277254>] ? oops_end+0x8f/0x93
[42493.276826]  [<c101ae92>] ? no_context+0x10d/0x116
[42493.276826]  [<c101af98>] ? bad_area_nosemaphore+0xa/0xc
[42493.276826]  [<c1278ade>] ? do_page_fault+0x19d/0x358
[42493.276826]  [<c1093236>] ? __alloc_pages_nodemask+0x115/0x53f
[42493.276826]  [<c127462a>] ? printk+0xe/0x14
[42493.276826]  [<c101ca4c>] ? free_memtype+0xe0/0x116
[42493.276826]  [<c1278941>] ? spurious_fault+0xa6/0xa6
[42493.276826]  [<c1276bef>] ? error_code+0x67/0x6c
[42493.276826]  [<c101007b>] ? do_machine_check+0x2a8/0x623
[42493.276826]  [<c10a4d18>] ? unmap_vmas+0x1a0/0x455
[42493.276826]  [<c10a7e37>] ? exit_mmap+0x64/0xa9
[42493.276826]  [<c102c447>] ? mmput+0x39/0xa9
[42493.276826]  [<c102f558>] ? exit_mm+0xdc/0xe4
[42493.276826]  [<c105e9ba>] ? acct_collect+0x77/0x127
[42493.276826]  [<c1030aea>] ? do_exit+0x1fb/0x64e
[42493.276826]  [<c1039df6>] ? dequeue_signal+0xb4/0x126
[42493.276826]  [<c1030f97>] ? do_group_exit+0x5a/0x7d
[42493.276826]  [<c103b94d>] ? get_signal_to_deliver+0x44c/0x45f
[42493.276826]  [<c1049790>] ? timekeeping_get_ns+0x10/0x48
[42493.276826]  [<c10020cd>] ? do_signal+0x2f/0x671
[42493.276826]  [<c104f577>] ? tick_program_event+0x1c/0x1f
[42493.276826]  [<c1045bf4>] ? __remove_hrtimer+0x54/0x71
[42493.276826]  [<c1046083>] ? remove_hrtimer+0x44/0x4d
[42493.276826]  [<c10460cb>] ? hrtimer_cancel+0xa/0x14
[42493.276826]  [<c1275771>] ? do_nanosleep+0x53/0x7f
[42493.276826]  [<c104647e>] ? hrtimer_nanosleep+0x77/0xe4
[42493.276826]  [<c1045c99>] ? update_rmtp+0x57/0x57
[42493.276826]  [<c100272f>] ? do_notify_resume+0x20/0x55
[42493.276826]  [<c12760d6>] ? work_notifysig+0x13/0x19

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

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

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