diff options
author | Hari Kanigeri <h-kanigeri2@ti.com> | 2009-12-15 20:29:22 -0600 |
---|---|---|
committer | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2010-01-05 06:26:15 +0530 |
commit | 59c9880a675b42d828a8a238012c4ab440e3090f (patch) | |
tree | 0686b029d8d5122e51ec64bd80e8c3b1e2588871 | |
parent | bb33d83194c286bb8dc6cdcad3d5261042dc6897 (diff) |
SYSLINK: Stabilize IPC for multithreaded applicationsti-2.6.31-omap4-L24.3-for-testing
This includes the changes to apply memory barriers in key
areas and extend the check in the notify module to wait
till the other core processed the event that was sent
before returning.
Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com>
-rwxr-xr-x | drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c | 25 | ||||
-rw-r--r-- | drivers/dsp/syslink/multicore_ipc/platform.c | 2 | ||||
-rw-r--r-- | drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c | 29 |
3 files changed, 42 insertions, 14 deletions
diff --git a/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c index 1530a89717a5..5904c6d18000 100755 --- a/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c +++ b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c @@ -809,7 +809,7 @@ bool listmp_sharedmemory_empty(listmp_sharedmemory_handle listmp_handle) /*! @retval true if list is empty */ sharedHead = (struct listmp_elem *)(sharedregion_get_srptr( (void *)obj->listmp_elem, obj->index)); - + dsb(); if (obj->listmp_elem->next == sharedHead) is_empty = true; @@ -856,6 +856,7 @@ void *listmp_sharedmemory_get_head(listmp_sharedmemory_handle listmp_handle) } localHeadNext = sharedregion_get_ptr((u32 *)obj->listmp_elem->next); + dsb(); /* See if the listmp_sharedmemory_object was empty */ if (localHeadNext == (struct listmp_elem *)obj->listmp_elem) { /*! @retval NULL if list is empty */ @@ -863,14 +864,14 @@ void *listmp_sharedmemory_get_head(listmp_sharedmemory_handle listmp_handle) } else { /* Elem to return */ elem = localHeadNext; - + dsb(); localNext = sharedregion_get_ptr((u32 *)elem->next); sharedHead = (struct listmp_elem *) sharedregion_get_srptr( (void *)obj->listmp_elem, obj->index); /* Fix the head of the list next pointer */ obj->listmp_elem->next = elem->next; - + dsb(); /* Fix the prev pointer of the new first elem on the list */ localNext->prev = sharedHead; @@ -979,12 +980,12 @@ int listmp_sharedmemory_put_head(listmp_sharedmemory_handle listmp_handle, handle = (listmp_sharedmemory_object *)listmp_handle; obj = (struct listmp_sharedmemory_obj *) handle->obj; - + dsb(); index = sharedregion_get_index(elem); sharedElem = (struct listmp_elem *) sharedregion_get_srptr(elem, index); sharedHead = (struct listmp_elem *)sharedregion_get_srptr( (void *)obj->listmp_elem, obj->index); - + dsb(); if (obj->params.gate != NULL) { retval = gatepeterson_enter(obj->params.gate); if (retval < 0) { @@ -992,10 +993,10 @@ int listmp_sharedmemory_put_head(listmp_sharedmemory_handle listmp_handle, goto exit; } } - /* Add the new elem into the list */ elem->next = obj->listmp_elem->next; elem->prev = sharedHead; + dsb(); localNextElem = sharedregion_get_ptr((u32 *)elem->next); localNextElem->prev = sharedElem; obj->listmp_elem->next = sharedElem; @@ -1042,7 +1043,7 @@ int listmp_sharedmemory_put_tail(listmp_sharedmemory_handle listmp_handle, handle = (listmp_sharedmemory_object *)listmp_handle; obj = (struct listmp_sharedmemory_obj *) handle->obj; - + dsb(); /* Safe to do outside the gate */ index = sharedregion_get_index(elem); sharedElem = (struct listmp_elem *) @@ -1058,11 +1059,12 @@ int listmp_sharedmemory_put_tail(listmp_sharedmemory_handle listmp_handle, goto exit; } } - /* Add the new elem into the list */ elem->next = sharedHead; elem->prev = obj->listmp_elem->prev; + dsb(); localPrevElem = sharedregion_get_ptr((u32 *)elem->prev); + dsb(); localPrevElem->next = sharedElem; obj->listmp_elem->prev = sharedElem; @@ -1126,7 +1128,7 @@ int listmp_sharedmemory_insert(listmp_sharedmemory_handle listmp_handle, index = sharedregion_get_index(new_elem); sharedNewElem = (struct listmp_elem *) sharedregion_get_srptr(new_elem, index); - + dsb(); /* Get SRPtr for cur_elem */ index = sharedregion_get_index(cur_elem); sharedCurElem = (struct listmp_elem *) @@ -1134,10 +1136,11 @@ int listmp_sharedmemory_insert(listmp_sharedmemory_handle listmp_handle, /* Get SRPtr for cur_elem->prev */ localPrevElem = sharedregion_get_ptr((u32 *)cur_elem->prev); - + dsb(); new_elem->next = sharedCurElem; new_elem->prev = cur_elem->prev; localPrevElem->next = sharedNewElem; + dsb(); cur_elem->prev = sharedNewElem; if (obj->params.gate != NULL) @@ -1191,7 +1194,7 @@ int listmp_sharedmemory_remove(listmp_sharedmemory_handle listmp_handle, localPrevElem = sharedregion_get_ptr((u32 *)elem->prev); localNextElem = sharedregion_get_ptr((u32 *)elem->next); - + dsb(); localPrevElem->next = elem->next; localNextElem->prev = elem->prev; diff --git a/drivers/dsp/syslink/multicore_ipc/platform.c b/drivers/dsp/syslink/multicore_ipc/platform.c index 957e9a2a84f1..5a08400b0743 100644 --- a/drivers/dsp/syslink/multicore_ipc/platform.c +++ b/drivers/dsp/syslink/multicore_ipc/platform.c @@ -94,7 +94,7 @@ /*! * @brief Wait for this much poll count when sending event */ -#define NOTIFY_SENDEVENTPOLLCOUNT ((u32) -1) +#define NOTIFY_SENDEVENTPOLLCOUNT 0xfffff /*! * @brief Align buffer in Heap diff --git a/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c b/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c index 413cae455eb3..860709f26430 100644 --- a/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c +++ b/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c @@ -941,7 +941,7 @@ int notify_ducatidrv_sendevent(struct notify_driver_object *handle, BUG_ON(handle == NULL); BUG_ON(handle->driver_object == NULL); - + dsb(); driver_object = (struct notify_ducatidrv_object *) handle->driver_object; @@ -970,9 +970,12 @@ int notify_ducatidrv_sendevent(struct notify_driver_object *handle, proc_ctrl[driver_object->other_id].reg_mask. enable_mask) != 1)) { status = -ENODEV; + printk(KERN_ERR "NOTIFY DRV: OTHER SIDE NOT READY TO" + "RECEIVE. %d\n", event_no); /* This may be used for polling till other-side is ready, so do not set failure reason.*/ } else { + dsb(); /* Enter critical section protection. */ if (mutex_lock_interruptible(notify_ducatidriver_state. gate_handle) != 0) @@ -1009,6 +1012,23 @@ int notify_ducatidrv_sendevent(struct notify_driver_object *handle, information to theremote processor */ status = omap_mbox_msg_send(ducati_mbox, payload); + i = 0; + while ((other_event_chart[event_no].flag + != DOWN) + && status == 0) { + /* Leave critical section protection + Create a window of opportunity + for other interrupts to be handled. + */ + i++; + if ((max_poll_count != (int) -1) + && (i == max_poll_count)) { + status = -EBUSY; + printk(KERN_ERR "NOTIFY-remote" + "not processed event %d\n", + event_no); + } + } } /* Leave critical section protection. */ mutex_unlock(notify_ducatidriver_state.gate_handle); @@ -1147,12 +1167,14 @@ static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg) struct notify_shmdrv_eventreg *reg_chart; VOLATILE struct notify_shmdrv_proc_ctrl *proc_ctrl_ptr; int event_no; + dsb(); + /* Enter critical section protection. */ driver_obj = (struct notify_ducatidrv_object *) ref_data; proc_ctrl_ptr = &(driver_obj->ctrl_ptr->proc_ctrl[driver_obj->self_id]); reg_chart = driver_obj->reg_chart; self_event_chart = proc_ctrl_ptr->self_event_chart; - + dsb(); /* Execute the loop till no asserted event is found for one complete loop through all registered events @@ -1169,9 +1191,11 @@ static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg) payload = self_event_chart[event_no]. payload; + dsb(); /* Acknowledge the event. */ payload = (int)ntfy_msg; self_event_chart[event_no].flag = DOWN; + dsb(); /*Call the callbacks associated with the event*/ temp = driver_obj-> event_list[event_no]. @@ -1212,6 +1236,7 @@ static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg) } } while ((event_no != (int) -1) && (i < driver_obj->params.num_events)); + } /* |