Skip to content

Commit d22d5f4

Browse files
arndbmiquelraynal
authored andcommitted
mtd: nftl: reduce stack usage in NFTL_movebuf()
The code in the ntfl write function is rather complex, and it contains a 512 byte on-stack buffer. The combination of these two leads to using more than the per-function stack warning limit in some configurations, especially with KASAN enabled: drivers/mtd/nftlcore.c:673:12: error: stack frame size (1328) exceeds limit (1280) in 'nftl_writeblock' [-Werror,-Wframe-larger-than] Avoid this warning by moving the on-stack buffer into a separate function that only copies one part of the device to another. This does not really help with the total maximum stack usage in the (non-KASAN) normal case, but it does two things: - no single function has more than the warning limit - the complexity goes down, so the parent function ends up spilling few local variables, and the total actually goes down slightly. Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Miquel Raynal <[email protected]>
1 parent 27b045e commit d22d5f4

File tree

1 file changed

+21
-22
lines changed

1 file changed

+21
-22
lines changed

drivers/mtd/nftlcore.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,25 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
228228
return BLOCK_NIL;
229229
}
230230

231+
static noinline_for_stack void NFTL_move_block(struct mtd_info *mtd, loff_t src, loff_t dst)
232+
{
233+
unsigned char movebuf[512];
234+
struct nftl_oob oob;
235+
size_t retlen;
236+
int ret;
237+
238+
ret = mtd_read(mtd, src, 512, &retlen, movebuf);
239+
if (ret < 0 && !mtd_is_bitflip(ret)) {
240+
ret = mtd_read(mtd, src, 512, &retlen, movebuf);
241+
if (ret != -EIO)
242+
printk("Error went away on retry.\n");
243+
}
244+
memset(&oob, 0xff, sizeof(struct nftl_oob));
245+
oob.b.Status = oob.b.Status1 = SECTOR_USED;
246+
247+
nftl_write(mtd, dst, 512, &retlen, movebuf, (char *)&oob);
248+
}
249+
231250
static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock )
232251
{
233252
struct mtd_info *mtd = nftl->mbd.mtd;
@@ -389,9 +408,6 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
389408
*/
390409
pr_debug("Folding chain %d into unit %d\n", thisVUC, targetEUN);
391410
for (block = 0; block < nftl->EraseSize / 512 ; block++) {
392-
unsigned char movebuf[512];
393-
int ret;
394-
395411
/* If it's in the target EUN already, or if it's pending write, do nothing */
396412
if (BlockMap[block] == targetEUN ||
397413
(pendingblock == (thisVUC * (nftl->EraseSize / 512) + block))) {
@@ -403,25 +419,8 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
403419
if (BlockMap[block] == BLOCK_NIL)
404420
continue;
405421

406-
ret = mtd_read(mtd,
407-
(nftl->EraseSize * BlockMap[block]) + (block * 512),
408-
512,
409-
&retlen,
410-
movebuf);
411-
if (ret < 0 && !mtd_is_bitflip(ret)) {
412-
ret = mtd_read(mtd,
413-
(nftl->EraseSize * BlockMap[block]) + (block * 512),
414-
512,
415-
&retlen,
416-
movebuf);
417-
if (ret != -EIO)
418-
printk("Error went away on retry.\n");
419-
}
420-
memset(&oob, 0xff, sizeof(struct nftl_oob));
421-
oob.b.Status = oob.b.Status1 = SECTOR_USED;
422-
423-
nftl_write(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) +
424-
(block * 512), 512, &retlen, movebuf, (char *)&oob);
422+
NFTL_move_block(mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
423+
(nftl->EraseSize * targetEUN) + (block * 512));
425424
}
426425

427426
/* add the header so that it is now a valid chain */

0 commit comments

Comments
 (0)