diff options
Diffstat (limited to 'drivers/mtd/mtdoops.c')
| -rw-r--r-- | drivers/mtd/mtdoops.c | 17 | 
1 files changed, 15 insertions, 2 deletions
| diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 774970bfcf85..862c4a889234 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -52,6 +52,7 @@ static struct mtdoops_context {  	int nextcount;  	unsigned long *oops_page_used; +	unsigned long oops_buf_busy;  	void *oops_buf;  } oops_cxt; @@ -180,6 +181,9 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)  	u32 *hdr;  	int ret; +	if (test_and_set_bit(0, &cxt->oops_buf_busy)) +		return; +  	/* Add mtdoops header to the buffer */  	hdr = cxt->oops_buf;  	hdr[0] = cxt->nextcount; @@ -190,7 +194,7 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)  				      record_size, &retlen, cxt->oops_buf);  		if (ret == -EOPNOTSUPP) {  			printk(KERN_ERR "mtdoops: Cannot write from panic without panic_write\n"); -			return; +			goto out;  		}  	} else  		ret = mtd_write(mtd, cxt->nextpage * record_size, @@ -203,6 +207,8 @@ static void mtdoops_write(struct mtdoops_context *cxt, int panic)  	memset(cxt->oops_buf, 0xff, record_size);  	mtdoops_inc_counter(cxt); +out: +	clear_bit(0, &cxt->oops_buf_busy);  }  static void mtdoops_workfunc_write(struct work_struct *work) @@ -271,13 +277,19 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper,  {  	struct mtdoops_context *cxt = container_of(dumper,  			struct mtdoops_context, dump); +	struct kmsg_dump_iter iter;  	/* Only dump oopses if dump_oops is set */  	if (reason == KMSG_DUMP_OOPS && !dump_oops)  		return; -	kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, +	kmsg_dump_rewind(&iter); + +	if (test_and_set_bit(0, &cxt->oops_buf_busy)) +		return; +	kmsg_dump_get_buffer(&iter, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE,  			     record_size - MTDOOPS_HEADER_SIZE, NULL); +	clear_bit(0, &cxt->oops_buf_busy);  	if (reason != KMSG_DUMP_OOPS) {  		/* Panics must be written immediately */ @@ -394,6 +406,7 @@ static int __init mtdoops_init(void)  		return -ENOMEM;  	}  	memset(cxt->oops_buf, 0xff, record_size); +	cxt->oops_buf_busy = 0;  	INIT_WORK(&cxt->work_erase, mtdoops_workfunc_erase);  	INIT_WORK(&cxt->work_write, mtdoops_workfunc_write); | 
