LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (http://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   vmap allocation for size 8192 failed (http://www.linuxquestions.org/questions/linux-kernel-70/vmap-allocation-for-size-8192-failed-819048/)

ravspratapsingh 07-10-2010 05:24 AM

vmap allocation for size 8192 failed
 
Hi,

I am running a test application to test the writes/reads to spi based fram on PowerPC MPC8313E based board. I am writing 128K data and reading it back and comparing it. This is done in a while(1) loop. What I observe is that after 650 iterations, the system hangs. When i ran dmesg command i found this:

vmap allocation for size 8192 failed: use vmalloc=<size> to increase size.
Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xc027fe4c
Oops: Kernel access of bad area, sig: 11 [#1]
PREEMPT PXM468k
Modules linked in:
NIP: c027fe4c LR: c027fe40 CTR: c021a1cc
REGS: cf9d7e60 TRAP: 0300 Not tainted (2.6.29.2pxm468kcore)
MSR: 00009032 <EE,ME,IR,DR> CR: 24042082 XER: 20000000
DAR: 00000000, DSISR: 20000000
TASK = cf84db20[906] 'e0007000.spi' THREAD: cf9d6000
GPR00: c027fe40 cf9d7f10 cf84db20 00000000 c0659520 cdca9c20 c021ac6c fffffff9
GPR08: c04839e8 c0480000 00000000 00000002 24042082 100eb240 0ffc7fc0 0fd5bf39
GPR16: 00000004 00000024 00000000 00000377 00000001 cf9d6034 cf20d764 cf20d720
GPR24: 00000200 cf9d6000 00000000 cf20d800 00000000 00000001 ccc05e1c ccc05e48
Call Trace:
[cf9d7f10] [c027fe40] 0xc027fe40 (unreliable)
[cf9d7f20] [c0280670] 0xc0280670
[cf9d7f60] [c0035d18] 0xc0035d18
[cf9d7f90] [c0036544] 0xc0036544
[cf9d7fd0] [c003b028] 0xc003b028
[cf9d7ff0] [c0012110] 0xc0012110
Instruction dump:
7c0004ac 914b0020 7c0004ac 900b0020 7d200124 4bd964cd 38800004 38630c08
4bd94925 3d20c049 90697198 3d20c048 <80030000> 5400003c 9009f374 90030000
---[ end trace 26b7d30f34dd75e6 ]---


What this error means and how to remove this error?

Mara 07-11-2010 12:10 PM

Do you allocate memory at every iteration? Is it possible that you get out of memory?

ravspratapsingh 07-12-2010 03:39 AM

Quote:

Originally Posted by Mara (Post 4029937)
Do you allocate memory at every iteration? Is it possible that you get out of memory?



No, I am not allocating memory at evry iteration. I have defined 3 arrays of 128Kb each globally and using same array in a while loop.

When I see cat /proc/meminfo before and after running the command, I see following difference and can't think why this is there.


Before

VmallocTotal: 737256 kB
VmallocUsed: 66196 kB
VmallocChunk: 670692 kB


After

VmallocTotal: 737256 kB
VmallocUsed: 401588 kB
VmallocChunk: 8 kB

Mara 07-17-2010 05:09 PM

VmallocChunk: 8 kB means that the biggest free block in virtual memory is 8K.... Something made half of your memory disappear or has overwritten the allocator structures. In both cases, there's a big bug somewhere. Can you see more differences in /proc/meminfo?

ravspratapsingh 07-20-2010 01:06 AM

Quote:

Originally Posted by Mara (Post 4036600)
VmallocChunk: 8 kB means that the biggest free block in virtual memory is 8K.... Something made half of your memory disappear or has overwritten the allocator structures. In both cases, there's a big bug somewhere. Can you see more differences in /proc/meminfo?

Hi,

I did not find any such issues. Where ever i am allocating memory I am freeing it. Following is the part of driver source code. It write routine which i am calling



static ssize_t
fm25_ee_write(struct fm25_data *fm25, char *buf, loff_t off, size_t count)
{
ssize_t status = 0;
unsigned written = 0;
unsigned buf_size;
u8 *bounce;

/* Temp buffer starts with command and address */
buf_size = 0x1000;
//buf_size = fm25->chip.page_size;
if (buf_size > io_limit)
{
buf_size = io_limit;
printk("RVSDBG iolimit %lx \n",io_limit);
}
bounce = kmalloc(buf_size + fm25->addrlen + 1, GFP_KERNEL);
// bounce = vmalloc(buf_size + fm25->addrlen +1);
if (!bounce){
printk("RVSDBG = %s bounce data =%d\n",__FUNCTION__,bounce);
return -ENOMEM;
}

/* For write, rollover is within the page ... so we write at
* most one page, then manually roll over to the next page.
*/
bounce[0] = fm25_WRITE;
mutex_lock(&fm25->lock);
do {
unsigned long timeout, retries;
unsigned segment;
unsigned offset = (unsigned) off;
u8 *cp = bounce + 1;

*cp = fm25_WREN;
status = spi_write(fm25->spi, cp, 1);
if (status < 0) {
dev_dbg(&fm25->spi->dev, "WREN --> %d\n",
(int) status);
break;
}

/* 8/16/24-bit address is written MSB first */
switch (fm25->addrlen) {
default: /* case 3 */
*cp++ = offset >> 16;
case 2:
*cp++ = offset >> 8;
case 1:
case 0: /* can't happen: for better codegen */
*cp++ = offset >> 0;
}

/* Write as much of a page as we can */
segment = buf_size - (offset % buf_size);
if (segment > count)
segment = count;
memcpy(cp, buf, segment);
status = spi_write(fm25->spi, bounce,
segment + fm25->addrlen + 1);

dev_dbg(&fm25->spi->dev,
"write %u bytes at %u --> %d\n",
segment, offset, (int) status);

if (status < 0)
break;

/* REVISIT this should detect (or prevent) failed writes
* to readonly sections of the EEPROM...
*/

/* Wait for non-busy status */
timeout = jiffies + msecs_to_jiffies(EE_TIMEOUT);
retries = 0;
do {
int sr;

sr = spi_w8r8(fm25->spi, fm25_RDSR);
if (sr < 0 || (sr & fm25_SR_nRDY)) {
dev_dbg(&fm25->spi->dev,
"rdsr --> %d (%02x)\n", sr, sr);
/* at HZ=100, this is sloooow */
msleep(1);
continue;
}
if (!(sr & fm25_SR_nRDY))
break;
} while (retries++ < 3 || time_before_eq(jiffies, timeout));

if (time_after(jiffies, timeout)) {
dev_err(&fm25->spi->dev,
"write %d bytes offset %d, "
"timeout after %u msecs\n",
segment, offset,
jiffies_to_msecs(jiffies -
(timeout - EE_TIMEOUT)));
printk("RVSDBG %s timeout\n",__FUNCTION__);
status = -ETIMEDOUT;
break;
}

off += segment;
buf += segment;
count -= segment;
written += segment;

} while (count > 0);

mutex_unlock(&fm25->lock);

kfree(bounce);
// vfree(bounce);
return written ? written : status;
}






and here is the part of aaplicaiton which i am calling to tst my driver



#include<string.h>

#include <sys/time.h>
#include <time.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
int dev_fd;
int count = 131072;
int ret_val = 0;
int i,offset,loop;

char temp[131072];
char tempread[131072];
char tempwrite[131072];
int num_of_byte_read = 0;
int iter = 0;

dev_fd = open("/sys/bus/spi/devices/spi32766.0/fram",O_RDWR);
if (dev_fd < 0)
{
perror(" device open err");
exit(-1);
}
while(1)
{
printf("iteration %d\t",iter);

/* Write */
printf("writing device\t");
memset(temp,0,131072);
memset(tempwrite,0,131072);
for(loop=0,offset=0;loop<32;loop++,offset ++)
{
for(i=0;i<4096;i++)
{
temp[i] = loop;
tempwrite[(4096*offset)+i] = loop;
}
lseek(dev_fd, (4096*offset), SEEK_SET);
ret_val = write(dev_fd,temp,count);
}
if(ret_val < 0)
{
perror("write err \n");
goto quit;
}
/* Read */
printf("Reading device\t");
memset(tempread,0,131072);
memset(temp,0,131072);
lseek(dev_fd, 0, SEEK_SET);
count = 131072;
do{
ret_val = read(dev_fd,temp,count);
// printf("ret_val : %d\n",ret_val);
count -= ret_val;
for(i=0;i<ret_val;i++)
tempread[i+num_of_byte_read] = temp[i];
#if 0
for(i=0;i<ret_val;i++)
{
printf("0x%x\t",tempread[i]);
}
#endif
num_of_byte_read += ret_val;
}while(ret_val != 0);
if(ret_val < 0)
{
perror("read err \n");
goto quit;
}
// printf("Total number of byte read :: %d\n",num_of_byte_read);
for(i=0;i<131072;i++)
{
if(tempread[i] != tempwrite[i])
{
printf("failed\n");
printf("at location 0x%x write : 0x%x\t read : 0x%x\n", i,tempwrite[i], tempread[i]);
goto quit;
}
}
printf("passed\n");
iter++;
num_of_byte_read = 0;
}
quit:
/* close the device file*/
close (dev_fd);

return ret_val;
}




All times are GMT -5. The time now is 07:25 PM.