亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 7442 | 回復(fù): 7
打印 上一主題 下一主題

請(qǐng)教關(guān)于“kmalloc分配內(nèi)存出錯(cuò)”,感謝 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2008-08-01 23:09 |只看該作者 |倒序?yàn)g覽
10可用積分
我的目標(biāo)平臺(tái)為 s3c2410-linux2.4.18
宿主機(jī)為readhat9.0
做對(duì)UART2以DMA方式進(jìn)行數(shù)據(jù)讀取的驅(qū)動(dòng)

在設(shè)置緩沖區(qū)的函數(shù)里,
當(dāng)為DMA內(nèi)核緩沖區(qū)數(shù)據(jù)結(jié)構(gòu)(uart_buf_t)分配內(nèi)存時(shí),
(構(gòu)建s->nbfrags個(gè)這樣的緩沖區(qū),所以乘以 s->nbfrags)
(s->nbfrags根據(jù)需要設(shè)定,在我看的音頻驅(qū)動(dòng)中,設(shè)定為最大8個(gè))

kmalloc(sizeof(uart_buf_t) * s->nbfrags, GFP_KERNEL);
// 其中 sizeof(uart_buf_t) = 36
// s->nbfrags = 2

當(dāng)s->nbfrags為2或者3時(shí),能正常分配。當(dāng)s->nbfrags為1, 4, 8 ... 出現(xiàn)如下錯(cuò)誤:

kernel BUG at slab.c:1099!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c3b2c000
*pgd = 33c11001, *pmd = 33c11001, *pte = 00000000, *ppte = 00000000
Internal error: Oops: ffffffff
CPU: 0
pc : [<c001e858>]    lr : [<c0025d74>]    Tainted: P
sp : c3b35e60  ip : c3b35e18  fp : c3b35e70
r10: c3b34000  r9 : 00149898  r8 : 00000000
r7 : 00000000  r6 : c02073b0  r5 : 00000007  r4 : 00000000
r3 : 00000000  r2 : 00000001  r1 : 00000001  r0 : 00000001
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  Segment user
Control: C000317F  Table: 33B2C000  DAC: 00000015
Process insmod (pid: 53, stackpage=c3b35000)
Stack: (0xc3b35e50 to 0xc3b36000)
......
......

----------------------------------------------------------------------------

請(qǐng)問:

我看了kmalloc的用法,原型是 void *kmalloc(unsigned int len, int priority);
priority,也應(yīng)該傳入?yún)?shù)GFP_KERNEL。

只是分配的內(nèi)存長(zhǎng)度不一樣怎么會(huì)出錯(cuò)呢? 而且我分配的內(nèi)存空間并不大。

請(qǐng)高手指點(diǎn),感謝!


----------------------------------------------------------------------------
kmaolloc的相關(guān)代碼如下:

void * kmalloc (size_t size, int flags)
{
        cache_sizes_t *csizep = cache_sizes;

        for (; csizep->cs_size; csizep++) {
                if (size > csizep->cs_size)
                        continue;
                return __kmem_cache_alloc(flags & GFP_DMA ?
                         csizep->cs_dmacachep : csizep->cs_cachep, flags);
        }
        return NULL;
}

static cache_sizes_t cache_sizes[] = {
#if PAGE_SIZE == 4096
        {    32,        NULL, NULL},
#endif
        {    64,        NULL, NULL},
        {   128,        NULL, NULL},
        {   256,        NULL, NULL},
        {   512,        NULL, NULL},
        {  1024,        NULL, NULL},
        {  2048,        NULL, NULL},
        {  4096,        NULL, NULL},
        {  8192,        NULL, NULL},
        { 16384,        NULL, NULL},
        { 32768,        NULL, NULL},
        { 65536,        NULL, NULL},
        {131072,        NULL, NULL},
        {     0,        NULL, NULL}
};

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2008-08-03 11:18 |只看該作者
先判斷下返回地址是否為空也會(huì)出現(xiàn)這樣的情況嗎??

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2008-08-04 11:25 |只看該作者

難道要做指針轉(zhuǎn)換?

int s3c2410_dma_queue_buffer(dmach_t channel, void *buf_id,
                             dma_addr_t data, int size, int write)
中:

