This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/AM5728:使用网络子系统时内核页面分配失败

Guru**** 2577385 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/630909/linux-am5728-kernel-page-allocation-failure-while-using-the-network-subsytem

器件型号:AM5728

工具/软件:Linux

我正在使用 psnap (skb buff)模块开发用于交换数据的驱动程序。但我遇到以下崩溃。 我的内核版本是4.9.41。

,*PMD=00000000000[125.914637]内部错误:Oops:206 [#4] preempt SMP ARM
[125.920145]链接的模块:SAMPLE_GADGET(O) libcomposite (O) psnap (O)
LLC(O) bc_example,(O) SHA512_generic SHA132_ARM 6.A256_generic SHCCD:SH000A1
:SH500_generic SHAUPID:r.1r.1r.1r.1rg.1rg.1rc.a1 D O 4.9.41-ge3a80a1c5c #1
[126.008949]硬件名称:通用 DRA74X (平展设备树)
[126.015064]任务:ed210000 task.stack: ed31c000
[126.019621] PC 位于__kmalloc_track_callers+0xa8/0x1d8
[126.019671]无法处理虚拟地址01092a85
[126.019675] PgD = d57867c0
[126.019681][01092a85]无法处理内核分页请求,[126.019675][126.0469m_mc=p_md

= d57369mc0 [12mc000[12m_mc64][012m_mc=12mc64]*12m_mc=12mc=12mc=12mc64_m_mc=12mc=12mc_ ] LR:[ ] PSR:200f0013
[126.044781] sp:ed31dc78 IP:ed31dc30 FP:ed31dc9c
[126.056303] R10:00000000 R9:00001d1e R8:ed31dc78
[126.061547] r7:ed31c000 R6:01092a85] r4:000080r4
:0000000r3:000080r4:06r4:0000000r4:000000 c0 00001d1e r0:ee801c00
[126.074650]标志:模式 SVC_32 ISA ARM 段用户
[126.081812]控制:30c5387d 表:ad24bd80 DAC:55555555[126.087578]
进程系统日志(126.081812]控制:30c5387d 表:ad24bd80 DAC:555555555555[126.87358]处理堆栈限制[126.33103][126.33210


](_kmalloc_track_caller)、来自[ ](_kmalloc_reserve.constprop.15+0x2C/0x78)
[ 126.349144] R9:0000000a R8:00000100 r7:c079fd74 R6:025004c0 R5:025004c0 R4:ed31dccf
[ 126.356920][ ](_kmalloc_reserve.constprop.15)、来自[ ](__alloc_skb+0x60/0x144)
[126.366088] R9:0000000a R8:00000000 r7:ee801cc0 R6:025004c0 R5:0000000a R4:ca4da240
[126.373864][ ](__alloc_skb)来自[ ](alloc_skb_wo_frags+0x50/0x1d4)
[126.382160] R9:0000000a R8:00000003 r7:c026e1f8 R6:00000000 R5:7ffffff R4:ee01de40
[126.389935][ ](alloc_skb_with frags)、来自[ ](SOCK_ALLOC_SEND_Pskb+0x1f0/0x20c)
[126.399104] R10:00000000 R9:0000000a R8:ee01df84 r7:c026e1f8 R6:ed31c000 R5:7ffff
[ 126.406960] R4:01de40505]
[ 126.40505] ](sock_alloc_send_pskb)、来自[ ](UNIX_dmgram_sendmsg+0x138/0x648)
[126.418500] r10:00000016 r9:00000000 r8:0000000a r7:dff2b500 r6:ee01de40 r5:ed31df48
[126.426356] r4:00000000
[ 126.428901][ ](UNIX_dgram_sendmsg)、来自[ ](SOCK_sendmsg+0x1c/0x2C)
[126.437023] R10:00004000 R9:00000000 R8:ed31de28 r7:dff2b500 R6:00000000 R5:00000000
[ 126.444880] R4:ed31df48
[ 126.447423][ ](sock_sendmsg)、来自[ ](__sys_sendmsg+0x1d8/0x1e8)
[126.455371][ ](__sys_sendmsg)、来自[ ](_sys_sendmsg+0x48/0x74)
[ 126.463231] R10:00000000 R9:ed31c000 R8:c0207d84 r7:00000128 R6:dff2b500 R5:00004000
[ 126.471089] R4:be80da10
[ 126.473630][ ](_sys_sendmsg)、来自[ ](sys_sendmsg+0x10/0x14)
[126.481227] r6:00000010 r5:be80dfa3 r4:be80da10
[126.485864][ ](sys_sendmsg)从[ ](RET_FAST_SYSCALL+0x0/0x34) 

这是我用于发送数据的示例代码、

int tx_data (void *buf、uint16_t len)
{
struct sk_buff *skb = NULL;
uint16_t HDR_len;

HDR_len = dll_dev->net_dev->hard_header_alloc + 8;

skb = len_skb (HDR_len + Len、GFP_Atomic);
if (dlp_transport = skb


);skb =
ration_reet (skb);skb = ration_reet (skb);skb = nel_return;skb = n_skb = r_skb = r_len_skb (r_skb);

sKB->dev = dll_dev->net_dev;

memcpy (skb->data、buf、len);
skb_put (skb、 len);
dll_dev->proto -> request (dll_dev->proto、skb、dll_dev->dmac);

return 0;
} 

通常、SK_buff 由我在发送端通过""分配alloc_skb、并分配给网络。 它基本上是由网络驱动程序在发送后释放的。 但我怀疑网络驱动程序无法释放 skb。 是否有办法确保网络驱动程序正确释放 skb。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    请参阅:
    www.linuxjournal.com/.../1312
    "kfree_skb()释放缓冲区,如果设置了 skb->SK,则会降低套接字(SK)的内存使用计数。 由套接字和协议级例程来递增这些计数并避免释放具有未处理缓冲区的套接字。 内存计数非常重要、因为内核网络层需要知道每个连接绑定了多少内存、以防止远程计算机或本地进程使用过多内存"

    www.linuxjournal.com/.../1312
    “最重要的是 skb->SK=SK。 sock_alloc_send_skb()已将缓冲区的内存充电至套接字。 通过设置 skb->SK,我们告诉内核,任何在缓冲区上执行 kfree_skb()的人都应将缓冲区的内存贷记到套接字中。 因此、当器件发送并释放缓冲区时、用户能够发送更多数据。"

    另请参阅 kfree_skb()的说明:
    www.cs.bham.ac.uk/.../r6776.html
    "如果使用计数达到零、则丢弃对缓冲区的引用并将其释放。"

    因此、您应该监控使用情况计数、以查看套接字是否使用了您的缓冲区。

    此致、
    Yordan