Commit ba40b8ae 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 08a74abb
......@@ -46,7 +46,7 @@
* @def MESSAGEQ_STATUSCODEBASE
* @brief Error code base for MessageQ.
*/
#define MESSAGEQ_STATUSCODEBASE (MESSAGEQ_MODULEID << 12)
#define MESSAGEQ_STATUSCODEBASE (MESSAGEQ_MODULEID << 12)
/*!
* @def MESSAGEQ_MAKE_FAILURE
......@@ -78,13 +78,13 @@
* @def MESSAGEQ_E_BUSY
* @brief the name is already registered or not.
*/
#define MESSAGEQ_E_BUSY MESSAGEQ_MAKE_FAILURE(3)
#define MESSAGEQ_E_BUSY MESSAGEQ_MAKE_FAILURE(3)
/*!
* @def MESSAGEQ_E_FAIL
* @brief Generic failure.
*/
#define MESSAGEQ_E_FAIL MESSAGEQ_MAKE_FAILURE(4)
#define MESSAGEQ_E_FAIL MESSAGEQ_MAKE_FAILURE(4)
/*!
* @def MESSAGEQ_E_NOTFOUND
......@@ -96,7 +96,7 @@
* @def MESSAGEQ_E_INVALIDSTATE
* @brief Module is not initialized.
*/
#define MESSAGEQ_E_INVALIDSTATE MESSAGEQ_MAKE_FAILURE(6)
#define MESSAGEQ_E_INVALIDSTATE MESSAGEQ_MAKE_FAILURE(6)
/*!
* @def MESSAGEQ_E_NOTONWER
......@@ -108,7 +108,7 @@
* @def MESSAGEQ_E_REMOTEACTIVE
* @brief Remote opener of the instance has not closed the instance.
*/
#define MESSAGEQ_E_REMOTEACTIVE MESSAGEQ_MAKE_FAILURE(8)
#define MESSAGEQ_E_REMOTEACTIVE MESSAGEQ_MAKE_FAILURE(8)
/*!
* @def MESSAGEQ_E_INUSE
......@@ -145,7 +145,7 @@
* @def MESSAGEQ_E_MAXREACHED
* @brief Indicates that all message queues are taken
*/
#define MESSAGEQ_E_MAXREACHED MESSAGEQ_MAKE_FAILURE(14)
#define MESSAGEQ_E_MAXREACHED MESSAGEQ_MAKE_FAILURE(14)
/*!
* @def MESSAGEQ_E_UNREGISTERHEAPID
......@@ -157,7 +157,7 @@
* @def MESSAGEQ_E_CANNOTFREESTATICMSG
* @brief Indicates that static msg cannot be freed
*/
#define MESSAGEQ_E_CANNOTFREESTATICMSG MESSAGEQ_MAKE_FAILURE(16)
#define MESSAGEQ_E_CANNOTFREESTATICMSG MESSAGEQ_MAKE_FAILURE(16)
/*!
* @def MESSAGEQ_E_HEAPIDINVALID
......@@ -187,7 +187,7 @@
* @def MESSAGEQ_E_TIMEOUT
* @brief Timeout while attempting to get a message
*/
#define MESSAGEQ_E_TIMEOUT MESSAGEQ_MAKE_FAILURE(21)
#define MESSAGEQ_E_TIMEOUT MESSAGEQ_MAKE_FAILURE(21)
/*!
* @def MESSAGEQ_SUCCESS
......@@ -199,7 +199,7 @@
* @def MESSAGEQ_S_ALREADYSETUP
* @brief The MESSAGEQ module has already been setup in this process.
*/
#define MESSAGEQ_S_ALREADYSETUP MESSAGEQ_MAKE_SUCCESS(1)
#define MESSAGEQ_S_ALREADYSETUP MESSAGEQ_MAKE_SUCCESS(1)
/* =============================================================================
......@@ -209,17 +209,17 @@
/*!
* @brief Mask to extract version setting
*/
#define MESSAGEQ_HEADERVERSION 0x2000u
#define MESSAGEQ_HEADERVERSION 0x2000u
/*!
* @brief Mask to extract priority setting
*/
#define MESSAGEQ_PRIORITYMASK 0x3u
#define MESSAGEQ_PRIORITYMASK 0x3u
/*!
* @brief Mask to extract priority setting
*/
#define MESSAGEQ_TRANSPORTPRIORITYMASK 0x01u
#define MESSAGEQ_TRANSPORTPRIORITYMASK 0x01u
/*!
* Mask to extract version setting
......@@ -245,7 +245,13 @@
* Indicates that if maximum number of message queues are already created,
* should allow growth to create additional Message Queue.
*/
#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
......@@ -455,5 +461,4 @@ int messageq_register_transport(void *messageq_transportshm_handle,
int messageq_unregister_transport(u16 proc_id, u32 priority);
#endif /* _MESSAGEQ_H_ */
......@@ -387,18 +387,18 @@ int gatepeterson_delete(void **gphandle)
handle = (struct gatepeterson_object *)(*gphandle);
obj = (struct gatepeterson_obj *)handle->obj;
if (obj == NULL) {
if (unlikely(obj == NULL)) {
retval = -EINVAL;
goto exit;
}
if (obj->attrs == NULL) {
if (unlikely(obj->attrs == NULL)) {
retval = -EINVAL;
goto exit;
}
/* 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;
goto exit;
}
......@@ -438,6 +438,7 @@ int gatepeterson_delete(void **gphandle)
obj->local_gate = NULL; /* TBD: Fixme */
break;
case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */
/* FIXME: Add a spinlock protection */
case GATEPETERSON_PROTECT_TASKLET: /* Fall through */
case GATEPETERSON_PROTECT_THREAD: /* Fall through */
case GATEPETERSON_PROTECT_PROCESS:
......@@ -620,6 +621,11 @@ int gatepeterson_close(void **gphandle)
handle = (struct gatepeterson_object *)(*gphandle);
obj = (struct gatepeterson_obj *) handle->obj;
if (unlikely(obj == NULL)) {
retval = -EINVAL;
goto exit;
}
retval = mutex_lock_interruptible(obj->local_gate);
if (retval)
goto exit;
......@@ -647,13 +653,14 @@ int gatepeterson_close(void **gphandle)
obj->local_gate = NULL; /* TBD: Fixme */
break;
case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */
/* FIXME: Add a spinlock protection */
case GATEPETERSON_PROTECT_TASKLET: /* Fall through */
case GATEPETERSON_PROTECT_THREAD: /* Fall through */
case GATEPETERSON_PROTECT_PROCESS:
kfree(obj->local_gate);
break;
default:
/* An invalid protection level was supplied, FIXME */
/* An invalid protection level was supplied */
break;
}
......@@ -874,6 +881,9 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params,
obj->nested = 0;
obj->top = handle;
/* Populate the params member */
memcpy(&obj->params, params, sizeof(struct gatepeterson_params));
/* Create the local lock if not provided */
if (likely(params->local_protection == GATEPETERSON_PROTECT_DEFAULT))
obj->params.local_protection =
......@@ -890,10 +900,11 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params,
* protection here also
*/
case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */
/* FIXME: Add a spinlock protection */
case GATEPETERSON_PROTECT_TASKLET: /* Fall through */
case GATEPETERSON_PROTECT_THREAD: /* Fall through */
case GATEPETERSON_PROTECT_PROCESS:
obj->local_gate = kmalloc(sizeof(struct mutex), GFP_KERNEL);
obj->local_gate = kmalloc(sizeof(struct mutex), GFP_KERNEL);
if (obj->local_gate == NULL) {
retval = -ENOMEM;
goto gate_create_fail;
......@@ -907,8 +918,6 @@ static void *_gatepeterson_create(const struct gatepeterson_params *params,
break;
}
/* Populate the params member */
memcpy(&obj->params, params, sizeof(struct gatepeterson_params));
/* Put in the local list */
retval = mutex_lock_interruptible(gatepeterson_state.mod_lock);
if (retval)
......@@ -944,6 +953,4 @@ exit:
retval);
return NULL;
}
......@@ -209,8 +209,12 @@ static int gatepeterson_ioctl_open(struct gatepeterson_cmd_args *cargs)
}
}
params.shared_addr = sharedregion_get_ptr(
(u32 *)cargs->args.create.shared_addr_srptr);
/* 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(
(u32 *)cargs->args.open.shared_addr_srptr);
}
cargs->api_status = gatepeterson_open(&handle, &params);
cargs->args.open.handle = handle;
......
......@@ -343,8 +343,8 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params,
s32 retval = 0;
u32 i;
s32 align;
s32 shmindex;
u32 shared_shmbase;
s32 shm_index;
u32 shared_shm_base;
void *entry = NULL;
if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count),
......@@ -379,6 +379,7 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params,
handle->alloc = &heapbuf_alloc;
handle->free = &heapbuf_free;
handle->get_stats = &heapbuf_get_stats;
/* FIXME: handle->is_blocking = &heapbuf_isblocking; */
/* Create the shared list */
listmp_sharedmemory_params_init(NULL, &listmp_params);
listmp_params.shared_addr = (u32 *)((u32) (params->shared_addr)
......@@ -464,13 +465,13 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params,
if ((likely(heapbuf_state.cfg.use_nameserver == true))
&& (create_flag == true)) {
/* We will store a shared pointer in the nameserver */
shmindex = sharedregion_get_index(params->shared_addr);
shared_shmbase = (u32)sharedregion_get_srptr(
params->shared_addr, shmindex);
shm_index = sharedregion_get_index(params->shared_addr);
shared_shm_base = (u32)sharedregion_get_srptr(
params->shared_addr, shm_index);
if (obj->params.name != NULL) {
entry = nameserver_add_uint32(heapbuf_state.ns_handle,
params->name,
(u32)(shared_shmbase));
(u32)(shared_shm_base));
if (entry == NULL) {
retval = -EFAULT;
goto ns_add_error;
......@@ -595,8 +596,10 @@ int heapbuf_delete(void **handle_ptr)
}
obj = (struct heapbuf_obj *)handle->obj;
if (obj == NULL)
if (obj == NULL) {
retval = -EINVAL;
goto error;
}
myproc_id = multiproc_get_id(NULL);
......
......@@ -192,12 +192,15 @@ static int heapbuf_ioctl_open(struct heapbuf_cmd_args *cargs)
}
}
params.shared_addr = sharedregion_get_ptr((u32 *)
cargs->args.open.shared_addr_srptr);
/* For open by name, the shared_add_srptr may be invalid */
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;
cargs->api_status = heapbuf_open(&handle, &params);
if (cargs->api_status != 0)
if (cargs->api_status < 0)
goto free_name;
cargs->args.open.handle = handle;
......
......@@ -1309,8 +1309,8 @@ listmp_sharedmemory_handle _listmp_sharedmemory_create(
listmp_sharedmemory_object *handle = NULL;
struct listmp_sharedmemory_obj *obj = NULL;
u32 key;
u32 shmIndex;
u32 *sharedShmBase;
u32 shm_index;
u32 *shared_shm_base;
BUG_ON(params == NULL);
......@@ -1419,15 +1419,15 @@ listmp_sharedmemory_handle _listmp_sharedmemory_create(
/* We will store a shared pointer in the
* NameServer
*/
shmIndex = sharedregion_get_index(params->shared_addr);
sharedShmBase = sharedregion_get_srptr(
params->shared_addr, shmIndex);
shm_index = sharedregion_get_index(params->shared_addr);
shared_shm_base = sharedregion_get_srptr(
params->shared_addr, shm_index);
/* Add list instance to name server */
if (obj->params.name != NULL) {
obj->ns_key = nameserver_add_uint32(
listmp_sharedmemory_state.ns_handle,
params->name,
(u32) (params->shared_addr));
(u32) (shared_shm_base));
if (obj->ns_key == NULL)
status = -EFAULT;
}
......
......@@ -248,15 +248,19 @@ static inline int listmp_sharedmemory_ioctl_open(
}
}
params.shared_addr = sharedregion_get_ptr(
/* 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(
(u32 *)cargs->args.open.shared_addr_srptr);
}
if (unlikely(params.shared_addr == NULL))
goto free_name;
/* Update gate in params. */
params.gate = cargs->args.open.knl_gate;
status = listmp_sharedmemory_open(&listmp_handle, &params);
if (status)
if (status < 0)
goto free_name;
cargs->args.open.listmp_handle = listmp_handle;
......
......@@ -115,7 +115,7 @@
#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))
/* =============================================================================
......@@ -127,11 +127,6 @@
*/
#define MESSAGEQ_NAMESERVER "MessageQ"
/*!
* @brief Number of types of priority queues for each transport
*/
#define MESSAGEQ_NUM_PRIORITY_QUEUES 2
/* =============================================================================
* Structures & Enums
......@@ -152,7 +147,7 @@ struct messageq_module_object {
struct messageq_params default_inst_params;
/*!< Default instance creation parameters */
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;*/
/*!< Grow option */
void **heaps; /*Heap_Handle *heaps; */
......@@ -847,6 +842,7 @@ int messageq_get(void *messageq_handle, messageq_msg *msg,
mutex_unlock(messageq_state.gate_handle);
}
}
return status;
exit:
if (status < 0)
......
......@@ -70,6 +70,9 @@ struct messageq_transportshm_moduleobject {
/*< Default instance parameters */
void *gate_handle;
/*< 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)
messageq_transportshm_state.gate_handle = \
kmalloc(sizeof(struct mutex), GFP_KERNEL);
mutex_init(messageq_transportshm_state.gate_handle);
if (messageq_transportshm_state.gate_handle == NULL) {
/* @retval MESSAGEQTRANSPORTSHM_E_FAIL Failed to create
GateMutex! */
......@@ -232,10 +234,13 @@ int messageq_transportshm_setup(const struct messageq_transportshm_config *cfg)
MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0));
goto exit;
}
mutex_init(messageq_transportshm_state.gate_handle);
/* Copy the user provided values into the state object. */
memcpy(&messageq_transportshm_state.cfg, cfg,
sizeof(struct messageq_transportshm_config));
memset(&(messageq_transportshm_state.transports), 0, (sizeof(void *) * \
MULTIPROC_MAXPROCESSORS * MESSAGEQ_NUM_PRIORITY_QUEUES));
return status;
exit:
......@@ -257,6 +262,8 @@ exit:
int messageq_transportshm_destroy(void)
{
int status = 0;
u16 i;
u16 j;
if (WARN_ON(atomic_cmpmask_and_lt(
&(messageq_transportshm_state.ref_count),
......@@ -266,21 +273,41 @@ int messageq_transportshm_destroy(void)
goto exit;
}
if (atomic_dec_return(&messageq_transportshm_state.ref_count)
== MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0)) {
if (messageq_transportshm_state.gate_handle != NULL) {
kfree(messageq_transportshm_state.gate_handle);
messageq_transportshm_state.gate_handle = NULL;
if (!(atomic_dec_return(&messageq_transportshm_state.ref_count)
== 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]));
}
}
/* Decrease the ref_count */
atomic_set(&messageq_transportshm_state.ref_count,
MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0));
}
if (messageq_transportshm_state.gate_handle != NULL) {
kfree(messageq_transportshm_state.gate_handle);
messageq_transportshm_state.gate_handle = NULL;
}
/* Decrease the ref_count */
atomic_set(&messageq_transportshm_state.ref_count,
MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0));
return 0;
exit:
printk(KERN_ERR "messageq_transportshm_destroy failed: status = 0x%x\n",
status);
if (status < 0) {
printk(KERN_ERR "messageq_transportshm_destroy failed: "
"status = 0x%x\n", status);
}
return status;
}
......@@ -360,6 +387,12 @@ void *messageq_transportshm_create(u16 proc_id,
status = -EINVAL;
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
......@@ -459,8 +492,11 @@ void *messageq_transportshm_create(u16 proc_id,
/* Register the transport with MessageQ */
status = messageq_register_transport((void *)handle, proc_id,
(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;
}
return handle;
listmp_open_fail:
......@@ -468,10 +504,8 @@ listmp_open_fail:
"listmp_sharedmemory_open failed!\n");
notify_register_fail:
if (status < 0) {
if (handle != NULL) {
kfree(handle);
handle = NULL;
}
if (handle != NULL)
messageq_transportshm_delete((void **)(&handle));
}
exit:
......@@ -513,6 +547,9 @@ int messageq_transportshm_delete(void **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;
status = listmp_sharedmemory_delete(
(listmp_sharedmemory_handle *)&obj->my_listmp_handle);
......
......@@ -16,12 +16,19 @@
* PURPOSE.
*/
/* Standard headers */
#include <linux/types.h>
/* Utilities headers */
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/semaphore.h>
/* Syslink headers */
#include <syslink/atomic_linux.h>
/* Module level headers */
#include <gate_remote.h>
#include <gatepeterson.h>
#include <nameserver.h>
......@@ -29,11 +36,24 @@
#include <nameserver_remotenotify.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
* 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
* module specific information
......@@ -44,6 +64,7 @@ struct nameserver_remotenotify_module_object {
struct nameserver_remotenotify_params def_inst_params;
bool is_setup;
void *gate_handle;
atomic_t ref_count;
};
/*
......@@ -55,8 +76,6 @@ struct nameserver_remotenotify_attrs {
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
*/
......@@ -68,7 +87,7 @@ struct nameserver_remotenotify_message {
u32 value_len;
char instance_name[32];
char name[32];
char value_buf[MAX_VALUE_LEN];
char value_buf[NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN];
};
/*
......@@ -157,6 +176,17 @@ int nameserver_remotenotify_setup(
struct mutex *lock = NULL;
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) {
nameserver_remotenotify_get_config(&tmp_cfg);
cfg = &tmp_cfg;
......@@ -192,12 +222,30 @@ exit:
*/
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)
kfree(nameserver_remotenotify_state.gate_handle);
nameserver_remotenotify_state.is_setup = false;
return 0;
exit:
return retval;
}
/*
......@@ -211,7 +259,21 @@ void nameserver_remotenotify_params_init(void *handle,
struct nameserver_remotenotify_object *object = 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;
if (handle == NULL)
memcpy(params,
......@@ -240,45 +302,59 @@ void nameserver_remotenotify_callback(u16 proc_id, u32 event_no,
u32 proc_count;
u16 offset = 0;
void *nshandle = NULL;
char value[MAX_VALUE_LEN] = { 0 }; /* To take care of value len > 4,
do we need to make it global? */
u32 value_len;
u32 key;
s32 retval = 0;
s32 count = -ENOENT;
if (WARN_ON(arg == NULL))
return;
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(arg == NULL)) {
retval = -EINVAL;
goto exit;
}
proc_count = multiproc_get_max_processors();
if (WARN_ON(proc_id >= proc_count))
return;
if (WARN_ON(proc_id >= proc_count)) {
retval = -EINVAL;
goto exit;
}
handle = (struct nameserver_remotenotify_obj *)arg;
if ((multiproc_get_id(NULL) > proc_id))
offset = 1;
if (handle->msg[1 - offset]->request != true)
goto exit;
goto signal_response;
/* This is a request */
value_len = handle->msg[1 - offset]->value_len;
nshandle = nameserver_get_handle(
handle->msg[1 - offset]->instance_name);
if (nshandle != NULL)
if (nshandle != NULL) {
/* Search for the NameServer entry */
retval = nameserver_get_local(nshandle,
handle->msg[1 - offset]->name, &value,
handle->msg[1 - offset]->value_len);
if (value_len == sizeof(u32)) {
count = nameserver_get_local(nshandle,
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);
/* If retval > 0 then an entry found */
if (retval > 0) {
if (count != -ENOENT)
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 */
handle->msg[1 - offset]->response = true;
......@@ -293,9 +369,14 @@ void nameserver_remotenotify_callback(u16 proc_id, u32 event_no,
retval = notify_sendevent(handle->params.notify_driver,
proc_id, event_no, 0, true);
exit:
signal_response:
if (handle->msg[offset]->response == true)
up(handle->sem_handle);
exit:
if (retval < 0) {
printk(KERN_ERR "nameserver_remotenotify_callback failed! "
"status = 0x%x\n", retval);
}
return;
}
......@@ -318,13 +399,23 @@ int nameserver_remotenotify_get(void *rhandle,
BUG_ON(instance_name == NULL);
BUG_ON(name == 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)) {
retval = -EINVAL;
goto exit;
}
if (value_len == 0) {
if ((value_len == 0) || \
(value_len > NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN)) {
retval = -EINVAL;
goto exit;
}
......@@ -351,8 +442,12 @@ int nameserver_remotenotify_get(void *rhandle,
obj->params.notify_event_no,
0, /* 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;
}
gatepeterson_leave(obj->params.gate, key);
......@@ -423,9 +518,21 @@ void *nameserver_remotenotify_create(u16 proc_id,
struct nameserver_remotenotify_obj *obj = NULL;
u16 proc_count;
s32 retval = 0;
s32 retval1 = 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 ||
params->shared_addr == NULL ||
params->shared_addr_size == 0)) {
......@@ -495,7 +602,7 @@ void *nameserver_remotenotify_create(u16 proc_id,
sem_alloc_error:
nameserver_unregister_remote_driver(proc_id);
/* 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->params.notify_event_no,
nameserver_remotenotify_callback,
......@@ -509,6 +616,8 @@ mem_error:
kfree(handle);
exit:
printk(KERN_ERR "nameserver_remotenotify_create failed! "
"status = 0x%x\n", retval);
return NULL;
}
......@@ -525,14 +634,24 @@ int nameserver_remotenotify_delete(void **rhandle)
s32 retval = 0;
struct mutex *gate = NULL;
BUG_ON(rhandle == NULL);
if (WARN_ON(*rhandle == 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((rhandle == NULL) || (*rhandle == NULL))) {
retval = -EINVAL;
goto exit;
}
handle = (struct nameserver_remotenotify_object *)(*rhandle);
obj = (struct nameserver_remotenotify_obj *)handle->obj;
if (obj == NULL) {
retval = -EINVAL;
goto exit;
}
retval = mutex_lock_interruptible(obj->local_gate);
if (retval)
......@@ -540,7 +659,7 @@ int nameserver_remotenotify_delete(void **rhandle)
retval = nameserver_unregister_remote_driver(obj->remote_proc_id);
/* Do we have to bug_on/warn_on oops here intead of exit ?*/
if (retval)
if (retval < 0)
goto exit;
kfree(obj->sem_handle);
......@@ -561,6 +680,10 @@ int nameserver_remotenotify_delete(void **rhandle)
kfree(gate);
exit:
if (retval < 0) {
printk(KERN_ERR "nameserver_remotenotify_delete failed! "
"status = 0x%x\n", retval);
}
return retval;
}
......
......@@ -115,6 +115,7 @@ int platform_mem_destroy(void)
if (atomic_dec_return(&platform_mem_state.ref_count)
== PLATFORM_MEM_MAKE_MAGICSTAMP(0)) {
list_del(&platform_mem_state.map_table);
/* Delete the gate handle */
kfree(&platform_mem_state.gate);
}
......@@ -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) {
if (info->knl_virtual_address == unmap_info->addr) {
list_del(&info->mem_entry);
kfree(info);
break;
}
......
......@@ -243,6 +243,7 @@ int sharedregion_add(u32 index, void *base, u32 len)
table = sharedregion_state.table;
/* Check for overlap */
for (i = 0; i < sharedregion_state.cfg.max_regions; i++) {
entry = (table
+ (myproc_id * sharedregion_state.cfg.max_regions)
......@@ -317,6 +318,7 @@ int sharedregion_remove(u32 index)
{
struct sharedregion_info *entry = NULL;
struct sharedregion_info *table = NULL;
u16 myproc_id;
s32 retval = 0;
if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count),
......@@ -335,8 +337,11 @@ int sharedregion_remove(u32 index)
if (retval)
goto error;
myproc_id = multiproc_get_id(NULL);
table = sharedregion_state.table;
entry = (table + index);
entry = (table
+ (myproc_id * sharedregion_state.cfg.max_regions)
+ index);
entry->is_valid = false;
entry->base = NULL;
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