Merge "smcinvoke: implement retry and timeout for CB processing"

This commit is contained in:
qctecmdr 2020-12-18 18:04:11 -08:00 • committed by Gerrit - the friendly Code Review server
commit 8168d364e5

View file

@ -61,6 +61,7 @@
*/
#define SMCINVOKE_SERVER_STATE_DEFUNCT 1
#define CBOBJ_MAX_RETRIES 5
#define FOR_ARGS(ndxvar, counts, section) \
for (ndxvar = OBJECT_COUNTS_INDEX_##section(counts); \
ndxvar < (OBJECT_COUNTS_INDEX_##section(counts) \
@ -1002,6 +1003,8 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp)
{
/* ret is going to TZ. Provide values from OBJECT_ERROR_<> */
int ret = OBJECT_ERROR_DEFUNCT;
int cbobj_retries = 0;
long timeout_jiff;
struct smcinvoke_cb_txn *cb_txn = NULL;
struct smcinvoke_tzcb_req *cb_req = NULL, *tmp_cb_req = NULL;
struct smcinvoke_server_info *srvr_info = NULL;
@ -1079,9 +1082,26 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp)
* as this CBObj is served by this server, srvr_info will be valid.
*/
wake_up_interruptible_all(&srvr_info->req_wait_q);
ret = wait_event_interruptible(srvr_info->rsp_wait_q,
(cb_txn->state == SMCINVOKE_REQ_PROCESSED) ||
(srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT));
/* timeout before 1s otherwise tzbusy would come */
timeout_jiff = msecs_to_jiffies(1000);
while (cbobj_retries < CBOBJ_MAX_RETRIES) {
ret = wait_event_interruptible_timeout(srvr_info->rsp_wait_q,
(cb_txn->state == SMCINVOKE_REQ_PROCESSED) ||
(srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT),
timeout_jiff);
if (ret == 0) {
pr_err("CBobj timed out cb-tzhandle:%d, retry:%d, op:%d counts :%d\n",
cb_req->hdr.tzhandle, cbobj_retries, cb_req->hdr.op, cb_req->hdr.counts);
pr_err("CBobj %d timedout pid %x,tid %x, srvr state=%d, srvr id:%u\n",
cb_req->hdr.tzhandle, current->pid, current->tgid, srvr_info->state,
srvr_info->server_id);
} else {
break;
}
cbobj_retries++;
}
out:
/*
@ -1091,18 +1111,26 @@ out:
*/
mutex_lock(&g_smcinvoke_lock);
hash_del(&cb_txn->hash);
if (cb_txn->state == SMCINVOKE_REQ_PROCESSED) {
/*
* it is possible that server was killed immediately
* after CB Req was processed but who cares now!
*/
} else if (!srvr_info ||
srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) {
cb_req->result = OBJECT_ERROR_DEFUNCT;
pr_err("server invalid, res: %d\n", cb_req->result);
} else {
pr_debug("%s wait_event interrupted ret = %d\n", __func__, ret);
if (ret == 0) {
pr_err("CBObj timed out! No more retries\n");
cb_req->result = OBJECT_ERROR_ABORT;
} else if (ret < 0) {
pr_err("wait event interruped, ret: %d\n", ret);
cb_req->result = OBJECT_ERROR_ABORT;
} else {
if (cb_txn->state == SMCINVOKE_REQ_PROCESSED) {
/*
* it is possible that server was killed immediately
* after CB Req was processed but who cares now!
*/
} else if (!srvr_info ||
srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) {
cb_req->result = OBJECT_ERROR_DEFUNCT;
pr_err("server invalid, res: %d\n", cb_req->result);
} else {
pr_err("%s: unexpected event happened\n", __func__);
cb_req->result = OBJECT_ERROR_ABORT;
}
}
--cb_reqs_inflight;
memcpy(buf, cb_req, buf_len);