Commit 25ca34bd authored by Suman Anna's avatar Suman Anna Committed by Hari Kanigeri

SYSLINK: ipc - bug fixes incorporated from SysLink 2.00.00.12

This patch incorporates a number of bug fixes from the Syslink
2.00.00.12 drop. The following is the summary of changes.

1. sharedregion:
	- sharedregion_remove() is corrected to remove the
		sharedregion entry from the desired processor table.
2. platform_mem:
	- fixed memory leaks.
3. nameserver_remotenotify:
	- an atomic_t variable is added to maintain reference counting
		and the state of the module.
	- nameserver_get_local searches directly copy the value into the
		sharedmemory request buffer.
	- additional error checking is added.
4. messageq:
	- Number of priority queues definition moved from messageq source
		code to messageq header file, and is now also used by
		the messageq_transportshm module.
	- messageqq_transportshm module state object also keeps track of
		the individual messageq_transportshm instances created.
5. listmp_sharedmemory:
	- listmp_sharedmemory_open return value can come from nameserver,
		and so is checked against only a negative value for failure
	- sharedregion value is added into the nameserver database rather
		than the absolute sharedaddr.
	- minor changes in variable names.
6. heapbuf:
	- additional checks were added for valid sharedregion ptrs.
	- heapbuf_open return value can come from nameserver, and so
		is checked against only a negative value for failure.
	- minor changes in variable names.
7. gatepeterson:
	- minor changes in gatepeterson module. This module is currently
		missing the gatespinlock for interrupt context protection.
	- additional checks were added for valid sharedregion ptrs.
