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:

committed by
Gerrit - the friendly Code Review server

parent
26a5a7df0d
commit
d87e10c694
@@ -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 */
|
||||
|
@@ -53,6 +53,7 @@ enum synx_core_id {
|
||||
#define SYNX_STATE_SIGNALED_ERROR 3
|
||||
#define SYNX_STATE_SIGNALED_EXTERNAL 5
|
||||
#define SYNX_STATE_SIGNALED_SSR 6
|
||||
#define SYNX_STATE_TIMEOUT 7
|
||||
|
||||
/* dma fence states */
|
||||
#define SYNX_DMA_FENCE_STATE_MAX 4096
|
||||
|
@@ -101,7 +101,10 @@ struct synx_kernel_payload {
|
||||
struct synx_cb_data {
|
||||
struct synx_session *session;
|
||||
u32 idx;
|
||||
u32 h_synx;
|
||||
u32 status;
|
||||
struct timer_list synx_timer;
|
||||
u64 timeout;
|
||||
struct work_struct cb_dispatch;
|
||||
struct list_head node;
|
||||
};
|
||||
|
@@ -301,6 +301,12 @@ void synx_util_object_destroy(struct synx_coredata *synx_obj)
|
||||
"dipatching un-released callbacks of session %pK\n",
|
||||
synx_cb->session);
|
||||
synx_cb->status = SYNX_STATE_SIGNALED_CANCEL;
|
||||
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);
|
||||
}
|
||||
list_del_init(&synx_cb->node);
|
||||
queue_work(synx_dev->wq_cb,
|
||||
&synx_cb->cb_dispatch);
|
||||
@@ -1175,6 +1181,12 @@ void synx_util_callback_dispatch(struct synx_coredata *synx_obj, u32 status)
|
||||
list_for_each_entry_safe(synx_cb,
|
||||
synx_cb_temp, &synx_obj->reg_cbs_list, node) {
|
||||
synx_cb->status = status;
|
||||
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);
|
||||
}
|
||||
list_del_init(&synx_cb->node);
|
||||
queue_work(synx_dev->wq_cb,
|
||||
&synx_cb->cb_dispatch);
|
||||
|
Reference in New Issue
Block a user