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? |
Do you allocate memory at every iteration? Is it possible that you get out of memory?
|
Quote:
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 |
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?
|
Quote:
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 04:05 AM. |