public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* Memory leak
@ 2003-03-09 16:46 matsunaga
  2003-03-09 17:37 ` Charles Manning
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: matsunaga @ 2003-03-09 16:46 UTC (permalink / raw)
  To: linux-mtd

Hi all

I am testing on NAND flash.
There seems memory leak when you mount and unmount a device with some data.
Dnode resource acquired during mount seems not to be freed during unmount.

Best regards.
__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!  http://bb.yahoo.co.jp/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-09 16:46 Memory leak matsunaga
@ 2003-03-09 17:37 ` Charles Manning
  2003-03-09 19:10 ` Thomas Gleixner
  2003-03-11 17:50 ` David Woodhouse
  2 siblings, 0 replies; 17+ messages in thread
From: Charles Manning @ 2003-03-09 17:37 UTC (permalink / raw)
  To: linux-mtd

What file system are you using?
On Mon, 10 Mar 2003 05:46, matsunaga wrote:
> Hi all
>
> I am testing on NAND flash.
> There seems memory leak when you mount and unmount a device with some data.
> Dnode resource acquired during mount seems not to be freed during unmount.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-09 16:46 Memory leak matsunaga
  2003-03-09 17:37 ` Charles Manning
@ 2003-03-09 19:10 ` Thomas Gleixner
  2003-03-09 23:10   ` matsunaga
  2003-03-11 17:50 ` David Woodhouse
  2 siblings, 1 reply; 17+ messages in thread
From: Thomas Gleixner @ 2003-03-09 19:10 UTC (permalink / raw)
  To: linux-mtd

On Sunday 09 March 2003 17:46, matsunaga wrote:
> Hi all
>
> I am testing on NAND flash.
> There seems memory leak when you mount and unmount a device with some data.
> Dnode resource acquired during mount seems not to be freed during unmount.
This is not a Problem of NAND Flash. It's a filesystem related problem. 
Do you use JFFS2 ?
If yes, which Dnode resource do you mean ? Where is it allocated ? Can you 
please give more precise information ?

-- 
Thomas
________________________________________________________________________
linutronix - competence in embedded & realtime linux
http://www.linutronix.de
mail: tglx at linutronix.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-09 19:10 ` Thomas Gleixner
@ 2003-03-09 23:10   ` matsunaga
  2003-03-10 14:53     ` Thomas Gleixner
  0 siblings, 1 reply; 17+ messages in thread
From: matsunaga @ 2003-03-09 23:10 UTC (permalink / raw)
  To: linux-mtd

----- Original Message ----- 
From: "Thomas Gleixner" <tglx@linutronix.de>
To: "matsunaga" <matsunaga_kazuhisa@yahoo.co.jp>; <linux-mtd@lists.infradead.org>
Sent: Monday, March 10, 2003 4:10 AM
Subject: Re: Memory leak


> On Sunday 09 March 2003 17:46, matsunaga wrote:
> > Hi all
> >
> > I am testing on NAND flash.
> > There seems memory leak when you mount and unmount a device with some data.
> > Dnode resource acquired during mount seems not to be freed during unmount.
> This is not a Problem of NAND Flash. It's a filesystem related problem. 
> Do you use JFFS2 ?
> If yes, which Dnode resource do you mean ? Where is it allocated ? Can you 
> please give more precise information ?

Sorry for lacking details.

Yes, I use JFFS2. 
If you mount a device with a file on JFFS2, a dirent node and a dnode are alloced.
But upper layer does not issue, jffs2_clear_inode for an inode of the dnode during unmount.
You can see it just by free command if my implementation is not wrong.

Best regards.
__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!  http://bb.yahoo.co.jp/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-10 14:53     ` Thomas Gleixner
@ 2003-03-10 14:14       ` David Woodhouse
  2003-03-10 15:48         ` matsunaga
  2003-03-10 15:36       ` matsunaga
  1 sibling, 1 reply; 17+ messages in thread
From: David Woodhouse @ 2003-03-10 14:14 UTC (permalink / raw)
  To: linux-mtd

On Mon, 2003-03-10 at 14:53, Thomas Gleixner wrote:
> On Monday 10 March 2003 00:10, matsunaga wrote:
> > Yes, I use JFFS2.
> > If you mount a device with a file on JFFS2, a dirent node and a dnode are
> > alloced. But upper layer does not issue, jffs2_clear_inode for an inode of
> > the dnode during unmount. You can see it just by free command if my
> > implementation is not wrong.
> on umount put_super is called
> void jffs2_put_super (struct super_block *sb)
> {
> SNIP
> 	jffs2_free_ino_caches(c);
> 	jffs2_free_raw_node_refs(c);
> 	vfree(c->blocks);
> SNIP
> }
> So everything is freed there. Are you looking at the first line of output from 
> free (Mem:) ? Have a look at the second line (-/+ buffers/cache). If this is 
> worrying you too, then send output of free before mount and after umount.

If you can rmmod jffs2 without a BUG() then it's freed everything in its
own slabs, although it is theoretically possible that it's leaked
something kmalloc'd. Unlikely though.


-- 
dwmw2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-09 23:10   ` matsunaga
@ 2003-03-10 14:53     ` Thomas Gleixner
  2003-03-10 14:14       ` David Woodhouse
  2003-03-10 15:36       ` matsunaga
  0 siblings, 2 replies; 17+ messages in thread
From: Thomas Gleixner @ 2003-03-10 14:53 UTC (permalink / raw)
  To: linux-mtd

On Monday 10 March 2003 00:10, matsunaga wrote:
> Yes, I use JFFS2.
> If you mount a device with a file on JFFS2, a dirent node and a dnode are
> alloced. But upper layer does not issue, jffs2_clear_inode for an inode of
> the dnode during unmount. You can see it just by free command if my
> implementation is not wrong.
on umount put_super is called
void jffs2_put_super (struct super_block *sb)
{
SNIP
	jffs2_free_ino_caches(c);
	jffs2_free_raw_node_refs(c);
	vfree(c->blocks);
SNIP
}
So everything is freed there. Are you looking at the first line of output from 
free (Mem:) ? Have a look at the second line (-/+ buffers/cache). If this is 
worrying you too, then send output of free before mount and after umount.

-- 
Thomas
________________________________________________________________________
linutronix - competence in embedded & realtime linux
http://www.linutronix.de
mail: tglx at linutronix.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-10 14:53     ` Thomas Gleixner
  2003-03-10 14:14       ` David Woodhouse
@ 2003-03-10 15:36       ` matsunaga
  1 sibling, 0 replies; 17+ messages in thread
From: matsunaga @ 2003-03-10 15:36 UTC (permalink / raw)
  To: linux-mtd

Hi.

> On Monday 10 March 2003 00:10, matsunaga wrote:
> > Yes, I use JFFS2.
> > If you mount a device with a file on JFFS2, a dirent node and a dnode are
> > alloced. But upper layer does not issue, jffs2_clear_inode for an inode of
> > the dnode during unmount. You can see it just by free command if my
> > implementation is not wrong.
> on umount put_super is called
> void jffs2_put_super (struct super_block *sb)
> {
> SNIP
> jffs2_free_ino_caches(c);
> jffs2_free_raw_node_refs(c);
> vfree(c->blocks);
> SNIP
> }
> So everything is freed there.

Fragtree and the dnode resoure belongs to it are not freed there.

>  Are you looking at the first line of output from 
> free (Mem:) ? Have a look at the second line (-/+ buffers/cache). 
> If this is worrying you too, then send output of free before mount and after umount.

I will send the output later... not available now.. 
I am looking at amount of free area by free command.

If you have an environment, could you please check it with a device which is written a large file?
Because it might be just the problem of my environment...

Best regards.

__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!  http://bb.yahoo.co.jp/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-10 14:14       ` David Woodhouse
@ 2003-03-10 15:48         ` matsunaga
  2003-03-10 16:02           ` David Woodhouse
  0 siblings, 1 reply; 17+ messages in thread
From: matsunaga @ 2003-03-10 15:48 UTC (permalink / raw)
  To: linux-mtd

Hi


> On Mon, 2003-03-10 at 14:53, Thomas Gleixner wrote:
> > On Monday 10 March 2003 00:10, matsunaga wrote:
> > > Yes, I use JFFS2.
> > > If you mount a device with a file on JFFS2, a dirent node and a dnode are
> > > alloced. But upper layer does not issue, jffs2_clear_inode for an inode of
> > > the dnode during unmount. You can see it just by free command if my
> > > implementation is not wrong.
> > on umount put_super is called
> > void jffs2_put_super (struct super_block *sb)
> > {
> > SNIP
> > jffs2_free_ino_caches(c);
> > jffs2_free_raw_node_refs(c);
> > vfree(c->blocks);
> > SNIP
> > }
> > So everything is freed there. Are you looking at the first line of output from 
> > free (Mem:) ? Have a look at the second line (-/+ buffers/cache). If this is 
> > worrying you too, then send output of free before mount and after umount.
> 
> If you can rmmod jffs2 without a BUG() then it's freed everything in its
> own slabs, although it is theoretically possible that it's leaked
> something kmalloc'd. Unlikely though.

It is correct that rmmod will resolve it, but my concern is a consistency of resource and memory saving.
Dnode resource acuqired during mount seems not to be refereneced when you access to the file.
 
Best regards.

__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!  http://bb.yahoo.co.jp/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-10 15:48         ` matsunaga
@ 2003-03-10 16:02           ` David Woodhouse
  2003-03-10 16:26             ` matsunaga
  0 siblings, 1 reply; 17+ messages in thread
From: David Woodhouse @ 2003-03-10 16:02 UTC (permalink / raw)
  To: linux-mtd

On Mon, 2003-03-10 at 15:48, matsunaga wrote:

> It is correct that rmmod will resolve it, but my concern is a
> consistency of resource and memory saving.
> Dnode resource acuqired during mount seems not to be refereneced when
> you access to the file.

No. My point is _not_ that rmmod will resolve it, rather that rmmod will
complain _loudly_ if there are slab resources still allocated when you
try to unload the module. You'll then be unable to reload the module at
all, if I recall correctly.

-- 
dwmw2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-10 16:02           ` David Woodhouse
@ 2003-03-10 16:26             ` matsunaga
  2003-03-10 17:04               ` David Woodhouse
  0 siblings, 1 reply; 17+ messages in thread
From: matsunaga @ 2003-03-10 16:26 UTC (permalink / raw)
  To: linux-mtd

> On Mon, 2003-03-10 at 15:48, matsunaga wrote:
> 
> > It is correct that rmmod will resolve it, but my concern is a
> > consistency of resource and memory saving.
> > Dnode resource acuqired during mount seems not to be refereneced when
> > you access to the file.
> 
> No. My point is _not_ that rmmod will resolve it, rather that rmmod will
> complain _loudly_ if there are slab resources still allocated when you
> try to unload the module. You'll then be unable to reload the module at
> all, if I recall correctly.

You are correct again ;-)
  kmem_cache_destroy(full_dnode_slab);
and
  kmem_cache_destroy(node_frag_slab);
return error.
__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!  http://bb.yahoo.co.jp/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-10 16:26             ` matsunaga
@ 2003-03-10 17:04               ` David Woodhouse
  2003-03-11 15:52                 ` matsunaga
  0 siblings, 1 reply; 17+ messages in thread
From: David Woodhouse @ 2003-03-10 17:04 UTC (permalink / raw)
  To: linux-mtd

On Mon, 2003-03-10 at 16:26, matsunaga wrote:
> You are correct again ;-)
>   kmem_cache_destroy(full_dnode_slab);
> and
>   kmem_cache_destroy(node_frag_slab);
> return error.

Aha, that's good. You're saying they _do_ return an error?

Please compile with CONFIG_JFFS2_FS_DEBUG=1 and capture all the messages
over a serial console. Add a printk to the allocation and free routines
for both the full_dnode and node_frag structures to print the address
which is allocated/freed. Then we can compare and find where structures
are allocated but not freed.

What exactly do you need to do to trigger this? Is it something special
about the particular file system image on your device?

-- 
dwmw2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-10 17:04               ` David Woodhouse
@ 2003-03-11 15:52                 ` matsunaga
  2003-03-11 18:39                   ` Thomas Gleixner
  0 siblings, 1 reply; 17+ messages in thread
From: matsunaga @ 2003-03-11 15:52 UTC (permalink / raw)
  To: linux-mtd

> Aha, that's good. You're saying they _do_ return an error?

They actually stall in BUG() dumping unfreed addresses.
 
> Please compile with CONFIG_JFFS2_FS_DEBUG=1 and capture all the messages
> over a serial console. Add a printk to the allocation and free routines
> for both the full_dnode and node_frag structures to print the address
> which is allocated/freed. Then we can compare and find where structures
> are allocated but not freed.

I attached message at the end.
I added "##m" for my original line.
No dnode resoure (ino #2) is freed during unmount.
 
> What exactly do you need to do to trigger this? Is it something special
> about the particular file system image on your device?

I think that dnode resouce need not be aquired during mount for upper fs layer.
It just wastes resource. 
This is not in the message, but if you read a file written before mount, 
dnode resource is newly aquired aside from that of aquired during mount(This could be dangerous).
Dnode resource aquired during read operation is freed when unmounting.

And if you write a file and unmount, no memory leak occur for the file.

Gc may need the dnode resouce when mounting, so in that case, some solution should be considered.

BR.

# cat /proc/meminfo
        total:    used:    free:  shared: buffers:  cached:
Mem:  58232832 40869888 17362944        0   249856 36564992
Swap:        0        0        0
MemTotal:        56868 kB
MemFree:         16956 kB
MemShared:           0 kB
Buffers:           244 kB
Cached:          35708 kB
SwapCached:          0 kB
Active:           1684 kB
Inactive:        35020 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:        56868 kB
LowFree:         16956 kB
SwapTotal:           0 kB
SwapFree:            0 kB
# 
# mount -t jffs2 /dev/mtdblock1 /mnt/nand1
jffs2: read_super for device 1f:01
jffs2: Erase block size too small (16KiB). Using virtual blocks size (32KiB) instead
Allocating readbuf of 32768 bytes
jffs2_scan_eraseblock(): Scanning block at 0x0
jffs2_scan_eraseblock(): Scanning block at 0x8000
jffs2_scan_eraseblock(): Scanning block at 0x10000
jffs2_scan_eraseblock(): Scanning block at 0x18000
jffs2_scan_eraseblock(): Scanning block at 0x20000
jffs2_scan_eraseblock(): Scanning block at 0x28000
jffs2_scan_inode_node(): Node at 0x00028000
Allocated inocache at 81ec8278
Node is ino #2, version 1. Range 0x0-0x0
jffs2_scan_dirent_node(): Node at 0x00028044
Allocated inocache at 81ec8260
jffs2_add_fd_to_list( 83e92600, 81ec8260 (->00000000))
jffs2_scan_inode_node(): Node at 0x00028070
Node is ino #2, version 2. Range 0x0-0x1000
Fewer than %zd bytes (node header) left to end of buf. Reading 0xc at 0x000078a0
jffs2_scan_inode_node(): Node at 0x00028760
Node is ino #2, version 3. Range 0x1000-0x2000
jffs2_scan_inode_node(): Node at 0x00028e48
Node is ino #2, version 4. Range 0x2000-0x3000
jffs2_scan_inode_node(): Node at 0x000293dc
Node is ino #2, version 5. Range 0x3000-0x4000
jffs2_scan_inode_node(): Node at 0x00029a54
Node is ino #2, version 6. Range 0x4000-0x5000
jffs2_scan_inode_node(): Node at 0x0002a1bc
Node is ino #2, version 7. Range 0x5000-0x6000
jffs2_scan_inode_node(): Node at 0x0002a984
Node is ino #2, version 8. Range 0x6000-0x7000
jffs2_scan_inode_node(): Node at 0x0002b0fc
Node is ino #2, version 9. Range 0x7000-0x8000
jffs2_scan_inode_node(): Node at 0x0002b7d8
Node is ino #2, version 10. Range 0x8000-0x9000
jffs2_scan_inode_node(): Node at 0x0002bdfc
Node is ino #2, version 11. Range 0x9000-0xa000
jffs2_scan_inode_node(): Node at 0x0002c4e4
Node is ino #2, version 12. Range 0xa000-0xb000
jffs2_scan_inode_node(): Node at 0x0002ca18
Node is ino #2, version 13. Range 0xb000-0xc000
jffs2_scan_inode_node(): Node at 0x0002d310
Node is ino #2, version 14. Range 0xc000-0xd000
jffs2_scan_inode_node(): Node at 0x0002dc18
Node is ino #2, version 15. Range 0xd000-0xe000
jffs2_scan_inode_node(): Node at 0x0002e344
Node is ino #2, version 16. Range 0xe000-0xf000
jffs2_scan_inode_node(): Node at 0x0002eba0
Node is ino #2, version 17. Range 0xf000-0x10000
jffs2_scan_inode_node(): Node at 0x0002f3e0
Node is ino #2, version 18. Range 0x10000-0x11000
jffs2_scan_inode_node(): Node at 0x0002f7dc
Node is ino #2, version 19. Range 0x11000-0x12000
jffs2_scan_inode_node(): Node at 0x0002fbf8
Node is ino #2, version 20. Range 0x12000-0x124a8
Block at 0x00028000: free 0x00000000, dirty 0x000001b0, unchecked 0x00007e24, used 0x0000002c
jffs2_scan_eraseblock(): Scanning block at 0x30000
Scanned flash completely
jffs2_dump_block_lists:
flash_size: 0003aa00
used_size: 0000002c
dirty_size: 000001b0
wasted_size: 00000000
unchecked_size: 00007e24
free_size: 00032a00
erasing_size: 00000000
bad_size: 00000000
sector_size: 00008000
jffs2_reserved_blocks size: 00028000
nextblock: NULL
gcblock: NULL
clean_list: empty
very_dirty_list: empty
dirty_list: 00028000 (used 0000002c, dirty 000001b0, wasted 00000000, unchecked 00007e24, free 00000000)
Contains 1 blocks with total dirty size 432, average dirty size: 432
erasable_list: empty
erasing_list: empty
erase_pending_list: empty
erasable_pending_wbuf_list: empty
free_list: 00030000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00020000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00018000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00010000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00008000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00000000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
bad_list: empty
bad_used_list: empty
Pass 1: ino #1
jffs2_build_inode building inode #1
Increased nlink for child "sed" (ino #2)
Pass 1: ino #2
jffs2_build_inode building inode #2
Pass 1 complete
jffs2_dump_block_lists:
flash_size: 0003aa00
used_size: 0000002c
dirty_size: 000001b0
wasted_size: 00000000
unchecked_size: 00007e24
free_size: 00032a00
erasing_size: 00000000
bad_size: 00000000
sector_size: 00008000
jffs2_reserved_blocks size: 00028000
nextblock: NULL
gcblock: NULL
clean_list: empty
very_dirty_list: empty
dirty_list: 00028000 (used 0000002c, dirty 000001b0, wasted 00000000, unchecked 00007e24, free 00000000)
Contains 1 blocks with total dirty size 432, average dirty size: 432
erasable_list: empty
erasing_list: empty
erase_pending_list: empty
erasable_pending_wbuf_list: empty
free_list: 00030000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00020000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00018000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00010000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00008000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00000000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
bad_list: empty
bad_used_list: empty
Pass 2 (re)starting
Pass 2: ino #1, nlink 1, ic 81ec8260, nodes 81ed7470
Pass 2: ino #2, nlink 1, ic 81ec8278, nodes 81ed7340
jffs2_dump_block_lists:
flash_size: 0003aa00
used_size: 0000002c
dirty_size: 000001b0
wasted_size: 00000000
unchecked_size: 00007e24
free_size: 00032a00
erasing_size: 00000000
bad_size: 00000000
sector_size: 00008000
jffs2_reserved_blocks size: 00028000
nextblock: NULL
gcblock: NULL
clean_list: empty
very_dirty_list: empty
dirty_list: 00028000 (used 0000002c, dirty 000001b0, wasted 00000000, unchecked 00007e24, free 00000000)
Contains 1 blocks with total dirty size 432, average dirty size: 432
erasable_list: empty
erasing_list: empty
erase_pending_list: empty
erasable_pending_wbuf_list: empty
free_list: 00030000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00020000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00018000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00010000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00008000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00000000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
bad_list: empty
bad_used_list: empty
Pass 2 complete
Pass 3: ino #1, ic 81ec8260, nodes 81ed7470
Pass 3: ino #2, ic 81ec8278, nodes 81ed7340
Pass 3 complete
jffs2_dump_block_lists:
flash_size: 0003aa00
used_size: 0000002c
dirty_size: 000001b0
wasted_size: 00000000
unchecked_size: 00007e24
free_size: 00032a00
erasing_size: 00000000
bad_size: 00000000
sector_size: 00008000
jffs2_reserved_blocks size: 00028000
nextblock: NULL
gcblock: NULL
clean_list: empty
very_dirty_list: empty
dirty_list: 00028000 (used 0000002c, dirty 000001b0, wasted 00000000, unchecked 00007e24, free 00000000)
Contains 1 blocks with total dirty size 432, average dirty size: 432
erasable_list: empty
erasing_list: empty
erase_pending_list: empty
erasable_pending_wbuf_list: empty
free_list: 00030000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00020000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00018000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00010000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00008000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
free_list: 00000000 (used 00000000, dirty 00000000, wasted 00000000, unchecked 00000000, free 00008000)
bad_list: empty
bad_used_list: empty
Not rotating empty clean_list
Not rotating empty very_dirty_list
Rotating dirty_list by 0
Erase block at front of dirty_list is at 00028000
Not rotating empty erasable_list
Not rotating empty erase_pending_list
Rotating free_list by 1
Erase block at front of free_list is at 00018000
jffs2_do_fill_super(): Getting root inode
jffs2_read_inode(): inode->i_ino == 1
jffs2_do_read_inode_internal(): ino #1 nlink is 1
jffs2_get_inode_nodes(): ino #1
Node at 00028044 (2) is a dirent node
Adding fd "sed", ino #2
jffs2_add_fd_to_list( 83e92600, 81ec7bdc (->00000000))
jffs2_read_inode() returning
jffs2_do_fill_super(): d_alloc_root()
JFFS2: Garbage collect thread is pid 207
thread_should_wake(): unchecked_size 32292, checked_ino #0
jffs2_garbage_collect_thread(): pass
Skipping ino #1 already checked
jffs2_garbage_collect_pass() triggering inode scan of ino#2
jffs2_do_read_inode_internal(): ino #2 nlink is 1
jffs2_get_inode_nodes(): ino #2
# Node at 0002fbf8 (0) is a data node
version 20, highest_version now 20
Marking node at 0x0002fbf8 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed63b0 
dnode @0002fbf8: ver 20, offset 12000, dsize 04a8
Node at 0002f7dc (0) is a data node
version 19, highest_version now 20
Marking node at 0x0002f7dc REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed63f0 
dnode @0002f7dc: ver 19, offset 11000, dsize 1000
Node at 0002f3e0 (0) is a data node
version 18, highest_version now 20
Marking node at 0x0002f3e0 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6410 
dnode @0002f3e0: ver 18, offset 10000, dsize 1000
Node at 0002eba0 (0) is a data node
version 17, highest_version now 20
Marking node at 0x0002eba0 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6430 
dnode @0002eba0: ver 17, offset f000, dsize 1000
Node at 0002e344 (0) is a data node
version 16, highest_version now 20
Marking node at 0x0002e344 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6450 
dnode @0002e344: ver 16, offset e000, dsize 1000
Node at 0002dc18 (0) is a data node
version 15, highest_version now 20
Marking node at 0x0002dc18 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6460 
dnode @0002dc18: ver 15, offset d000, dsize 1000
Node at 0002d310 (0) is a data node
version 14, highest_version now 20
Marking node at 0x0002d310 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6440 
dnode @0002d310: ver 14, offset c000, dsize 1000
Node at 0002ca18 (0) is a data node
version 13, highest_version now 20
Marking node at 0x0002ca18 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6420 
dnode @0002ca18: ver 13, offset b000, dsize 1000
Node at 0002c4e4 (0) is a data node
version 12, highest_version now 20
Marking node at 0x0002c4e4 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6400 
dnode @0002c4e4: ver 12, offset a000, dsize 1000
Node at 0002bdfc (0) is a data node
version 11, highest_version now 20
Marking node at 0x0002bdfc REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed63d0 
dnode @0002bdfc: ver 11, offset 9000, dsize 1000
Node at 0002b7d8 (0) is a data node
version 10, highest_version now 20
Marking node at 0x0002b7d8 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed63e0 
dnode @0002b7d8: ver 10, offset 8000, dsize 1000
Node at 0002b0fc (0) is a data node
version 9, highest_version now 20
Marking node at 0x0002b0fc REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed63c0 
dnode @0002b0fc: ver 9, offset 7000, dsize 1000
Node at 0002a984 (0) is a data node
version 8, highest_version now 20
Marking node at 0x0002a984 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6370 
dnode @0002a984: ver 8, offset 6000, dsize 1000
Node at 0002a1bc (0) is a data node
version 7, highest_version now 20
Marking node at 0x0002a1bc REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6390 
dnode @0002a1bc: ver 7, offset 5000, dsize 1000
Node at 00029a54 (0) is a data node
version 6, highest_version now 20
Marking node at 0x00029a54 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed63a0 
dnode @00029a54: ver 6, offset 4000, dsize 1000
Node at 000293dc (0) is a data node
version 5, highest_version now 20
Marking node at 0x000293dc REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6380 
dnode @000293dc: ver 5, offset 3000, dsize 1000
Node at 00028e48 (0) is a data node
version 4, highest_version now 20
Marking node at 0x00028e48 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6340 
dnode @00028e48: ver 4, offset 2000, dsize 1000
Node at 00028760 (0) is a data node
version 3, highest_version now 20
Marking node at 0x00028760 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6360 
dnode @00028760: ver 3, offset 1000, dsize 1000
Node at 00028070 (0) is a data node
version 2, highest_version now 20
Marking node at 0x00028070 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6350 
dnode @00028070: ver 2, offset 0000, dsize 1000
Node at 00028000 (0) is a data node
version 1, highest_version now 20
Marking node at 0x00028000 REF_PRISTINE
##m jffs2_alloc_full_dnode at 0x81ed6470 
dnode @00028000: ver 1, offset 0000, dsize 0000
metadata @00028000: ver 1
Obsoleting old metadata at 0x00028000
Obsoleting node at 0x00028000 of len 44: Dirtying
Eraseblock at 0x00028000 not moved anywhere. (free 0x00000000, dirty 0x000001f4, used 0x00007e0c)
##m jffs2_free_full_dnode at 0x81ed6470 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6350)
##m jffs2_alloc_node_frag at 0x81ebf2e4 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6360)
##m jffs2_alloc_node_frag at 0x81ebf354 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6340)
##m jffs2_alloc_node_frag at 0x81ebf38c 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6380)
##m jffs2_alloc_node_frag at 0x81ebf3c4 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed63a0)
##m jffs2_alloc_node_frag at 0x81ebf3fc 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6390)
##m jffs2_alloc_node_frag at 0x81ebf418 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6370)
##m jffs2_alloc_node_frag at 0x81ebf3e0 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed63c0)
##m jffs2_alloc_node_frag at 0x81ebf3a8 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed63e0)
##m jffs2_alloc_node_frag at 0x81ebf370 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed63d0)
##m jffs2_alloc_node_frag at 0x81ebf31c 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6400)
##m jffs2_alloc_node_frag at 0x81ebf338 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6420)
##m jffs2_alloc_node_frag at 0x81ebf300 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6440)
##m jffs2_alloc_node_frag at 0x81ebf274 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6460)
##m jffs2_alloc_node_frag at 0x81ebf2ac 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6450)
##m jffs2_alloc_node_frag at 0x81ebf2c8 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6430)
##m jffs2_alloc_node_frag at 0x81ebf290 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed6410)
##m jffs2_alloc_node_frag at 0x81ebf23c 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed63f0)
##m jffs2_alloc_node_frag at 0x81ebf258 
jffs2_add_full_dnode_to_inode(ino #2, f 80b6ff60, fn 81ed63b0)
##m jffs2_alloc_node_frag at 0x81ebf220 
Truncating fraglist to 0x000124a8 bytes
Truncating frag 0x00012000-0x000124a8
thread_should_wake(): nr_free_blocks 6, nr_erasing_blocks 0, dirty_size 0x1f4: no
jffs2_garbage_collect_thread sleeping...

# 
# umount /dev/mtdblock1
jffs2_clear_inode(): ino #1 mode 40755
jffs2: Killing GC task 207
jffs2_garbage_collect_thread(): SIGKILL received.
Freeing inocache at 81ec8260
Freeing inocache at 81ec8278
jffs2_put_super returning
# 
# cat /proc/meminfo
        total:    used:    free:  shared: buffers:  cached:
Mem:  58232832 40878080 17354752        0   249856 36564992
Swap:        0        0        0
MemTotal:        56868 kB
MemFree:         16948 kB
MemShared:           0 kB
Buffers:           244 kB
Cached:          35708 kB
SwapCached:          0 kB
Active:           1684 kB
Inactive:        35020 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:        56868 kB
LowFree:         16948 kB
SwapTotal:           0 kB
SwapFree:            0 kB
# 
# 
#
__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!  http://bb.yahoo.co.jp/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-09 16:46 Memory leak matsunaga
  2003-03-09 17:37 ` Charles Manning
  2003-03-09 19:10 ` Thomas Gleixner
@ 2003-03-11 17:50 ` David Woodhouse
  2003-03-12 15:47   ` dnode of meta data matsunaga
  2 siblings, 1 reply; 17+ messages in thread
From: David Woodhouse @ 2003-03-11 17:50 UTC (permalink / raw)
  To: linux-mtd

On Sun, 2003-03-09 at 16:46, matsunaga wrote:
> I am testing on NAND flash.
> There seems memory leak when you mount and unmount a device with some data.
> Dnode resource acquired during mount seems not to be freed during unmount.

Mea Culpa. It was introduced with the latest round of GC/crc changes. It
should be fixed in CVS now.


-- 
dwmw2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
  2003-03-11 15:52                 ` matsunaga
@ 2003-03-11 18:39                   ` Thomas Gleixner
  0 siblings, 0 replies; 17+ messages in thread
From: Thomas Gleixner @ 2003-03-11 18:39 UTC (permalink / raw)
  To: linux-mtd

On Tuesday 11 March 2003 16:52, matsunaga wrote:
> > Aha, that's good. You're saying they _do_ return an error?
It should be fixed now.
CVS up

-- 
Thomas
________________________________________________________________________
linutronix - competence in embedded & realtime linux
http://www.linutronix.de
mail: tglx at linutronix.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

* dnode of meta data
  2003-03-11 17:50 ` David Woodhouse
@ 2003-03-12 15:47   ` matsunaga
  2003-03-13  7:14     ` David Woodhouse
  0 siblings, 1 reply; 17+ messages in thread
From: matsunaga @ 2003-03-12 15:47 UTC (permalink / raw)
  To: linux-mtd

> > I am testing on NAND flash.
> > There seems memory leak when you mount and unmount a device with some data.
> > Dnode resource acquired during mount seems not to be freed during unmount.
> 
> Mea Culpa. It was introduced with the latest round of GC/crc changes. It
> should be fixed in CVS now.

Thank you for the quick reaction. I would apreciate it.
By the way, if you write a file, a dnode of meta data is written and obsoleted just after that.
It consumes flash area(not much though) and might be caused by old fasioned format, 
but could the process be omitted in advance?

BR.
__________________________________________________
Do You Yahoo!?
Yahoo! BB is Broadband by Yahoo!  http://bb.yahoo.co.jp/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* dnode of meta data
  2003-03-12 15:47   ` dnode of meta data matsunaga
@ 2003-03-13  7:14     ` David Woodhouse
  0 siblings, 0 replies; 17+ messages in thread
From: David Woodhouse @ 2003-03-13  7:14 UTC (permalink / raw)
  To: linux-mtd

On Wed, 2003-03-12 at 15:47, matsunaga wrote:
> Thank you for the quick reaction. I would apreciate it.
> By the way, if you write a file, a dnode of meta data is written and obsoleted just after that.
> It consumes flash area(not much though) and might be caused by old fasioned format, 
> but could the process be omitted in advance?

Not easily. When you open and write a file, there are two separate
system calls -- open() and write().

JFFS2 is entirely synchronous -- we ensure that the results of a system
call have hit the medium before we return to the user. So optimising out
the 'metadata' node which holds the permissions and timestamps etc. of
the new file, and which exists before any data are written, isn't very
easy.

-- 
dwmw2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Memory leak
@ 2008-04-09 13:54 hinko.kocevar
  0 siblings, 0 replies; 17+ messages in thread
From: hinko.kocevar @ 2008-04-09 13:54 UTC (permalink / raw)
  To: Linux MTD

Hello,

I've ported 2.6.12 NAND module driver for our board to git tree version
(2.6.25-rc8). While testing the module, I've noticed that memory gets
eaten with each insmod/rmmod cycle. Eg. in ~12 minutes Slab consumption
rises from 1632 kB to 8584 kB, which is soon fatal for our embedded
system with 16megs of ram.

In my NAND driver only mtd_info and nand_chip structs are allocated in
module init, and accordingly released in module cleanup. Step by step
commenting lines in init/cleanup I came up with the conclusion that if
my drivers calls add_mtd_partition(), it leaks! If I comment out call to
add_mtd_partition() no more leaks are seen!?!?!

Quick inspectiion of /proc/slabinfo shows that 'sysfs_dir_cache' entry
'active_objs' rises from 3788 to 10800 - which is suspicious.

I've attached /proc/meminfo and /proc/slabinfo for my test, which does:
while c < 100
 insmod nand driver
 rmmod nand driver
 save meminfo
 save slabinfo
 inc c
done

I've put the dumps on the public FTP server for you to retrieve (size
71940 b):
http://4thway.0catch.com/dumps.zip

Attached is out NAND driver ported to 2.6.25-rc8.
---
/*
 *  drivers/mtd/nand/carneol.c
 *
 *  Copyright (C) 2005 Simon Posnjak (simon.posnjak@cetrtapot.si)
 *
 *  Based on :
 *    drivers/mtd/nand/spia.c
 *    Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
 *
 * Pin fliping code was "borowed" from Hinko Kocevar's TCS2301 driver
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *  Overview:
 *   This is a device driver for the NAND flash device found on the
 *   Carneol board which utilizes the Toshiba TC58 part.
 */

#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
#include <linux/platform_device.h>
#else
#include <linux/config.h>
#endif

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/fs.h>

#include <asm/io.h>
#include <asm/cpot/carneol-platform.h>

static unsigned char mod_name[]		= "carneol-nand";
static unsigned char mod_version[]	= "08040801";

static struct mtd_info *tc58512_mtd = NULL;


/*
 * All NAND flash signals are connected to cris PGx ports.
 */

/*
 * Data signals are on PG1 port pins b0 - b7. Direction of data pins must be
 * set before starting byte read/write operation on data pins.
 */
//#define TC58512_DATA		CARNEOL_PG1		/* PORTG b8 - b15 */
//#define TC58512_DATA0	CARNEOL_PG1_IO0	/* PORTG b8 */
//#define TC58512_DATA1	CARNEOL_PG1_IO1	/* PORTG b9 */
//#define TC58512_DATA2	CARNEOL_PG1_IO2	/* PORTG b10 */
//#define TC58512_DATA3	CARNEOL_PG1_IO3	/* PORTG b11 */
//#define TC58512_DATA4	CARNEOL_PG1_IO4	/* PORTG b12 */
//#define TC58512_DATA5	CARNEOL_PG1_IO5	/* PORTG b13 */
//#define TC58512_DATA6	CARNEOL_PG1_IO6	/* PORTG b14 */
//#define TC58512_DATA7	CARNEOL_PG1_IO7	/* PORTG b15 */

/*
 * Control signals are on PG2 port pins b1 - b6. Direction of control pins
 * is set to output in init stage.
 *
 * NOTE: PG2 pins b0 and b7 are not used for NAND flash!
 */
//#define TC58512_CTRL		CARNEOL_PG2		/* PORTG b16 - b23 */
//#define TC58512_RE		CARNEOL_PG2_IO1	/* PORTG b17 */
//#define TC58512_CE		CARNEOL_PG2_IO2	/* PORTG b18 */
//#define TC58512_CLE		CARNEOL_PG2_IO3	/* PORTG b19 */
//#define TC58512_ALE		CARNEOL_PG2_IO4	/* PORTG b20 */
//#define TC58512_WE		CARNEOL_PG2_IO5	/* PORTG b21 */
//#define TC58512_WP		CARNEOL_PG2_IO6	/* PORTG b22 */

/*
 * Status signal (chip ready) is on PG3 pin b0. Direction of status pin
 * is set to input in init stage.
 */
//#define TC58512_STATUS	CARNEOL_PG3		/* PORTG b24 - b31 */
//#define TC58512_RYBY		CARNEOL_PG3_IO0	/* PORTG b24 */

#if defined(CONFIG_CPOT_PLATFORM_AFC2)
const static struct mtd_partition partition_info[] =
{
	{
	 .name = "Carneol NAND part1 (program)",
	 .offset = 0,
	 .size = 4 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part2 (dataout)",
	 .offset = 4 * 1024 * 1024,
	 .size = 4 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part3 (datain)",
	 .offset = 8	* 1024 * 1024,
	 .size = 4 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part4 (backup)",
	 .offset = 12 * 1024 * 1024,
	 .size = 8 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part5 (upgrade)",
	 .offset = 20 * 1024 * 1024,
	 .size = 8 * 1024 * 1024
	}
};
#define NUM_PARTITIONS 5
#elif defined(CONFIG_CPOT_PLATFORM_CDU2)
const static struct mtd_partition partition_info[] =
{
	{
	 .name = "Carneol NAND part1 (program)",
	 .offset = 0,
	 .size = 4 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part2 (dataout)",
	 .offset = 4 * 1024 * 1024,
	 .size = 4 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part3 (datain)",
	 .offset = 8	* 1024 * 1024,
	 .size = 4 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part4 (disk1)",
	 .offset = 12	* 1024 * 1024,
	 .size = 8 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part5 (disk2)",
	 .offset = 20	* 1024 * 1024,
	 .size = 8 * 1024 * 1024
	},
	{
	 .name = "Carneol NAND part4 (backup)",
	 .offset = 28	* 1024 * 1024,
	 .size = 4 * 1024 * 1024
	},

};
#define NUM_PARTITIONS 6
#elif defined(CONFIG_CPOT_PLATFORM_TAA2)
const static struct mtd_partition partition_info[] =
{
	{
	 .name = "Carneol NAND part1 (program)",
	 .offset = 0,
	 .size = 4 * 1024 * 1024,
	},
	{
	 .name = "Carneol NAND part2 (dataout)",
	 .offset = 4 * 1024 * 1024,
	 .size = 8 * 1024 * 1024,
	},
	{
	 .name = "Carneol NAND part3 (datain)",
	 .offset = 12	* 1024 * 1024,
	 .size = 8 * 1024 * 1024,
	},
	{
	 .name = "Carneol NAND part4 (lib)",
	 .offset = 20 * 1024 * 1024,
	 .size = 8 * 1024 * 1024,
	},
	{
	 .name = "Carneol NAND part5 (usr)",
	 .offset = 28 * 1024 * 1024,
	 .size = 4 * 1024 * 1024,
	},
};
#define NUM_PARTITIONS 5
#endif	/* CONFIG_CPOT_PLATFORM_AFC2, CDU2, TAA2 */

static u_char tc58512_read_byte (struct mtd_info *mtd);
static void tc58512_write_byte (struct mtd_info *mtd, u_char byte);
static void tc58512_write_buf (struct mtd_info *mtd, const u_char * buf,
int len);
static void tc58512_read_buf (struct mtd_info *mtd, u_char * buf, int len);
static int tc58512_verify_buf (struct mtd_info *mtd, const u_char * buf,
int len);


#if 0
57 /* Select the chip by setting nCE to low */
58 #define NAND_NCE								0x01
59 /* Select the command latch by setting CLE to high */
60 #define NAND_CLE								0x02
61 /* Select the address latch by setting ALE to high */
62 #define NAND_ALE								0x04
63
64 #define NAND_CTRL_CLE					 (NAND_NCE | NAND_CLE)
65 #define NAND_CTRL_ALE					 (NAND_NCE | NAND_ALE)
66 #define NAND_CTRL_CHANGE				0x80
#endif

static void tc58512_cmd_ctrl (struct mtd_info *mtd, int cmd, unsigned
int ctrl)
{
	if (ctrl & NAND_CTRL_CHANGE)
	{
		if (ctrl & NAND_NCE)
			//carneol_pin_low(TC58512_CTRL, TC58512_CE);
			carneol_low_pg_18();
		else
			//carneol_pin_high(TC58512_CTRL, TC58512_CE);
			carneol_high_pg_18();

		if (ctrl & NAND_CLE)
			//carneol_pin_high(TC58512_CTRL, TC58512_CLE);
			carneol_high_pg_19();
		else
			//carneol_pin_low(TC58512_CTRL, TC58512_CLE);
			carneol_low_pg_19();
	
		if (ctrl & NAND_ALE)
			//carneol_pin_high(TC58512_CTRL, TC58512_ALE);
			carneol_high_pg_20();
		else
			//carneol_pin_low(TC58512_CTRL, TC58512_ALE);
			carneol_low_pg_20();
	}

	if (cmd != NAND_CMD_NONE)
	{
		tc58512_write_byte(mtd, (unsigned char)cmd);
	}
}

static int tc58512_device_ready (struct mtd_info *mtd)
{
	/* 1 - chip is ready, 0 - chip is busy. */
	//return (int) (carneol_pin_level(TC58512_STATUS, TC58512_RYBY));
	return carneol_is_high_pg_24();
}

static u_char tc58512_read_byte (struct mtd_info *mtd)
{
	u_int8_t val;

	//carneol_port_input(TC58512_DATA);
	carneol_input_pg_8();
	//carneol_pin_low(TC58512_CTRL, TC58512_RE);
	carneol_low_pg_17();

	//val = (unsigned char) carneol_port_read(TC58512_DATA);
	val = carneol_read_pg1();
	//carneol_pin_high(TC58512_CTRL, TC58512_RE);
	carneol_high_pg_17();

	return val;
}

static void tc58512_write_byte (struct mtd_info *mtd, u_char byte)
{
	//carneol_port_output(TC58512_DATA);
	carneol_output_pg_8();
	
	//carneol_port_write(TC58512_DATA, (unsigned char)byte);
	carneol_write_pg1((u_int8_t) byte);
		
	//carneol_pin_low(TC58512_CTRL, TC58512_WE);
	carneol_low_pg_21();
	//carneol_pin_high(TC58512_CTRL, TC58512_WE);
	carneol_high_pg_21();
}

static void tc58512_write_buf (struct mtd_info *mtd, const u_char * buf,
int len)
{
	int i;

	//carneol_port_output(TC58512_DATA);
	carneol_output_pg_8();

	for (i = 0; i < len; i++)
	{
		//carneol_port_write(TC58512_DATA, (unsigned char)buf[i]);
		carneol_write_pg1((u_int8_t) buf[i]);
		//carneol_pin_low(TC58512_CTRL, TC58512_WE);
		carneol_low_pg_21();
		//carneol_pin_high(TC58512_CTRL, TC58512_WE);
		carneol_high_pg_21();
	}
}

static void tc58512_read_buf (struct mtd_info *mtd, u_char * buf, int len)
{
	int i;

	//carneol_port_input(TC58512_DATA);
	carneol_input_pg_8();

	for (i = 0; i < len; i++)
	{
		//carneol_pin_low(TC58512_CTRL, TC58512_RE);
		carneol_low_pg_17();
		//buf[i] = (unsigned char) carneol_port_read(TC58512_DATA);
		buf[i] = carneol_read_pg1();
		//carneol_pin_high(TC58512_CTRL, TC58512_RE);
		carneol_high_pg_17();
	}
}

static int tc58512_verify_buf (struct mtd_info *mtd, const u_char * buf,
int len)
{
	int i;

	//carneol_port_input(TC58512_DATA);
	carneol_input_pg_8();

	for (i = 0; i < len; i++)
	{
		//carneol_pin_low(TC58512_CTRL, TC58512_RE);
		carneol_low_pg_17();
		//if ((u_char) buf[i] != (unsigned char) carneol_port_read(TC58512_DATA))
		if ((u_int8_t) buf[i] != (u_int8_t) carneol_read_pg1())
			return -EFAULT;
		//carneol_pin_high(TC58512_CTRL, TC58512_RE);
		carneol_high_pg_17();
	}
	return 0;
}


static int __init tc58512_init (void)
{
	struct nand_chip *this;

	printk("Carneol %s module %s, (C) 2005 - 2008 Simon Posnjak, Hinko
Kocevar\n", mod_name, mod_version);
	
	tc58512_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip),
			 GFP_KERNEL);
	if (!tc58512_mtd)
	{
		printk(KERN_ERR "%s: Unable to allocate carneol NAND MTD device
structure.\n", __func__);
		return -ENOMEM;
	}

	this = (struct nand_chip *) (&tc58512_mtd[1]);

	memset((char *) tc58512_mtd, 0, sizeof(struct mtd_info));
	memset((char *) this, 0, sizeof(struct nand_chip));

	tc58512_mtd->priv = this;
	tc58512_mtd->owner = THIS_MODULE;

	//carneol_port_output(TC58512_CTRL);
	carneol_output_pg_16();
	//carneol_port_input(TC58512_DATA);
	carneol_input_pg_8();
	//carneol_port_input(TC58512_STATUS);
	carneol_input_pg_24();

	//carneol_pin_low(TC58512_CTRL, TC58512_CLE);
	carneol_low_pg_19();
	//carneol_pin_low(TC58512_CTRL, TC58512_ALE);
	carneol_low_pg_20();
	//carneol_pin_high(TC58512_CTRL, TC58512_CE);
	carneol_high_pg_18();
	//carneol_pin_high(TC58512_CTRL, TC58512_RE);
	carneol_high_pg_17();
	//carneol_pin_high(TC58512_CTRL, TC58512_WE);
	carneol_high_pg_21();
	//carneol_pin_high(TC58512_CTRL, TC58512_WP);
	carneol_high_pg_22();

	this->read_byte = tc58512_read_byte;
	//this->write_byte = tc58512_write_byte;
	this->write_buf = tc58512_write_buf;
	this->read_buf = tc58512_read_buf;
	this->verify_buf = tc58512_verify_buf;
	this->dev_ready = tc58512_device_ready;
	
	/* Set address of hardware control function */
	this->cmd_ctrl = tc58512_cmd_ctrl;
	/* 3 us command delay time */
	this->chip_delay = 3;
	this->ecc.mode = NAND_ECC_SOFT;
	
	/* Scan to find existence of the device */
	if (nand_scan(tc58512_mtd, 1))
	{
		kfree(tc58512_mtd);
		return -ENXIO;
	}

#ifdef CONFIG_MTD_PARTITIONS
	/* Register the partitions */
	add_mtd_partitions(tc58512_mtd, partition_info, NUM_PARTITIONS);
#endif
	return 0;
}

static void __exit tc58512_cleanup (void)
{
#if 0
	/* Release MTD partitions */
	del_mtd_partitions(tc58512_mtd);
#endif
	
	/* Release resources, unregister device */
	nand_release(tc58512_mtd);

	/* Free the MTD device structure */
	kfree(tc58512_mtd);

	printk("Carneol %s module version %s removed\n", mod_name, mod_version);
}

module_init(tc58512_init);
module_exit(tc58512_cleanup);

MODULE_AUTHOR("Simon Posnjak <simon.posnjak@cetrtapot.si>, Hinko Kocevar
<hinko.kocevar@cetrtapot.si>");
MODULE_DESCRIPTION("CPOT Carneol NAND flash module for TC58512
compatible flash");
MODULE_LICENSE("GPL");

---

Best regards,
Hinko



-- 
ČETRTA POT, d.o.o., Kranj
Planina 3
4000 Kranj
Slovenia, Europe
Tel. +386 (0) 4 280 66 03
E-mail: hinko.kocevar@cetrtapot.si
Http: www.cetrtapot.si

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2008-04-09 13:54 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-03-09 16:46 Memory leak matsunaga
2003-03-09 17:37 ` Charles Manning
2003-03-09 19:10 ` Thomas Gleixner
2003-03-09 23:10   ` matsunaga
2003-03-10 14:53     ` Thomas Gleixner
2003-03-10 14:14       ` David Woodhouse
2003-03-10 15:48         ` matsunaga
2003-03-10 16:02           ` David Woodhouse
2003-03-10 16:26             ` matsunaga
2003-03-10 17:04               ` David Woodhouse
2003-03-11 15:52                 ` matsunaga
2003-03-11 18:39                   ` Thomas Gleixner
2003-03-10 15:36       ` matsunaga
2003-03-11 17:50 ` David Woodhouse
2003-03-12 15:47   ` dnode of meta data matsunaga
2003-03-13  7:14     ` David Woodhouse
  -- strict thread matches above, loose matches on Subject: below --
2008-04-09 13:54 Memory leak hinko.kocevar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox