UBI memory usage on large page nand

Nicholas ciliwung36 at gmail.com
Wed Aug 17 02:35:49 EDT 2011


Dear Artem,

1. drivers/mtd/ubi/build.c

attach_by_scanning(struct ubi_device *ubi)

        ubi->min_io_size = ubi->mtd->writesize;
        ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;
+       ubi->max_write_size = ubi->mtd->writesize;

-      ubi->peb_buf1 = vmalloc(ubi->peb_size);
+      ubi->peb_buf1 = vmalloc(ubi->max_write_size);
        if (!ubi->peb_buf1)
                goto out_free;

-       ubi->peb_buf2 = vmalloc(ubi->peb_size);
+      ubi->peb_buf2 = vmalloc(ubi->max_write_size);
        if (!ubi->peb_buf2)
                goto out_free;

2. drivers/mtd/ubi/kapi.c

ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di)

        di->min_io_size = ubi->min_io_size;
+      di->max_write_size = ubi->max_write_size;
        di->ro_mode = ubi->ro_mode;

3. drivers/mtd/ubi/ubi.h

    * @dbg_buf_mutex: protects @dbg_peb_buf
+  * @max_write_size : maximum write buffer size

struct ubi_device {

        unsigned int bad_allowed:1;
        unsigned int nor_flash:1;
+      int max_write_size;

4. fs/ubifs/ubifs.h
     * @min_io_shift: number of bits in @min_io_size minus one
+   * @max_write_size: maximum amount of bytes the underlying flash
can write at a
+   *                  time (MTD write buffer size)

        int min_io_shift;
+     int max_write_size;

5. fs/ubifs/super.c

int init_constants_early(struct ubifs_info *c)

        c->min_io_shift = fls(c->min_io_size) - 1;
+      c->max_write_size = c->di.max_write_size;

int mount_ubifs(struct ubifs_info *c)

	dbg_msg("min. I/O unit size:  %d bytes", c->min_io_size);
+	dbg_msg("max. write size:     %d bytes", c->max_write_size);

-        if (!mounted_read_only) {
-                c->ileb_buf = vmalloc(c->leb_size);
-                //c->ileb_buf = vmalloc(c->max_write_size);
-                if (!c->ileb_buf)
-                        goto out_free;
-        }

    out_free:
	kfree(c->bu.buf);
-	vfree(c->ileb_buf);
	vfree(c->sbuf);

ubifs_umount(struct ubifs_info *c)

	kfree(c->bu.buf);
-	vfree(c->ileb_buf);
	vfree(c->sbuf);

6. fs/ubifs/tnc_commit.c

fill_gap(struct ubifs_info *c, int lnum, int gap_start, int gap_end, int *dirt)

			ubifs_assert(alen <= gap_remains);
-			err = make_idx_node(c, c->ileb_buf + gap_pos, znode,
-					    lnum, gap_pos, len);
+			err = make_idx_node(c, c->sbuf + gap_pos, znode,
+					    lnum, gap_pos, len);

-  ubifs_pad(c, c->ileb_buf + gap_pos, pad_len);
+ ubifs_pad(c, c->sbuf + gap_pos, pad_len);

layout_leb_in_gaps(struct ubifs_info *c, int *p)

/*
	 * Scan the index LEB.  We use the generic scan for this even though
	 * it is more comprehensive and less efficient than is needed for this
	 * purpose.
	 */
-	sleb = ubifs_scan(c, lnum, 0, c->ileb_buf, 0);
+	sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0);

        if (err)
		return err;
-	err = ubifs_leb_change(c, lnum, c->ileb_buf, c->ileb_len,
-			       UBI_SHORTTERM);
+	err = ubifs_leb_change(c, lnum, c->sbuf, c->ileb_len,
+			       UBI_SHORTTERM);

7. fs/ubifs/orphan.c

ubifs_mount_orphans(struct ubifs_inf *c, int unclean, int read_only)

        if (!read_only) {
-               c->orph_buf = vmalloc(c->leb_size);
+              c->orph_buf = vmalloc(c->max_write_size);
                if (!c->orph_buf)
                        return -ENOMEM;
        }

8. fs/ubifs/lpt.c

lpt_init_wr(struct ubifs_info *c)

-	c->lpt_buf = vmalloc(c->leb_size);
-	if (!c->lpt_buf)
-		return -ENOMEM;

9. fs/ubifs/lpt_commit.c

int write_cnodes(struct ubifs_info *c)

	struct ubifs_cnode *cnode;
-	void *buf = c->lpt_buf;
+	void *buf = c->sbuf;

int lpt_gc_lnum(struct ubifs_info *c, int lnum)

	int err, len = c->leb_size, node_type, node_num, node_len, offs;
-	void *buf = c->lpt_buf;
+	void *buf = c->sbuf;

ubifs_lpt_free(struct ubifs_info *c, int wr_only)

-	vfree(c->lpt_buf);
-	c->lpt_buf = NULL;
+	vfree(c->sbuf);
+	c->sbuf = NULL;

Since lpt & orphan's buffer is only used while doing commit, i think
there's a chance to use sbuf for commit activity.
Is there any chance to shrink the "c->sbuf" from fs/ubifs/super.c ?


More information about the linux-mtd mailing list