msm: synx: async_wait timeout changes

Adding timeout parameter for async wait so the callback
will be invoked on timer expiry if not signalled.

Change-Id: Ia31f59021f00befed5317fdac262d823c659c6bf
Signed-off-by: Ram Nagesh <quic_ramnages@quicinc.com>
Signed-off-by: Urvesh Rathod <quic_urathod@quicinc.com>
This commit is contained in:
Urvesh Rathod
2023-04-18 14:51:32 +05:30
committed by Gerrit - the friendly Code Review server
parent 26a5a7df0d
commit d87e10c694
4 changed files with 82 additions and 4 deletions

View File

@@ -882,6 +882,52 @@ static int synx_match_payload(struct synx_kernel_payload *cb_payload,
return rc;
}
/* Timer Callback function. This will be called when timer expires */
void synx_timer_cb(struct timer_list *data)
{
struct synx_client *client;
struct synx_handle_coredata *synx_data;
struct synx_coredata *synx_obj;
struct synx_cb_data *synx_cb = container_of(data, struct synx_cb_data, synx_timer);
client = synx_get_client(synx_cb->session);
if (IS_ERR_OR_NULL(client)) {
dprintk(SYNX_ERR,
"invalid session data 0x%x in cb payload\n",
synx_cb->session);
return;
}
synx_data = synx_util_acquire_handle(client, synx_cb->h_synx);
synx_obj = synx_util_obtain_object(synx_data);
if (IS_ERR_OR_NULL(synx_obj)) {
dprintk(SYNX_ERR,
"[sess :0x%llx] invalid handle access 0x%x\n",
synx_cb->session, synx_cb->h_synx);
return;
}
dprintk(SYNX_VERB,
"Timer expired for synx_cb 0x%x timeout 0x%llx. Deleting the timer.\n",
synx_cb, synx_cb->timeout);
synx_cb->status = SYNX_STATE_TIMEOUT;
del_timer(&synx_cb->synx_timer);
list_del_init(&synx_cb->node);
queue_work(synx_dev->wq_cb, &synx_cb->cb_dispatch);
}
static int synx_start_timer(struct synx_cb_data *synx_cb)
{
int rc = 0;
timer_setup(&synx_cb->synx_timer, synx_timer_cb, 0);
rc = mod_timer(&synx_cb->synx_timer, jiffies + msecs_to_jiffies(synx_cb->timeout));
dprintk(SYNX_VERB,
"Timer started for synx_cb 0x%x timeout 0x%llx\n",
synx_cb, synx_cb->timeout);
return rc;
}
int synx_async_wait(struct synx_session *session,
struct synx_callback_params *params)
{
@@ -897,9 +943,6 @@ int synx_async_wait(struct synx_session *session,
if (IS_ERR_OR_NULL(session) || IS_ERR_OR_NULL(params))
return -SYNX_INVALID;
if (params->timeout_ms != SYNX_NO_TIMEOUT)
return -SYNX_NOSUPPORT;
client = synx_get_client(session);
if (IS_ERR_OR_NULL(client))
return -SYNX_INVALID;
@@ -952,6 +995,8 @@ int synx_async_wait(struct synx_session *session,
synx_cb->session = session;
synx_cb->idx = idx;
synx_cb->h_synx = params->h_synx;
INIT_WORK(&synx_cb->cb_dispatch, synx_util_cb_dispatch);
/* add callback if object still ACTIVE, dispatch if SIGNALED */
@@ -959,6 +1004,17 @@ int synx_async_wait(struct synx_session *session,
dprintk(SYNX_VERB,
"[sess :%llu] callback added for handle %u\n",
client->id, params->h_synx);
synx_cb->timeout = params->timeout_ms;
if (params->timeout_ms != SYNX_NO_TIMEOUT) {
rc = synx_start_timer(synx_cb);
if (rc != SYNX_SUCCESS) {
dprintk(SYNX_ERR,
"[sess :%llu] timer start failed - synx_cb: 0x%x, params->timeout_ms: 0x%llx, handle: 0x%x, ret : %d\n",
client->id, synx_cb, params->timeout_ms,
params->h_synx, rc);
goto release;
}
}
list_add(&synx_cb->node, &synx_obj->reg_cbs_list);
} else {
synx_cb->status = status;
@@ -1024,7 +1080,7 @@ int synx_cancel_async_wait(
status = synx_util_get_object_status(synx_obj);
if (status != SYNX_STATE_ACTIVE) {
dprintk(SYNX_ERR,
"handle %u already signaled cannot cancel\n",
"handle %u already signaled or timed out, cannot cancel\n",
params->h_synx);
rc = -SYNX_INVALID;
goto release;
@@ -1052,6 +1108,12 @@ int synx_cancel_async_wait(
cb_payload = &client->cb_table[synx_cb->idx];
ret = synx_match_payload(&cb_payload->kernel_cb, &payload);
if (synx_cb->timeout != SYNX_NO_TIMEOUT) {
dprintk(SYNX_VERB,
"Deleting timer synx_cb 0x%x, timeout 0x%llx\n",
synx_cb, synx_cb->timeout);
del_timer(&synx_cb->synx_timer);
}
switch (ret) {
case 1:
/* queue the cancel cb work */