[Skiboot] [RFC PATCH 6/6] libflash: add blocklevel_raw_prepare()

Stewart Smith stewart at linux.ibm.com
Fri Mar 1 11:36:13 AEDT 2019


Vasant Hegde <hegdevasant at linux.vnet.ibm.com> writes:

> On 02/28/2019 11:48 AM, Stewart Smith wrote:
>> The logic of a prepare call is to move the window (or at least start the
>> process of moving the window) so that when a read/write/erase call is
>> made, we don't have to wait for a IPMI round trip. >
>> For non-hiomap backends, one could use similar logic.
>> 
>> ---
>> Not Signed-off-by yet as I'm totally not convinced
>
> Even I'm not convinced about this approach. Its still error prone.
> May be best is to split read/write/erase call to two parts (one initiates 
> request to BMC
> and second one does post processing after getting data from BMC).
> That way we can remove synchronous message completely from these
> paths.

Yeah, that was my thought as well... It involves more surgery to
libflash though, which is annoying.

> Few comments based on current code.
>
>
>> ---
>>   core/flash.c           |  9 +++++++--
>>   libflash/blocklevel.c  | 22 +++++++++++++++++++++
>>   libflash/blocklevel.h  |  2 ++
>>   libflash/ipmi-hiomap.c | 44 ++++++++++++++++++++++++++++++++++++++++--
>>   4 files changed, 73 insertions(+), 4 deletions(-)
>> 
>> diff --git a/core/flash.c b/core/flash.c
>> index 04d99348515e..e267aaa0373d 100644
>> --- a/core/flash.c
>> +++ b/core/flash.c
>> @@ -1,4 +1,4 @@
>> -/* Copyright 2013-2018 IBM Corp.
>> +/* Copyright 2013-2019 IBM Corp.
>>    *
>>    * Licensed under the Apache License, Version 2.0 (the "License");
>>    * you may not use this file except in compliance with the License.
>> @@ -239,7 +239,7 @@ static void flash_poll(struct timer *t __unused, void *data, uint64_t now __unus
>>   {
>>   	struct flash *flash = data;
>>   	uint64_t offset, buf, len;
>> -	int rc;
>> +	int rc = 0;
>> 
>>   	offset = flash->async.pos;
>>   	buf = flash->async.buf;
>> @@ -254,6 +254,10 @@ static void flash_poll(struct timer *t __unused, void *data, uint64_t now __unus
>>   	len = MIN(flash->async.len, flash->block_size);
>>   	prlog(PR_TRACE, "Flash poll op %d len %llu\n", flash->async.op, len);
>> 
>> +	/* If we've done work to prepare, come back later */
>> +	if (blocklevel_raw_prepare(flash->bl, (flash->async.op!=FLASH_OP_READ), offset, len))
>> +		goto schedule;
>
> Need a way to differentiate errors vs waiting to get response from
> BMC.

yep.

>> +
>>   	switch (flash->async.op) {
>>   	case FLASH_OP_READ:
>>   		rc = blocklevel_raw_read(flash->bl, offset, (void *)buf, len);
>> @@ -274,6 +278,7 @@ static void flash_poll(struct timer *t __unused, void *data, uint64_t now __unus
>>   	flash->async.pos += len;
>>   	flash->async.buf += len;
>>   	flash->async.len -= len;
>> +schedule:
>>   	if (!rc && flash->async.len) {
>>   		/*
>>   		 * We want to get called pretty much straight away, just have
>> diff --git a/libflash/blocklevel.c b/libflash/blocklevel.c
>> index 5b57d3c6194f..9659c7fd68af 100644
>
> .../...
>
>
>> 
>> +static int ipmi_hiomap_prepare(struct blocklevel_device *bl, bool rw,
>> +			       uint64_t pos, uint64_t len)
>> +{
>> +	struct ipmi_hiomap *ctx;
>> +	enum lpc_window_state want_state;
>> +	uint64_t size;
>> +	uint8_t command = HIOMAP_C_CREATE_READ_WINDOW;
>> +	bool valid_state;
>> +	bool is_read;
>> +	int rc = 0;
>> +
>> +	/* LPC is only 32bit */
>> +	if (pos > UINT_MAX || len > UINT_MAX)
>> +		return FLASH_ERR_PARM_ERROR;
>> +
>> +	if (rw)
>> +		command = HIOMAP_C_CREATE_WRITE_WINDOW;
>> +
>> +	ctx = container_of(bl, struct ipmi_hiomap, bl);
>> +
>> +	is_read = (command == HIOMAP_C_CREATE_READ_WINDOW);
>> +	want_state = is_read ? read_window : write_window;
>> +
>> +	lock(&ctx->lock);
>> +	valid_state = want_state == ctx->window_state;
>> +	rc = hiomap_window_valid(ctx, pos, len);
>> +	if (valid_state && !rc) {
>> +		unlock(&ctx->lock);
>> +		return 0;
>> +	}
>> +	unlock(&ctx->lock);
>> +
>> +	rc = ipmi_hiomap_handle_events(ctx);
>> +	if (rc)
>> +		return rc;
>> +
>> +	rc = hiomap_window_move(ctx, command, pos, len, &size);
>
> This still uses synchronous path. So not going to help much.

Yeah, it doesn't make a huge impact, but amazingly enough, there is
*some* improvement (tens of ms)... but it needs work.


-- 
Stewart Smith
OPAL Architect, IBM.



More information about the Skiboot mailing list