[v3,03/11] core/flash: Only lock around flashes update in flash_register()

Message ID 20181009073237.16251-4-andrew@aj.id.au
State Accepted
Headers show
Series
  • Add and integrate an IPMI flash implementation
Related show

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied

Commit Message

Andrew Jeffery Oct. 9, 2018, 7:32 a.m.
Previously in flash_register() held flash_lock across ffs_init(), which
calls through the blocklevel layer to read the flash. This is unhelpful
with the IPMI HIOMAP protocol transport as LPC interrupts have not yet
been enabled and we are relying on polling to progress. The held lock
stalls the boot as we take the nopoll path in time_wait() while
completing ipmi_queue_msg_sync() in libflash/ipmi-flash.c

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 core/flash.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

Patch

diff --git a/core/flash.c b/core/flash.c
index 8e7b90e672c4..15eb7443faac 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -406,13 +406,9 @@  int flash_register(struct blocklevel_device *bl)
 	prlog(PR_INFO, "FLASH: registering flash device %s "
 			"(size 0x%llx, blocksize 0x%x)\n",
 			name ?: "(unnamed)", size, block_size);
-
-	lock(&flash_lock);
-
 	flash = malloc(sizeof(struct flash));
 	if (!flash) {
 		prlog(PR_ERR, "FLASH: Error allocating flash structure\n");
-		unlock(&flash_lock);
 		return OPAL_RESOURCE;
 	}
 
@@ -423,8 +419,6 @@  int flash_register(struct blocklevel_device *bl)
 	flash->block_size = block_size;
 	flash->id = num_flashes();
 
-	list_add(&flashes, &flash->list);
-
 	rc = ffs_init(0, flash->size, bl, &ffs, 1);
 	if (rc) {
 		/**
@@ -445,6 +439,8 @@  int flash_register(struct blocklevel_device *bl)
 	if (ffs)
 		ffs_close(ffs);
 
+	lock(&flash_lock);
+	list_add(&flashes, &flash->list);
 	unlock(&flash_lock);
 
 	return OPAL_SUCCESS;