sizeof(*buf)等于24 )。DMA緩沖區(qū)的指針。buf的定義為:(

          dma_buf_t *buf;

原來kmalloc的語句為:

          buf = kmalloc(sizeof(*buf), GFP_ATOMIC);

我改為:

          buf = (dma_buf_t*) kmalloc(sizeof(*buf), GFP_ATOMIC);

好像就沒出問題了。

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2008-08-04 11:45 |只看該作者

kmalloc能處理的最小的內(nèi)存塊是32或者64 ?

sizeof(*buf) = sizeof(dma_buf_t) = 24

但在《LDD3》page217, 有:
   kmalloc能處理的最小的內(nèi)存塊是32或者64,取決于當(dāng)前體系結(jié)構(gòu)中使用的頁面大小


我用kmalloc分配的內(nèi)存為24字節(jié)。這個(gè)32/64指內(nèi)存塊,不是指字節(jié)吧。

是不是這個(gè)原因引起的呢?

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2008-08-04 13:54 |只看該作者
原帖由 robotlee2002 于 2008-8-4 11:45 發(fā)表
sizeof(*buf) = sizeof(dma_buf_t) = 24

但在《LDD3》page217, 有:
   kmalloc能處理的最小的內(nèi)存塊是32或者64,取決于當(dāng)前體系結(jié)構(gòu)中使用的頁面大小

我用kmalloc分配的內(nèi)存為24字節(jié)。這個(gè)32/64指內(nèi)存 ...



假如你想kmalloc()size大小的內(nèi)存,那么內(nèi)核從malloc_sizes[]數(shù)組里找到最小的一個(gè)元素,其cssize比size要大,見下面代碼。
如果你分配24字節(jié),不足malloc_sizes[]里面最小的32字節(jié),那么內(nèi)核就會(huì)kmem_cache_alloc(cachep,flags)從數(shù)組第一個(gè)32字節(jié)內(nèi)
存slab對(duì)應(yīng)的cachep里面摘下一塊內(nèi)存給你(這個(gè)內(nèi)存的大小為32字節(jié)),雖然你只用到其中的24字節(jié)。

void * kmalloc (size_t size, int flags)
{
      struct cache_sizes_t *csizep = malloc_sizes;
      kmem_cache_t *cachep;
      for (; csizep->cs_size; csizep++) {
                if (size > csizep->cs_size)
                        continue;
                if(flags & GFP_DMA)
                     cachep=csizep->cs_dmacachep;
                else
                     cachep=csizep->cs_cachep;
                 return kmem_cache_alloc(cachep,flags);
        }
        return NULL;
}

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2008-08-04 16:03 |只看該作者

錯(cuò)誤總是一會(huì)出現(xiàn),一會(huì)不出現(xiàn)。

...
s3c2410_dma_queue_buffer(291): before: kmalloc

kernel BUG at slab.c:1099!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c3b40000
*pgd = 33b95001, *pmd = 33b95001, *pte = 00000000, *ppte = 00000000
Internal error: Oops: ffffffff
CPU: 0
pc : [<c001e858>]    lr : [<c0025d74>]    Tainted: P
sp : c3c7fec4  ip : c3c7fe7c  fp : c3c7fed4
r10: 00000000  r9 : 00000000  r8 : 00000400
r7 : 33ad5400  r6 : c02070a0  r5 : 00000002  r4 : 00000000
r3 : 00000000  r2 : 00000001  r1 : 00000001  r0 : 00000001
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  Segment user
Control: C000317F  Table: 33B40000  DAC: 00000015
Process test (pid: 54, stackpage=c3c7f000)
Stack: (0xc3c7feb4 to 0xc3c80000)
fea0:                                              c0025d74 c001e858 60000013
fec0: ffffffff c02070a0 c3c7fefc c3c7fed8 c003cef4 c001e824 c02070a0 00000002
fee0: c48f2b18 33ad5400 00000400 00000000 c3c7ff14 c3c7ff00 c003d3b4 c003ced0
ff00: c03711c4 00000001 c3c7ff40 c3c7ff18 c48f0504 c003d2a0 00000001 c03711c4
ff20: 00000001 c48f29f0 02008ee0 00000800 c48f1fec c3c7ff78 c3c7ff44 c48f11b0
ff40: c48f0490 00000000 02008ee0 c3bfb7c0 00000800 c3bfb7c0 ffffffea 00000000
ff60: 02008ee0 c3c7e000 401983f8 c3c7ffa4 c3c7ff7c c0046014 c48f1044 401983f8
ff80: c3c7ffac 02008d78 bffffddc 0200053c 00000003 c00197c4 00000000 c3c7ffa8
ffa0: c0019640 c0045f48 02008d78 c001f808 00000003 02008ee0 00000800 02008d70
ffc0: 02008d78 bffffddc 0200053c 00000001 4019a4c4 02000750 401983f8 bffffe68
ffe0: 00000000 bffffd70 0000230c 40029000 60000010 00000003 00000000 00000000
Backtrace:
Function entered at [<c001e814>] from [<c003cef4>]
r4 = C02070A0
Function entered at [<c003cec0>] from [<c003d3b4>]
Function entered at [<c003d290>] from [<c48f0504>]
r5 = 00000001  r4 = C03711C4
Function entered at [<c48f0480>] from [<c48f11b0>]
Function entered at [<c48f1034>] from [<c0046014>]
Function entered at [<c0045f38>] from [<c0019640>]
r8 = C00197C4  r7 = 00000003  r6 = 0200053C  r5 = BFFFFDDC
r4 = 02008D78
Code: eb001c9e e59f0014 eb001c9c e3a03000 (e5833000)
Segmentation fault

奇怪了,錯(cuò)誤一會(huì)出現(xiàn)。把板子重啟后,可能又可以。
我的源碼見附件中,感謝熟悉的大拿幫我看看,謝謝。

[ 本帖最后由 robotlee2002 于 2008-8-4 20:08 編輯 ]

linux_uart2-dma.rar

83.88 KB, 下載次數(shù): 66

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2008-08-04 16:50 |只看該作者
這個(gè)是嵌入式系統(tǒng),發(fā)生這種問題只有一種可能,指針未對(duì)齊,或者因此導(dǎo)致的非法內(nèi)存訪問。至于原因,很可能在你那個(gè)sizeof(uart_buf_t) = 36上,你換一個(gè)32的嘗試過沒有?或者強(qiáng)制對(duì)齊。
還有種導(dǎo)致這種不對(duì)齊原因的是,傳入函數(shù)的緩沖區(qū)指針最好能用memmove復(fù)制一份再新的函數(shù)里,否則也可能產(chǎn)生這種不對(duì)齊的影響。
都嘗試過后,有無進(jìn)展請(qǐng)回復(fù)一下哦

論壇徽章:
0
8 [報(bào)告]
發(fā)表于 2008-09-09 18:16 |只看該作者
sizeof(*buf) 多大,你想求的長(zhǎng)度是這個(gè)嗎?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP