Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c27f4ee authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: merge two uchar variable in struct node_info to reduce memory cost



This patch moves one member of struct nat_entry: _flag_ to struct node_info,
so _version_ in struct node_info and _flag_ which are unsigned char type will
merge to one 32-bit space in register/memory. So the size of nat_entry will be
reduced from 28 bytes to 24 bytes (for 64-bit machine, reduce its size from 40
bytes to 32 bytes) and then slab memory using by f2fs will be reduced.

changes from v2:
 o update description of memory usage gain for 64-bit machine suggested by
   Changman Lee.
changes from v1:
 o introduce inline copy_node_info() to copy valid data from node info suggested
   by Jaegeuk Kim, it can avoid bug.

Reviewed-by: default avatarChangman Lee <cm224.lee@samsung.com>
Signed-off-by: default avatarChao Yu <chao2.yu@samsung.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 3fa06d7b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -269,7 +269,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
	e = __lookup_nat_cache(nm_i, ni->nid);
	if (!e) {
		e = grab_nat_entry(nm_i, ni->nid);
		e->ni = *ni;
		copy_node_info(&e->ni, ni);
		f2fs_bug_on(sbi, ni->blk_addr == NEW_ADDR);
	} else if (new_blkaddr == NEW_ADDR) {
		/*
@@ -277,7 +277,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
		 * previous nat entry can be remained in nat cache.
		 * So, reinitialize it with new information.
		 */
		e->ni = *ni;
		copy_node_info(&e->ni, ni);
		f2fs_bug_on(sbi, ni->blk_addr != NULL_ADDR);
	}

+22 −11
Original line number Diff line number Diff line
@@ -29,6 +29,14 @@
/* return value for read_node_page */
#define LOCKED_PAGE	1

/* For flag in struct node_info */
enum {
	IS_CHECKPOINTED,	/* is it checkpointed before? */
	HAS_FSYNCED_INODE,	/* is the inode fsynced before? */
	HAS_LAST_FSYNC,		/* has the latest node fsync mark? */
	IS_DIRTY,		/* this nat entry is dirty? */
};

/*
 * For node information
 */
@@ -37,18 +45,11 @@ struct node_info {
	nid_t ino;		/* inode number of the node's owner */
	block_t	blk_addr;	/* block address of the node */
	unsigned char version;	/* version of the node */
};

enum {
	IS_CHECKPOINTED,	/* is it checkpointed before? */
	HAS_FSYNCED_INODE,	/* is the inode fsynced before? */
	HAS_LAST_FSYNC,		/* has the latest node fsync mark? */
	IS_DIRTY,		/* this nat entry is dirty? */
	unsigned char flag;	/* for node information bits */
};

struct nat_entry {
	struct list_head list;	/* for clean or dirty nat list */
	unsigned char flag;	/* for node information bits */
	struct node_info ni;	/* in-memory node information */
};

@@ -63,20 +64,30 @@ struct nat_entry {

#define inc_node_version(version)	(++version)

static inline void copy_node_info(struct node_info *dst,
						struct node_info *src)
{
	dst->nid = src->nid;
	dst->ino = src->ino;
	dst->blk_addr = src->blk_addr;
	dst->version = src->version;
	/* should not copy flag here */
}

static inline void set_nat_flag(struct nat_entry *ne,
				unsigned int type, bool set)
{
	unsigned char mask = 0x01 << type;
	if (set)
		ne->flag |= mask;
		ne->ni.flag |= mask;
	else
		ne->flag &= ~mask;
		ne->ni.flag &= ~mask;
}

static inline bool get_nat_flag(struct nat_entry *ne, unsigned int type)
{
	unsigned char mask = 0x01 << type;
	return ne->flag & mask;
	return ne->ni.flag & mask;
}

static inline void nat_reset_flag(struct nat_entry *ne)