From 33b53716bc4b3ff3da2bc41581226424443f9d5a Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Fri, 8 Apr 2011 08:51:32 -0700 Subject: mtd: create function to perform large allocations Introduce a common function to handle large, contiguous kmalloc buffer allocations by exponentially backing off on the size of the requested kernel transfer buffer until it succeeds or until the requested transfer buffer size falls below the page size. This helps ensure the operation can succeed under low-memory, highly- fragmented situations albeit somewhat more slowly. Artem: so this patch solves the problem that the kernel tries to kmalloc too large buffers, which (a) may fail and does fail - people complain about this, and (b) slows down the system in case of high memory fragmentation, because the kernel starts dropping caches, writing back, swapping, etc. But we do not really have to allocate a lot of memory to do the I/O, we may do this even with as little as one min. I/O unit (NAND page) of RAM. So the idea of this patch is that if the user asks to read or write a lot, we try to kmalloc a lot, with GFP flags which make the kernel _not_ drop caches, etc. If we can allocate it - good, if not - we try to allocate twice as less, and so on, until we reach the min. I/O unit size, which is our last resort allocation and use the normal GFP_KERNEL flag. Artem: re-write the allocation function so that it makes sure the allocated buffer is aligned to the min. I/O size of the flash. Signed-off-by: Grant Erickson Tested-by: Ben Gardiner Tested-by: Stefano Babic Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/mtd.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/mtd/mtd.h') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 9d5306bad117..06b489a7605b 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -348,6 +348,8 @@ int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); +void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); + #ifdef CONFIG_MTD_PARTITIONS void mtd_erase_callback(struct erase_info *instr); #else -- cgit v1.2.1 From f5671ab3f67a10f7234de21464391c20c1ef8ebb Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 17:15:46 +0100 Subject: mtd: introduce mtd_device_(un)register() To prepare for the removal of add_mtd_device and add_mtd_partitions(), introduce mtd_device_register(). This will create partitions if they are supplied or register the whole device if there are no partitions. Once all drivers are converted to use mtd_device_register(), add_mtd_device() and add_mtd_partitions() will be made internal only. v2: move kerneldoc to implementation file and fixup some kerneldoc warnings. Artem: tweak comments: remove junk tabs, use dots consistently. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/mtd.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux/mtd/mtd.h') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 06b489a7605b..f4b0b27a7bbe 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -325,6 +325,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) extern int add_mtd_device(struct mtd_info *mtd); extern int del_mtd_device (struct mtd_info *mtd); +struct mtd_partition; + +extern int mtd_device_register(struct mtd_info *master, + const struct mtd_partition *parts, + int nr_parts); +extern int mtd_device_unregister(struct mtd_info *master); extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); extern int __get_mtd_device(struct mtd_info *mtd); extern void __put_mtd_device(struct mtd_info *mtd); -- cgit v1.2.1 From eea72d5fdf59879edb2c6639b0b7cc385e0df646 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 10:23:42 +0100 Subject: mtd: remove add_mtd_partitions, add_mtd_device and friends These symbols are replaced with mtd_device_register() (and removal with mtd_device_unregister()) for public registration. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/mtd.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux/mtd/mtd.h') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f4b0b27a7bbe..1e3887bc105c 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -322,9 +322,6 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) /* Kernel-side ioctl definitions */ -extern int add_mtd_device(struct mtd_info *mtd); -extern int del_mtd_device (struct mtd_info *mtd); - struct mtd_partition; extern int mtd_device_register(struct mtd_info *master, -- cgit v1.2.1 From 6a8a98b22b10f1560d5f90aded4a54234b9b2724 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 23 May 2011 10:23:43 +0100 Subject: mtd: kill CONFIG_MTD_PARTITIONS Now that none of the drivers use CONFIG_MTD_PARTITIONS we can remove it from Kconfig and the last remaining uses. Signed-off-by: Jamie Iles Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/mtd.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux/mtd/mtd.h') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 1e3887bc105c..2541fb848daa 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -353,15 +353,7 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); -#ifdef CONFIG_MTD_PARTITIONS void mtd_erase_callback(struct erase_info *instr); -#else -static inline void mtd_erase_callback(struct erase_info *instr) -{ - if (instr->callback) - instr->callback(instr); -} -#endif /* * Debugging macro and defines -- cgit v1.2.1