Signed-off-by: default avatarSuman Anna <s-anna@ti.com>
parent 66506b23
...@@ -247,6 +247,12 @@ ...@@ -247,6 +247,12 @@
*/ */
#define MESSAGEQ_ALLOWGROWTH (~((u32) 0)) #define MESSAGEQ_ALLOWGROWTH (~((u32) 0))
/*!
* Number of types of priority queues for each transport
*/
#define MESSAGEQ_NUM_PRIORITY_QUEUES 2
/* ============================================================================= /* =============================================================================
* Structures & Enums * Structures & Enums
* ============================================================================= * =============================================================================
...@@ -455,5 +461,4 @@ int messageq_register_transport(void *messageq_transportshm_handle, ...@@ -455,5 +461,4 @@ int messageq_register_transport(void *messageq_transportshm_handle,
int messageq_unregister_transport(u16 proc_id, u32 priority); int messageq_unregister_transport(u16 proc_id, u32 priority);
#endif /* _MESSAGEQ_H_ */ #endif /* _MESSAGEQ_H_ */
...@@ -387,18 +387,18 @@ int gatepeterson_delete(void **gphandle) ...@@ -387,18 +387,18 @@ int gatepeterson_delete(void **gphandle)
handle = (struct gatepeterson_object *)(*gphandle); handle = (struct gatepeterson_object *)(*gphandle);
obj = (struct gatepeterson_obj *)handle->obj; obj = (struct gatepeterson_obj *)handle->obj;
if (obj == NULL) { if (unlikely(obj == NULL)) {
retval = -EINVAL; retval = -EINVAL;
goto exit; goto exit;
} }
if (obj->attrs == NULL) { if (unlikely(obj->attrs == NULL)) {
retval = -EINVAL; retval = -EINVAL;
goto exit; goto exit;
} }
/* Check if we have created the GP or not */ /* Check if we have created the GP or not */
if (obj->attrs->creator_proc_id != multiproc_get_id(NULL)) { if (unlikely(obj->attrs->creator_proc_id != multiproc_get_id(NULL))) {
retval = -EACCES; retval = -EACCES;
goto exit; goto exit;
} }
...@@ -438,6 +438,7 @@ int gatepeterson_delete(void **gphandle) ...@@ -438,6 +438,7 @@ int gatepeterson_delete(void **gphandle)
obj->local_gate = NULL; /* TBD: Fixme */ obj->local_gate = NULL; /* TBD: Fixme */
break; break;
case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */ case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */
/* FIXME: Add a spinlock protection */
case GATEPETERSON_PROTECT_TASKLET: /* Fall through */ case GATEPETERSON_PROTECT_TASKLET: /* Fall through */
case GATEPETERSON_PROTECT_THREAD: /* Fall through */ case GATEPETERSON_PROTECT_THREAD: /* Fall through */
case GATEPETERSON_PROTECT_PROCESS: case GATEPETERSON_PROTECT_PROCESS:
...@@ -620,6 +621,11 @@ int gatepeterson_close(void **gphandle) ...@@ -620,6 +621,11 @@ int gatepeterson_close(void **gphandle)
handle = (struct gatepeterson_object *)(*gphandle); handle = (struct gatepeterson_object *)(*gphandle);
obj = (struct gatepeterson_obj *) handle->obj; obj = (struct gatepeterson_obj *) handle->obj;
if (unlikely(obj == NULL)) {
retval = -EINVAL;
goto exit;
}
retval = mutex_lock_interruptible(obj->local_gate); retval = mutex_lock_interruptible(obj->local_gate);
if (retval) if (retval)
goto exit; goto exit;
...@@ -647,13 +653,14 @@ int gatepeterson_close(void **gphandle) ...@@ -647,13 +653,14 @@ int gatepeterson_close(void **gphandle)
obj->local_gate = NULL; /* TBD: Fixme */ obj->local_gate = NULL; /* TBD: Fixme */
break; break;
case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */ case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */
/* FIXME: Add a spinlock protection */
case GATEPETERSON_PROTECT_TASKLET: /* Fall through */ case GATEPETERSON_PROTECT_TASKLET: /* Fall through */
case GATEPETERSON_PROTECT_THREAD: /* Fall through */ case GATEPETERSON_PROTECT_THREAD: /* Fall through */
case GATEPETERSON_PROTECT_PROCESS: case GATEPETERSON_PROTECT_PROCESS:
kfree(obj->local_gate); kfree(obj->local_gate);
break; break;
default: default:
/* An invalid protection level was supplied, FIXME */ /* An invalid protection level was supplied */
break; break;
} }
...@@ -874,6 +881,9 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params, ...@@ -874,6 +881,9 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params,
obj->nested = 0; obj->nested = 0;
obj->top = handle; obj->top = handle;
/* Populate the params member */
memcpy(&obj->params, params, sizeof(struct gatepeterson_params));
/* Create the local lock if not provided */ /* Create the local lock if not provided */
if (likely(params->local_protection == GATEPETERSON_PROTECT_DEFAULT)) if (likely(params->local_protection == GATEPETERSON_PROTECT_DEFAULT))
obj->params.local_protection = obj->params.local_protection =
...@@ -890,6 +900,7 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params, ...@@ -890,6 +900,7 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params,
* protection here also * protection here also
*/ */
case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */ case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */
/* FIXME: Add a spinlock protection */
case GATEPETERSON_PROTECT_TASKLET: /* Fall through */ case GATEPETERSON_PROTECT_TASKLET: /* Fall through */
case GATEPETERSON_PROTECT_THREAD: /* Fall through */ case GATEPETERSON_PROTECT_THREAD: /* Fall through */
case GATEPETERSON_PROTECT_PROCESS: case GATEPETERSON_PROTECT_PROCESS:
...@@ -907,8 +918,6 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params, ...@@ -907,8 +918,6 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params,
break; break;
} }
/* Populate the params member */
memcpy(&obj->params, params, sizeof(struct gatepeterson_params));
/* Put in the local list */ /* Put in the local list */
retval = mutex_lock_interruptible(gatepeterson_state.mod_lock); retval = mutex_lock_interruptible(gatepeterson_state.mod_lock);
if (retval) if (retval)
...@@ -944,6 +953,4 @@ exit: ...@@ -944,6 +953,4 @@ exit:
retval); retval);
return NULL; return NULL;
} }
...@@ -209,8 +209,12 @@ static int gatepeterson_ioctl_open(struct gatepeterson_cmd_args *cargs) ...@@ -209,8 +209,12 @@ static int gatepeterson_ioctl_open(struct gatepeterson_cmd_args *cargs)
} }
} }
/* For open by name, the shared_add_srptr may be invalid */
if (cargs->args.open.shared_addr_srptr != \
(u32) SHAREDREGION_INVALIDSRPTR) {
params.shared_addr = sharedregion_get_ptr( params.shared_addr = sharedregion_get_ptr(
(u32 *)cargs->args.create.shared_addr_srptr); (u32 *)cargs->args.open.shared_addr_srptr);
}
cargs->api_status = gatepeterson_open(&handle, &params); cargs->api_status = gatepeterson_open(&handle, &params);
cargs->args.open.handle = handle; cargs->args.open.handle = handle;
......
...@@ -343,8 +343,8 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params, ...@@ -343,8 +343,8 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params,
s32 retval = 0; s32 retval = 0;
u32 i; u32 i;
s32 align; s32 align;
s32 shmindex; s32 shm_index;
u32 shared_shmbase; u32 shared_shm_base;
void *entry = NULL; void *entry = NULL;
if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count),
...@@ -379,6 +379,7 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params, ...@@ -379,6 +379,7 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params,
handle->alloc = &heapbuf_alloc; handle->alloc = &heapbuf_alloc;
handle->free = &heapbuf_free; handle->free = &heapbuf_free;
handle->get_stats = &heapbuf_get_stats; handle->get_stats = &heapbuf_get_stats;
/* FIXME: handle->is_blocking = &heapbuf_isblocking; */
/* Create the shared list */ /* Create the shared list */
listmp_sharedmemory_params_init(NULL, &listmp_params); listmp_sharedmemory_params_init(NULL, &listmp_params);
listmp_params.shared_addr = (u32 *)((u32) (params->shared_addr) listmp_params.shared_addr = (u32 *)((u32) (params->shared_addr)
...@@ -464,13 +465,13 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params, ...@@ -464,13 +465,13 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params,
if ((likely(heapbuf_state.cfg.use_nameserver == true)) if ((likely(heapbuf_state.cfg.use_nameserver == true))
&& (create_flag == true)) { && (create_flag == true)) {
/* We will store a shared pointer in the nameserver */ /* We will store a shared pointer in the nameserver */
shmindex = sharedregion_get_index(params->shared_addr); shm_index = sharedregion_get_index(params->shared_addr);
shared_shmbase = (u32)sharedregion_get_srptr( shared_shm_base = (u32)sharedregion_get_srptr(
params->shared_addr, shmindex); params->shared_addr, shm_index);
if (obj->params.name != NULL) { if (obj->params.name != NULL) {
entry = nameserver_add_uint32(heapbuf_state.ns_handle, entry = nameserver_add_uint32(heapbuf_state.ns_handle,
params->name, params->name,
(u32)(shared_shmbase)); (u32)(shared_shm_base));
if (entry == NULL) { if (entry == NULL) {
retval = -EFAULT; retval = -EFAULT;
goto ns_add_error; goto ns_add_error;
...@@ -595,8 +596,10 @@ int heapbuf_delete(void **handle_ptr) ...@@ -595,8 +596,10 @@ int heapbuf_delete(void **handle_ptr)
} }
obj = (struct heapbuf_obj *)handle->obj; obj = (struct heapbuf_obj *)handle->obj;
if (obj == NULL) if (obj == NULL) {
retval = -EINVAL;
goto error; goto error;
}
myproc_id = multiproc_get_id(NULL); myproc_id = multiproc_get_id(NULL);
......
...@@ -192,12 +192,15 @@ static int heapbuf_ioctl_open(struct heapbuf_cmd_args *cargs) ...@@ -192,12 +192,15 @@ static int heapbuf_ioctl_open(struct heapbuf_cmd_args *cargs)
} }
} }
params.shared_addr = sharedregion_get_ptr((u32 *) /* For open by name, the shared_add_srptr may be invalid */
cargs->args.open.shared_addr_srptr); if (cargs->args.open.shared_addr_srptr != SHAREDREGION_INVALIDSRPTR) {
params.shared_addr = sharedregion_get_ptr(
(u32 *)cargs->args.open.shared_addr_srptr);
}
params.gate = cargs->args.open.knl_gate; params.gate = cargs->args.open.knl_gate;
cargs->api_status = heapbuf_open(&handle, &params); cargs->api_status = heapbuf_open(&handle, &params);
if (cargs->api_status != 0) if (cargs->api_status < 0)
goto free_name; goto free_name;
cargs->args.open.handle = handle; cargs->args.open.handle = handle;
......
...@@ -1309,8 +1309,8 @@ listmp_sharedmemory_handle _listmp_sharedmemory_create( ...@@ -1309,8 +1309,8 @@ listmp_sharedmemory_handle _listmp_sharedmemory_create(
listmp_sharedmemory_object *handle = NULL; listmp_sharedmemory_object *handle = NULL;
struct listmp_sharedmemory_obj *obj = NULL; struct listmp_sharedmemory_obj *obj = NULL;
u32 key; u32 key;
u32 shmIndex; u32 shm_index;
u32 *sharedShmBase; u32 *shared_shm_base;
BUG_ON(params == NULL); BUG_ON(params == NULL);
...@@ -1419,15 +1419,15 @@ listmp_sharedmemory_handle _listmp_sharedmemory_create( ...@@ -1419,15 +1419,15 @@ listmp_sharedmemory_handle _listmp_sharedmemory_create(
/* We will store a shared pointer in the /* We will store a shared pointer in the
* NameServer * NameServer
*/ */
shmIndex = sharedregion_get_index(params->shared_addr); shm_index = sharedregion_get_index(params->shared_addr);
sharedShmBase = sharedregion_get_srptr( shared_shm_base = sharedregion_get_srptr(
params->shared_addr, shmIndex); params->shared_addr, shm_index);
/* Add list instance to name server */ /* Add list instance to name server */
if (obj->params.name != NULL) { if (obj->params.name != NULL) {
obj->ns_key = nameserver_add_uint32( obj->ns_key = nameserver_add_uint32(
listmp_sharedmemory_state.ns_handle, listmp_sharedmemory_state.ns_handle,
params->name, params->name,
(u32) (params->shared_addr)); (u32) (shared_shm_base));
if (obj->ns_key == NULL) if (obj->ns_key == NULL)
status = -EFAULT; status = -EFAULT;
} }
......
...@@ -248,15 +248,19 @@ static inline int listmp_sharedmemory_ioctl_open( ...@@ -248,15 +248,19 @@ static inline int listmp_sharedmemory_ioctl_open(
} }
} }
/* For open by name, the shared_add_srptr may be invalid */
if (cargs->args.open.shared_addr_srptr != \
(u32)SHAREDREGION_INVALIDSRPTR) {
params.shared_addr = sharedregion_get_ptr( params.shared_addr = sharedregion_get_ptr(
(u32 *)cargs->args.open.shared_addr_srptr); (u32 *)cargs->args.open.shared_addr_srptr);
}
if (unlikely(params.shared_addr == NULL)) if (unlikely(params.shared_addr == NULL))
goto free_name; goto free_name;
/* Update gate in params. */ /* Update gate in params. */
params.gate = cargs->args.open.knl_gate; params.gate = cargs->args.open.knl_gate;
status = listmp_sharedmemory_open(&listmp_handle, &params); status = listmp_sharedmemory_open(&listmp_handle, &params);
if (status) if (status < 0)
goto free_name; goto free_name;
cargs->args.open.listmp_handle = listmp_handle; cargs->args.open.listmp_handle = listmp_handle;
......
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
#include <messageq.h> #include <messageq.h>
/*! @brief Macro to make a correct module magic number with refCount */ /* Macro to make a correct module magic number with refCount */
#define MESSAGEQ_MAKE_MAGICSTAMP(x) ((MESSAGEQ_MODULEID << 12u) | (x)) #define MESSAGEQ_MAKE_MAGICSTAMP(x) ((MESSAGEQ_MODULEID << 12u) | (x))
/* ============================================================================= /* =============================================================================
...@@ -127,11 +127,6 @@ ...@@ -127,11 +127,6 @@
*/ */
#define MESSAGEQ_NAMESERVER "MessageQ" #define MESSAGEQ_NAMESERVER "MessageQ"
/*!
* @brief Number of types of priority queues for each transport
*/
#define MESSAGEQ_NUM_PRIORITY_QUEUES 2
/* ============================================================================= /* =============================================================================
* Structures & Enums * Structures & Enums
...@@ -152,7 +147,7 @@ struct messageq_module_object { ...@@ -152,7 +147,7 @@ struct messageq_module_object {
struct messageq_params default_inst_params; struct messageq_params default_inst_params;
/*!< Default instance creation parameters */ /*!< Default instance creation parameters */
void *transports[MULTIPROC_MAXPROCESSORS][MESSAGEQ_NUM_PRIORITY_QUEUES]; void *transports[MULTIPROC_MAXPROCESSORS][MESSAGEQ_NUM_PRIORITY_QUEUES];
/*!< Transport to be set in messageq_registerTransport */ /*!< Transport to be set in messageq_register_transport */
void **queues; /*messageq_handle *queues;*/ void **queues; /*messageq_handle *queues;*/
/*!< Grow option */ /*!< Grow option */
void **heaps; /*Heap_Handle *heaps; */ void **heaps; /*Heap_Handle *heaps; */
...@@ -847,6 +842,7 @@ int messageq_get(void *messageq_handle, messageq_msg *msg, ...@@ -847,6 +842,7 @@ int messageq_get(void *messageq_handle, messageq_msg *msg,
mutex_unlock(messageq_state.gate_handle); mutex_unlock(messageq_state.gate_handle);
} }
} }
return status;
exit: exit:
if (status < 0) if (status < 0)
......
...@@ -70,6 +70,9 @@ struct messageq_transportshm_moduleobject { ...@@ -70,6 +70,9 @@ struct messageq_transportshm_moduleobject {
/*< Default instance parameters */ /*< Default instance parameters */
void *gate_handle; void *gate_handle;
/*< Handle to the gate for local thread safety */ /*< Handle to the gate for local thread safety */
void *transports[MULTIPROC_MAXPROCESSORS][MESSAGEQ_NUM_PRIORITY_QUEUES];
/*!< Transport to be set in messageq_register_transport */
}; };
/* /*
...@@ -221,7 +224,6 @@ int messageq_transportshm_setup(const struct messageq_transportshm_config *cfg) ...@@ -221,7 +224,6 @@ int messageq_transportshm_setup(const struct messageq_transportshm_config *cfg)
messageq_transportshm_state.gate_handle = \ messageq_transportshm_state.gate_handle = \
kmalloc(sizeof(struct mutex), GFP_KERNEL); kmalloc(sizeof(struct mutex), GFP_KERNEL);
mutex_init(messageq_transportshm_state.gate_handle);
if (messageq_transportshm_state.gate_handle == NULL) { if (messageq_transportshm_state.gate_handle == NULL) {
/* @retval MESSAGEQTRANSPORTSHM_E_FAIL Failed to create /* @retval MESSAGEQTRANSPORTSHM_E_FAIL Failed to create
GateMutex! */ GateMutex! */
...@@ -232,10 +234,13 @@ int messageq_transportshm_setup(const struct messageq_transportshm_config *cfg) ...@@ -232,10 +234,13 @@ int messageq_transportshm_setup(const struct messageq_transportshm_config *cfg)
MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0)); MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0));
goto exit; goto exit;
} }
mutex_init(messageq_transportshm_state.gate_handle);
/* Copy the user provided values into the state object. */ /* Copy the user provided values into the state object. */
memcpy(&messageq_transportshm_state.cfg, cfg, memcpy(&messageq_transportshm_state.cfg, cfg,
sizeof(struct messageq_transportshm_config)); sizeof(struct messageq_transportshm_config));
memset(&(messageq_transportshm_state.transports), 0, (sizeof(void *) * \
MULTIPROC_MAXPROCESSORS * MESSAGEQ_NUM_PRIORITY_QUEUES));
return status; return status;
exit: exit:
...@@ -257,6 +262,8 @@ exit: ...@@ -257,6 +262,8 @@ exit:
int messageq_transportshm_destroy(void) int messageq_transportshm_destroy(void)
{ {
int status = 0; int status = 0;
u16 i;
u16 j;
if (WARN_ON(atomic_cmpmask_and_lt( if (WARN_ON(atomic_cmpmask_and_lt(
&(messageq_transportshm_state.ref_count), &(messageq_transportshm_state.ref_count),
...@@ -266,21 +273,41 @@ int messageq_transportshm_destroy(void) ...@@ -266,21 +273,41 @@ int messageq_transportshm_destroy(void)
goto exit; goto exit;
} }
if (atomic_dec_return(&messageq_transportshm_state.ref_count) if (!(atomic_dec_return(&messageq_transportshm_state.ref_count)
== MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0)) { == MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0))) {
status = 1;
goto exit;
}
/* Temporarily increment ref_count here. */
atomic_set(&messageq_transportshm_state.ref_count,
MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1));
/* Delete any Transports that have not been deleted so far. */
for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) {
for (j = 0 ; j < MESSAGEQ_NUM_PRIORITY_QUEUES; j++) {
if (messageq_transportshm_state.transports[i][j] != \
NULL) {
messageq_transportshm_delete(&
(messageq_transportshm_state.transports[i][j]));
}
}
}
if (messageq_transportshm_state.gate_handle != NULL) { if (messageq_transportshm_state.gate_handle != NULL) {
kfree(messageq_transportshm_state.gate_handle); kfree(messageq_transportshm_state.gate_handle);
messageq_transportshm_state.gate_handle = NULL; messageq_transportshm_state.gate_handle = NULL;
} }
/* Decrease the ref_count */ /* Decrease the ref_count */
atomic_set(&messageq_transportshm_state.ref_count, atomic_set(&messageq_transportshm_state.ref_count,
MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0)); MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0));
}
return 0; return 0;
exit: exit:
printk(KERN_ERR "messageq_transportshm_destroy failed: status = 0x%x\n", if (status < 0) {
status); printk(KERN_ERR "messageq_transportshm_destroy failed: "
"status = 0x%x\n", status);
}
return status; return status;
} }
...@@ -360,6 +387,12 @@ void *messageq_transportshm_create(u16 proc_id, ...@@ -360,6 +387,12 @@ void *messageq_transportshm_create(u16 proc_id,
status = -EINVAL; status = -EINVAL;
goto exit; goto exit;
} }
if (messageq_transportshm_state.transports[proc_id][params->priority] \
!= NULL) {
/* Specified transport is already registered. */
status = MESSAGEQ_E_ALREADYEXISTS;
goto exit;
}
/* /*
* Determine who gets the '0' slot and who gets the '1' slot * Determine who gets the '0' slot and who gets the '1' slot
...@@ -459,8 +492,11 @@ void *messageq_transportshm_create(u16 proc_id, ...@@ -459,8 +492,11 @@ void *messageq_transportshm_create(u16 proc_id,
/* Register the transport with MessageQ */ /* Register the transport with MessageQ */
status = messageq_register_transport((void *)handle, proc_id, status = messageq_register_transport((void *)handle, proc_id,
(u32)params->priority); (u32)params->priority);
if (status >= 0) if (status >= 0) {
messageq_transportshm_state.transports
[proc_id][params->priority] = (void *)handle;
handle->status = messageq_transportshm_status_UP; handle->status = messageq_transportshm_status_UP;
}
return handle; return handle;
listmp_open_fail: listmp_open_fail:
...@@ -468,10 +504,8 @@ listmp_open_fail: ...@@ -468,10 +504,8 @@ listmp_open_fail:
"listmp_sharedmemory_open failed!\n"); "listmp_sharedmemory_open failed!\n");
notify_register_fail: notify_register_fail:
if (status < 0) { if (status < 0) {
if (handle != NULL) { if (handle != NULL)
kfree(handle); messageq_transportshm_delete((void **)(&handle));
handle = NULL;
}
} }
exit: exit:
...@@ -513,6 +547,9 @@ int messageq_transportshm_delete(void **mqtshm_handleptr) ...@@ -513,6 +547,9 @@ int messageq_transportshm_delete(void **mqtshm_handleptr)
} }
obj = (struct messageq_transportshm_object *) (*mqtshm_handleptr); obj = (struct messageq_transportshm_object *) (*mqtshm_handleptr);
/* Clear handle in the local array */
messageq_transportshm_state.transports[obj->proc_id][obj->priority] = \
NULL;
obj->attrs[obj->my_index]->flag = 0; obj->attrs[obj->my_index]->flag = 0;
status = listmp_sharedmemory_delete( status = listmp_sharedmemory_delete(
(listmp_sharedmemory_handle *)&obj->my_listmp_handle); (listmp_sharedmemory_handle *)&obj->my_listmp_handle);
......
...@@ -16,12 +16,19 @@ ...@@ -16,12 +16,19 @@
* PURPOSE. * PURPOSE.
*/ */
/* Standard headers */
#include <linux/types.h> #include <linux/types.h>
/* Utilities headers */
#include <linux/string.h> #include <linux/string.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
/* Syslink headers */
#include <syslink/atomic_linux.h>
/* Module level headers */
#include <gate_remote.h> #include <gate_remote.h>
#include <gatepeterson.h> #include <gatepeterson.h>
#include <nameserver.h> #include <nameserver.h>
...@@ -29,12 +36,25 @@ ...@@ -29,12 +36,25 @@
#include <nameserver_remotenotify.h> #include <nameserver_remotenotify.h>
#include <notify.h> #include <notify.h>
/*
* Macro to make a correct module magic number with refCount
*/
#define NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(x) \
((NAMESERVERREMOTENOTIFY_MODULEID << 12u) | (x))
/* /*
* Cache line length * Cache line length
* TODO: Short-term hack. Make parameter or figure out some other way! * TODO: Short-term hack. Make parameter or figure out some other way!
*/ */
#define NAMESERVERREMOTENOTIFY_CACHESIZE 128 #define NAMESERVERREMOTENOTIFY_CACHESIZE 128
/*
* Maximum length of value buffer that can be stored in the NameServer
* managed by this NameServerRemoteNotify instance.
*/
#define NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN 300
/* Defines the nameserver_remotenotify state object, which contains all the /* Defines the nameserver_remotenotify state object, which contains all the
* module specific information * module specific information
*/ */
...@@ -44,6 +64,7 @@ struct nameserver_remotenotify_module_object { ...@@ -44,6 +64,7 @@ struct nameserver_remotenotify_module_object {
struct nameserver_remotenotify_params def_inst_params; struct nameserver_remotenotify_params def_inst_params;
bool is_setup; bool is_setup;
void *gate_handle; void *gate_handle;
atomic_t ref_count;
}; };
/* /*
...@@ -55,8 +76,6 @@ struct nameserver_remotenotify_attrs { ...@@ -55,8 +76,6 @@ struct nameserver_remotenotify_attrs {
u32 shared_addr_size; u32 shared_addr_size;
}; };
#define MAX_VALUE_LEN 300 /* This should be actually sync with
nameserver value or user configured value */
/* /*
* NameServer remote transport packet definition * NameServer remote transport packet definition
*/ */
...@@ -68,7 +87,7 @@ struct nameserver_remotenotify_message { ...@@ -68,7 +87,7 @@ struct nameserver_remotenotify_message {
u32 value_len; u32 value_len;
char instance_name[32]; char instance_name[32];
char name[32]; char name[32];
char value_buf[MAX_VALUE_LEN]; char value_buf[NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN];
}; };
/* /*
...@@ -157,6 +176,17 @@ int nameserver_remotenotify_setup( ...@@ -157,6 +176,17 @@ int nameserver_remotenotify_setup(
struct mutex *lock = NULL; struct mutex *lock = NULL;
bool user_cfg = true; bool user_cfg = true;
/* This sets the ref_count variable is not initialized, upper 16 bits is
* written with module Id to ensure correctness of refCount variable.
*/
atomic_cmpmask_and_set(&nameserver_remotenotify_state.ref_count,
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0));
if (atomic_inc_return(&nameserver_remotenotify_state.ref_count)
!= NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) {
return 1;
}
if (cfg == NULL) { if (cfg == NULL) {
nameserver_remotenotify_get_config(&tmp_cfg); nameserver_remotenotify_get_config(&tmp_cfg);
cfg = &tmp_cfg; cfg = &tmp_cfg;
...@@ -192,12 +222,30 @@ exit: ...@@ -192,12 +222,30 @@ exit:
*/ */
int nameserver_remotenotify_destroy(void) int nameserver_remotenotify_destroy(void)
{ {
s32 retval = 0;
if (WARN_ON(atomic_cmpmask_and_lt(
&(nameserver_remotenotify_state.ref_count),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true)) {
retval = -ENODEV;
goto exit;
}
if (!(atomic_dec_return(&nameserver_remotenotify_state.ref_count)
== NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0))) {
retval = 1;
goto exit;
}
if (nameserver_remotenotify_state.gate_handle != NULL) if (nameserver_remotenotify_state.gate_handle != NULL)
kfree(nameserver_remotenotify_state.gate_handle); kfree(nameserver_remotenotify_state.gate_handle);
nameserver_remotenotify_state.is_setup = false; nameserver_remotenotify_state.is_setup = false;
return 0; return 0;
exit:
return retval;
} }
/* /*
...@@ -211,7 +259,21 @@ void nameserver_remotenotify_params_init(void *handle, ...@@ -211,7 +259,21 @@ void nameserver_remotenotify_params_init(void *handle,
struct nameserver_remotenotify_object *object = NULL; struct nameserver_remotenotify_object *object = NULL;
struct nameserver_remotenotify_obj *obj = NULL; struct nameserver_remotenotify_obj *obj = NULL;
BUG_ON(params == NULL); if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) {
printk(KERN_ERR "nameserver_remotenotify_params_init failed: "
"Module is not initialized!\n");
return;
}
if (WARN_ON(params == NULL)) {
printk(KERN_ERR "nameserver_remotenotify_params_init failed: "
"Argument of type(nameserver_remotenotify_params *) "
"is NULL!\n");
return;
}
object = (struct nameserver_remotenotify_object *)handle; object = (struct nameserver_remotenotify_object *)handle;
if (handle == NULL) if (handle == NULL)
memcpy(params, memcpy(params,
...@@ -240,45 +302,59 @@ void nameserver_remotenotify_callback(u16 proc_id, u32 event_no, ...@@ -240,45 +302,59 @@ void nameserver_remotenotify_callback(u16 proc_id, u32 event_no,
u32 proc_count; u32 proc_count;
u16 offset = 0; u16 offset = 0;
void *nshandle = NULL; void *nshandle = NULL;
char value[MAX_VALUE_LEN] = { 0 }; /* To take care of value len > 4, u32 value_len;
do we need to make it global? */
u32 key; u32 key;
s32 retval = 0; s32 retval = 0;
s32 count = -ENOENT;
if (WARN_ON(arg == NULL)) if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count),
return; NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) {
retval = -ENODEV;
goto exit;
}
if (WARN_ON(arg == NULL)) {
retval = -EINVAL;
goto exit;
}
proc_count = multiproc_get_max_processors(); proc_count = multiproc_get_max_processors();
if (WARN_ON(proc_id >= proc_count)) if (WARN_ON(proc_id >= proc_count)) {
return; retval = -EINVAL;
goto exit;
}
handle = (struct nameserver_remotenotify_obj *)arg; handle = (struct nameserver_remotenotify_obj *)arg;
if ((multiproc_get_id(NULL) > proc_id)) if ((multiproc_get_id(NULL) > proc_id))
offset = 1; offset = 1;
if (handle->msg[1 - offset]->request != true) if (handle->msg[1 - offset]->request != true)
goto exit; goto signal_response;
/* This is a request */ /* This is a request */
value_len = handle->msg[1 - offset]->value_len;
nshandle = nameserver_get_handle( nshandle = nameserver_get_handle(
handle->msg[1 - offset]->instance_name); handle->msg[1 - offset]->instance_name);
if (nshandle != NULL) if (nshandle != NULL) {
/* Search for the NameServer entry */ /* Search for the NameServer entry */
retval = nameserver_get_local(nshandle, if (value_len == sizeof(u32)) {
handle->msg[1 - offset]->name, &value, count = nameserver_get_local(nshandle,
handle->msg[1 - offset]->value_len); handle->msg[1 - offset]->name,
&handle->msg[1 - offset]->value,
value_len);
} else {
count = nameserver_get_local(nshandle,
handle->msg[1 - offset]->name,
&handle->msg[1 - offset]->value_buf,
value_len);
}
}
key = gatepeterson_enter(handle->params.gate); key = gatepeterson_enter(handle->params.gate);
/* If retval > 0 then an entry found */ /* If retval > 0 then an entry found */
if (retval > 0) { if (count != -ENOENT)
handle->msg[1 - offset]->request_status = true; handle->msg[1 - offset]->request_status = true;
if (handle->msg[1 - offset]->value_len == sizeof(u32))
memcpy(&(handle->msg[1 - offset]->value), &value,
sizeof(u32));
else
memcpy(&(handle->msg[1 - offset]->value_buf), &value,
handle->msg[1 - offset]->value_len);
}
/* Send a response back */ /* Send a response back */
handle->msg[1 - offset]->response = true; handle->msg[1 - offset]->response = true;
...@@ -293,9 +369,14 @@ void nameserver_remotenotify_callback(u16 proc_id, u32 event_no, ...@@ -293,9 +369,14 @@ void nameserver_remotenotify_callback(u16 proc_id, u32 event_no,
retval = notify_sendevent(handle->params.notify_driver, retval = notify_sendevent(handle->params.notify_driver,
proc_id, event_no, 0, true); proc_id, event_no, 0, true);
exit: signal_response:
if (handle->msg[offset]->response == true) if (handle->msg[offset]->response == true)
up(handle->sem_handle); up(handle->sem_handle);
exit:
if (retval < 0) {
printk(KERN_ERR "nameserver_remotenotify_callback failed! "
"status = 0x%x\n", retval);
}
return; return;
} }
...@@ -318,13 +399,23 @@ int nameserver_remotenotify_get(void *rhandle, ...@@ -318,13 +399,23 @@ int nameserver_remotenotify_get(void *rhandle,
BUG_ON(instance_name == NULL); BUG_ON(instance_name == NULL);
BUG_ON(name == NULL); BUG_ON(name == NULL);
BUG_ON(value == NULL); BUG_ON(value == NULL);
BUG_ON((value_len <= 0) || \
(value_len > NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN));
if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) {
retval = -ENODEV;
goto exit;
}
if (WARN_ON(rhandle == NULL)) { if (WARN_ON(rhandle == NULL)) {
retval = -EINVAL; retval = -EINVAL;
goto exit; goto exit;
} }
if (value_len == 0) { if ((value_len == 0) || \
(value_len > NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN)) {
retval = -EINVAL; retval = -EINVAL;
goto exit; goto exit;
} }
...@@ -351,8 +442,12 @@ int nameserver_remotenotify_get(void *rhandle, ...@@ -351,8 +442,12 @@ int nameserver_remotenotify_get(void *rhandle,
obj->params.notify_event_no, obj->params.notify_event_no,
0, /* Payload */ 0, /* Payload */
false); /* Not sending a payload */ false); /* Not sending a payload */
if (retval < 0) if (retval < 0) {
/* Undo previous operations */
obj->msg[offset]->request = 0;
obj->msg[offset]->value_len = 0;
goto notify_error; goto notify_error;
}
gatepeterson_leave(obj->params.gate, key); gatepeterson_leave(obj->params.gate, key);
...@@ -423,9 +518,21 @@ void *nameserver_remotenotify_create(u16 proc_id, ...@@ -423,9 +518,21 @@ void *nameserver_remotenotify_create(u16 proc_id,
struct nameserver_remotenotify_obj *obj = NULL; struct nameserver_remotenotify_obj *obj = NULL;
u16 proc_count; u16 proc_count;
s32 retval = 0; s32 retval = 0;
s32 retval1 = 0;
u32 offset = 0; u32 offset = 0;
BUG_ON(params == NULL); if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) {
retval = -ENODEV;
goto exit;
}
if (WARN_ON(params == NULL)) {
retval = -EINVAL;
goto exit;
}
if (WARN_ON(params->notify_driver == NULL || if (WARN_ON(params->notify_driver == NULL ||
params->shared_addr == NULL || params->shared_addr == NULL ||
params->shared_addr_size == 0)) { params->shared_addr_size == 0)) {
...@@ -495,7 +602,7 @@ void *nameserver_remotenotify_create(u16 proc_id, ...@@ -495,7 +602,7 @@ void *nameserver_remotenotify_create(u16 proc_id,
sem_alloc_error: sem_alloc_error:
nameserver_unregister_remote_driver(proc_id); nameserver_unregister_remote_driver(proc_id);
/* Do we want to check the staus ? */ /* Do we want to check the staus ? */
retval = notify_unregister_event(obj->params.notify_driver, retval1 = notify_unregister_event(obj->params.notify_driver,
obj->remote_proc_id, obj->remote_proc_id,
obj->params.notify_event_no, obj->params.notify_event_no,
nameserver_remotenotify_callback, nameserver_remotenotify_callback,
...@@ -509,6 +616,8 @@ mem_error: ...@@ -509,6 +616,8 @@ mem_error:
kfree(handle); kfree(handle);
exit: exit:
printk(KERN_ERR "nameserver_remotenotify_create failed! "
"status = 0x%x\n", retval);
return NULL; return NULL;
} }
...@@ -525,14 +634,24 @@ int nameserver_remotenotify_delete(void **rhandle) ...@@ -525,14 +634,24 @@ int nameserver_remotenotify_delete(void **rhandle)
s32 retval = 0; s32 retval = 0;
struct mutex *gate = NULL; struct mutex *gate = NULL;
BUG_ON(rhandle == NULL); if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count),
if (WARN_ON(*rhandle == NULL)) { NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0),
NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) {
retval = -ENODEV;
goto exit;
}
if (WARN_ON((rhandle == NULL) || (*rhandle == NULL))) {
retval = -EINVAL; retval = -EINVAL;
goto exit; goto exit;
} }
handle = (struct nameserver_remotenotify_object *)(*rhandle); handle = (struct nameserver_remotenotify_object *)(*rhandle);
obj = (struct nameserver_remotenotify_obj *)handle->obj; obj = (struct nameserver_remotenotify_obj *)handle->obj;
if (obj == NULL) {
retval = -EINVAL;
goto exit;
}
retval = mutex_lock_interruptible(obj->local_gate); retval = mutex_lock_interruptible(obj->local_gate);
if (retval) if (retval)
...@@ -540,7 +659,7 @@ int nameserver_remotenotify_delete(void **rhandle) ...@@ -540,7 +659,7 @@ int nameserver_remotenotify_delete(void **rhandle)
retval = nameserver_unregister_remote_driver(obj->remote_proc_id); retval = nameserver_unregister_remote_driver(obj->remote_proc_id);
/* Do we have to bug_on/warn_on oops here intead of exit ?*/ /* Do we have to bug_on/warn_on oops here intead of exit ?*/
if (retval) if (retval < 0)
goto exit; goto exit;
kfree(obj->sem_handle); kfree(obj->sem_handle);
...@@ -561,6 +680,10 @@ int nameserver_remotenotify_delete(void **rhandle) ...@@ -561,6 +680,10 @@ int nameserver_remotenotify_delete(void **rhandle)
kfree(gate); kfree(gate);
exit: exit:
if (retval < 0) {
printk(KERN_ERR "nameserver_remotenotify_delete failed! "
"status = 0x%x\n", retval);
}
return retval; return retval;
} }
......
...@@ -115,6 +115,7 @@ int platform_mem_destroy(void) ...@@ -115,6 +115,7 @@ int platform_mem_destroy(void)
if (atomic_dec_return(&platform_mem_state.ref_count) if (atomic_dec_return(&platform_mem_state.ref_count)
== PLATFORM_MEM_MAKE_MAGICSTAMP(0)) { == PLATFORM_MEM_MAKE_MAGICSTAMP(0)) {
list_del(&platform_mem_state.map_table);
/* Delete the gate handle */ /* Delete the gate handle */
kfree(&platform_mem_state.gate); kfree(&platform_mem_state.gate);
} }
...@@ -230,6 +231,7 @@ int platform_mem_unmap(memory_unmap_info *unmap_info) ...@@ -230,6 +231,7 @@ int platform_mem_unmap(memory_unmap_info *unmap_info)
list_for_each_entry(info, &platform_mem_state.map_table, mem_entry) { list_for_each_entry(info, &platform_mem_state.map_table, mem_entry) {
if (info->knl_virtual_address == unmap_info->addr) { if (info->knl_virtual_address == unmap_info->addr) {
list_del(&info->mem_entry); list_del(&info->mem_entry);
kfree(info);
break; break;
} }
......
...@@ -243,6 +243,7 @@ int sharedregion_add(u32 index, void *base, u32 len) ...@@ -243,6 +243,7 @@ int sharedregion_add(u32 index, void *base, u32 len)
table = sharedregion_state.table; table = sharedregion_state.table;
/* Check for overlap */
for (i = 0; i < sharedregion_state.cfg.max_regions; i++) { for (i = 0; i < sharedregion_state.cfg.max_regions; i++) {
entry = (table entry = (table
+ (myproc_id * sharedregion_state.cfg.max_regions) + (myproc_id * sharedregion_state.cfg.max_regions)
...@@ -317,6 +318,7 @@ int sharedregion_remove(u32 index) ...@@ -317,6 +318,7 @@ int sharedregion_remove(u32 index)
{ {
struct sharedregion_info *entry = NULL; struct sharedregion_info *entry = NULL;
struct sharedregion_info *table = NULL; struct sharedregion_info *table = NULL;
u16 myproc_id;
s32 retval = 0; s32 retval = 0;
if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count),
...@@ -335,8 +337,11 @@ int sharedregion_remove(u32 index) ...@@ -335,8 +337,11 @@ int sharedregion_remove(u32 index)
if (retval) if (retval)
goto error; goto error;
myproc_id = multiproc_get_id(NULL);
table = sharedregion_state.table; table = sharedregion_state.table;
entry = (table + index); entry = (table
+ (myproc_id * sharedregion_state.cfg.max_regions)
+ index);
entry->is_valid = false; entry->is_valid = false;
entry->base = NULL; entry->base = NULL;
entry->len = 0; entry->len = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment