linux 分配大连续内存,allocation 如何在Linux中分配大的连续内存区域 - 糯米PHP

是的,我最终会将其用于DMA,但暂时不考虑一致性。我有64位BAR寄存器,因此AFAIK的所有RAM(例如高于4G)都可用于DMA。

我正在寻找大约64MB的连续RAM。是的,很多。

Ubuntu 16和18具有CONFIG_CMA = y,但未在内核编译时设置CONFIG_DMA_CMA。

我注意到,如果同时设置了两者(在内核构建时),我可以简单地调用dma_alloc_coherent,但是,由于后勤原因,不希望重新编译内核。

这些机器将始终至少具有32GB的RAM,不会运行任何占用大量RAM的内存,并且在RAM启动变得明显碎片之前,内核模块将在启动后不久加载,并且AFAIK,其他都没有使用CMA。

我已经设置了内核参数CMA = 1G。(并尝试过256M和512M)

# dmesg | grep cma

[ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.4.170 root=UUID=2b25933c-e10c-4833-b5b2-92e9d3a33fec ro cma=1G

[ 0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-4.4.170 root=UUID=2b25933c-e10c-4833-b5b2-92e9d3a33fec ro cma=1G

[ 0.000000] Memory: 65612056K/67073924K available (8604K kernel code, 1332K rwdata, 3972K rodata, 1484K init, 1316K bss, 1461868K reserved, 0K cma-reserved)

我已经尝试过alloc_pages(GFP_KERNEL | __GFP_HIGHMEM,命令),不高兴。

最后是实际的问题:如何从CMA获得大的连续块?我在网上找到的所有内容都建议使用dma_alloc_coherent,但我知道这仅适用于CONFIG_CMA = y和CONFIG_DMA_CMA = yes。

模块源tim.c

#include /* Needed by all modules */

#include /* Needed for KERN_INFO */

#include

#include

#include

unsigned long big;

const int order = 15;

static int __init tim_init(void)

{

printk(KERN_INFO "Hello Tim!\n");

big = __get_free_pages(GFP_KERNEL | __GFP_HIGHMEM, order);

printk(KERN_NOTICE "big = %lx\n", big);

if (!big)

return -EIO; // AT&T

return 0; // success

}

static void __exit tim_exit(void)

{

free_pages(big, order);

printk(KERN_INFO "Tim says, Goodbye world\n");

}

module_init(tim_init);

module_exit(tim_exit);

MODULE_LICENSE("GPL");

插入模块会产生...

# insmod tim.ko

insmod: ERROR: could not insert module tim.ko: Input/output error

# dmesg | tail -n 33

[ 176.137053] Hello Tim!

[ 176.137056] ------------[ cut here ]------------

[ 176.137062] WARNING: CPU: 4 PID: 2829 at mm/page_alloc.c:3198 __alloc_pages_nodemask+0xd14/0xe00()

[ 176.137063] Modules linked in: tim(OE+) xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter ip_tables x_tables configfs vxlan ip6_udp_tunnel udp_tunnel uio pf_ring(OE) x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm mei_me mei irqbypass sb_edac ioatdma edac_core shpchp serio_raw input_leds lpc_ich dca acpi_pad 8250_fintek mac_hid ib_iser rdma_cm iw_cm ib_cm ib_sa ib_mad ib_core ib_addr iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 btrfs raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid0 multipath linear

[ 176.137094] hid_generic usbhid crct10dif_pclmul crc32_pclmul ghash_clmulni_intel e1000e aesni_intel raid1 aes_x86_64 isci lrw libsas ahci gf128mul ptp glue_helper ablk_helper cryptd psmouse hid libahci scsi_transport_sas pps_core wmi fjes

[ 176.137105] CPU: 4 PID: 2829 Comm: insmod Tainted: G OE 4.4.170 #1

[ 176.137106] Hardware name: Supermicro X9SRL-F/X9SRL-F, BIOS 3.3 11/13/2018

[ 176.137108] 0000000000000286 8ba89d23429d5749 ffff88100f5cba90 ffffffff8140a061

[ 176.137110] 0000000000000000 ffffffff81cd89dd ffff88100f5cbac8 ffffffff810852d2

[ 176.137112] ffffffff821da620 0000000000000000 000000000000000f 000000000000000f

[ 176.137113] Call Trace:

[ 176.137118] [] dump_stack+0x63/0x82

[ 176.137121] [] warn_slowpath_common+0x82/0xc0

[ 176.137123] [] warn_slowpath_null+0x1a/0x20

[ 176.137125] [] __alloc_pages_nodemask+0xd14/0xe00

[ 176.137128] [] ? msg_print_text+0xdf/0x1a0

[ 176.137132] [] ? irq_work_queue+0x8e/0xa0

[ 176.137133] [] ? console_unlock+0x20f/0x550

[ 176.137137] [] alloc_pages_current+0x8c/0x110

[ 176.137139] [] ? 0xffffffffc0024000

[ 176.137141] [] __get_free_pages+0xe/0x40

[ 176.137143] [] tim_init+0x20/0x1000 [tim]

[ 176.137146] [] do_one_initcall+0xb5/0x200

[ 176.137149] [] ? kmem_cache_alloc_trace+0x185/0x1f0

[ 176.137151] [] do_init_module+0x5f/0x1cf

[ 176.137154] [] load_module+0x22e5/0x2960

[ 176.137156] [] ? __symbol_put+0x60/0x60

[ 176.137159] [] ? kernel_read+0x50/0x80

[ 176.137161] [] SYSC_finit_module+0xb4/0xe0

[ 176.137163] [] SyS_finit_module+0xe/0x10

[ 176.137167] [] entry_SYSCALL_64_fastpath+0x22/0xcb

[ 176.137169] ---[ end trace 6aa0b905b8418c7b ]---

[ 176.137170] big = 0

奇怪的是,再次尝试会产生...

# insmod tim.ko

insmod: ERROR: could not insert module tim.ko: Input/output error

...and dmesg just shows:

[ 302.068396] Hello Tim!

[ 302.068398] big = 0

为什么没有堆栈转储第二(和后续)次尝试?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值