diff mbox

FSP/RTC: Fix possible FSP R/R issue in rtc write path

Message ID 20170613102234.5050-1-hegdevasant@linux.vnet.ibm.com
State Accepted
Headers show

Commit Message

Vasant Hegde June 13, 2017, 10:22 a.m. UTC
fsp_opal_rtc_write() checks FSP status before queueing message to FSP. But if
FSP R/R starts before getting response to queued message then we will continue
to return OPAL_BUSY_EVENT to host. In some extreme condition host may
experience hang. Once FSP is back we will repost message, get response from FSP
and return OPAL_SUCCES to host.

This patch caches new values and returns OPAL_SUCCESS if FSP R/R is happening.
And once FSP is back we will send cached value to FSP.

Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 hw/fsp/fsp-rtc.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

Comments

Vasant Hegde June 13, 2017, 1:11 p.m. UTC | #1
On 06/13/2017 03:52 PM, Vasant Hegde wrote:
> fsp_opal_rtc_write() checks FSP status before queueing message to FSP. But if
> FSP R/R starts before getting response to queued message then we will continue
> to return OPAL_BUSY_EVENT to host. In some extreme condition host may
> experience hang. Once FSP is back we will repost message, get response from FSP
> and return OPAL_SUCCES to host.
>
> This patch caches new values and returns OPAL_SUCCESS if FSP R/R is happening.
> And once FSP is back we will send cached value to FSP.

Stewart,

I missed to add "v2" to subject line. Please consider this patch. Not v1 patch.

With this changes, OPAL will record new request from kernel  while FSP is in reboot.
Once FSP is back OPAL will call rtc_flush_cached_tod() to flush the data.

-Vasant
Stewart Smith June 14, 2017, 6:56 a.m. UTC | #2
Vasant Hegde <hegdevasant@linux.vnet.ibm.com> writes:
> On 06/13/2017 03:52 PM, Vasant Hegde wrote:
>> fsp_opal_rtc_write() checks FSP status before queueing message to FSP. But if
>> FSP R/R starts before getting response to queued message then we will continue
>> to return OPAL_BUSY_EVENT to host. In some extreme condition host may
>> experience hang. Once FSP is back we will repost message, get response from FSP
>> and return OPAL_SUCCES to host.
>>
>> This patch caches new values and returns OPAL_SUCCESS if FSP R/R is happening.
>> And once FSP is back we will send cached value to FSP.
>
> Stewart,
>
> I missed to add "v2" to subject line. Please consider this patch. Not v1 patch.
>
> With this changes, OPAL will record new request from kernel  while FSP is in reboot.
> Once FSP is back OPAL will call rtc_flush_cached_tod() to flush the
> data.

Okay, I think this is an okay thing to do in this scenario.

Merged to master as of f4757fbfcf616365c74b1aa6508b2ab27480cdd0

and to 5.4.x as of 79a78d3d8ba61033e6f9084c4519ada1588ebbe1
diff mbox

Patch

diff --git a/hw/fsp/fsp-rtc.c b/hw/fsp/fsp-rtc.c
index b41e295..8ee0f5a 100644
--- a/hw/fsp/fsp-rtc.c
+++ b/hw/fsp/fsp-rtc.c
@@ -342,7 +342,6 @@  static int64_t fsp_rtc_send_write_request(uint32_t year_month_day,
 {
 	struct fsp_msg *msg;
 	uint32_t w0, w1, w2;
-	struct tm tm;
 
 	assert(lock_held_by_me(&rtc_lock));
 	assert(rtc_write_request_state == RTC_WRITE_NO_REQUEST);
@@ -362,14 +361,7 @@  static int64_t fsp_rtc_send_write_request(uint32_t year_month_day,
 	}
 	prlog(PR_TRACE, " -> req at %p\n", msg);
 
-	if (fsp_in_rr()) {
-		datetime_to_tm(msg->data.words[0],
-			       (u64) msg->data.words[1] << 32,  &tm);
-		rtc_cache_update(&tm);
-		rtc_tod_cache_dirty = true;
-		fsp_freemsg(msg);
-		return OPAL_SUCCESS;
-	} else if (fsp_queue_msg(msg, fsp_rtc_req_complete)) {
+	if (fsp_queue_msg(msg, fsp_rtc_req_complete)) {
 		prlog(PR_TRACE, " -> queueing failed !\n");
 		fsp_freemsg(msg);
 		return OPAL_INTERNAL_ERROR;
@@ -384,6 +376,7 @@  static int64_t fsp_opal_rtc_write(uint32_t year_month_day,
 				  uint64_t hour_minute_second_millisecond)
 {
 	int rc;
+	struct tm tm;
 
 	lock(&rtc_lock);
 	if (rtc_tod_state == RTC_TOD_PERMANENT_ERROR) {
@@ -391,6 +384,15 @@  static int64_t fsp_opal_rtc_write(uint32_t year_month_day,
 		goto out;
 	}
 
+	if (fsp_in_rr()) {
+		datetime_to_tm(year_month_day,
+			       hour_minute_second_millisecond, &tm);
+		rtc_cache_update(&tm);
+		rtc_tod_cache_dirty = true;
+		rc = OPAL_SUCCESS;
+		goto out;
+	}
+
 	if (rtc_write_request_state == RTC_WRITE_NO_REQUEST) {
 		prlog(PR_TRACE, "Sending new RTC write request\n");
 		rc = fsp_rtc_send_write_request(year_month_day,