[SLOF] [PATCH] rtas-nvram: optimize erase

Nikunj A Dadhania nikunj at linux.vnet.ibm.com
Thu May 5 16:13:39 AEST 2016


As this was done at byte granularity, erasing complete nvram(64K
default) took a lot of time. To reduce the number of rtas call per byte
write which is expensive, the erase is done in a block of 1024.

After this patch there is ~450msec improvement during boot. Default qemu
booting does not provide file backed nvram, so every boot there would be
full erase of 64K.

Before this patch:

real	0m2.214s
user	0m0.015s
sys	  0m0.006s

real	0m2.222s
user	0m0.014s
sys	  0m0.005s

real	0m2.201s
user	0m0.010s
sys	  0m0.005s

After this patch:

real	0m1.762s
user	0m0.014s
sys	  0m0.006s

real	0m1.773s
user	0m0.011s
sys   0m0.004s

real	0m1.754s
user	0m0.013s
sys	  0m0.005s

Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
---
 lib/libnvram/nvram.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/lib/libnvram/nvram.c b/lib/libnvram/nvram.c
index 473814e..5a895ee 100644
--- a/lib/libnvram/nvram.c
+++ b/lib/libnvram/nvram.c
@@ -80,6 +80,8 @@ static volatile uint8_t nvram[NVRAM_LENGTH]; /* FAKE */
 
 #elif defined(RTAS_NVRAM)
 
+#define RTAS_ERASE_BUF_SZ 1024
+unsigned char erase_buf[RTAS_ERASE_BUF_SZ] = {0};
 static inline void nvram_fetch(unsigned int offset, void *buf, unsigned int len)
 {
  	struct hv_rtas_call rtas = {
@@ -372,9 +374,18 @@ partition_t get_partition_fs(char *name, int namelen)
 void erase_nvram(int offset, int len)
 {
 	int i;
+#ifdef RTAS_NVRAM
+	int chunk;
 
+	memset(erase_buf, 0, RTAS_ERASE_BUF_SZ);
+	for (i = len; i > 0; i -= RTAS_ERASE_BUF_SZ, offset += RTAS_ERASE_BUF_SZ) {
+		chunk = (i > RTAS_ERASE_BUF_SZ)? RTAS_ERASE_BUF_SZ : i;
+		nvram_store(offset, erase_buf, chunk);
+	}
+#else
 	for (i=offset; i<offset+len; i++)
 		nvram_write_byte(i, 0);
+#endif
 }
 
 void wipe_nvram(void)
-- 
2.5.5



More information about the SLOF mailing list