Commit 42581ff9 authored by Suman Anna's avatar Suman Anna Committed by Hari Kanigeri

SYSLINK: ipc - fix heapbuf issues in open, create & delete

This patch fixes multiple issues found in the heapbuf
module code based on IPC50. The patch also includes a fix for
a minor compile warning in gatepeterson. This patch includes
the following changes.
	1. heapbuf_ioctl.h - Matched the ioctl args for open
		and create arguments. Also includes some minor
		formatting style changes.
	2. heapbuf_ioctl.c - Retrieved the correct shared
		region address pointers and gate handle from
		the user-side. Memory allocated for heapbuf name
		in heapbuf_ioctl_create and heapbuf_ioctl_open
		is adjusted as the length is already incremented
		in the user-side.
	3. heapbuf.c - gatepeterson gate is used properly
		for the gate used in internal object. The memory
		for the heapbuf object name is freed after it is
		removed from the nameserver module. This fixed
		the issue with heapbuf_delete failure. volatile
		has been used using a macro to reduce the checkpatch
		warnings.
Signed-off-by: default avatarSuman Anna <s-anna@ti.com>
parent 2aee6ac5
......@@ -146,6 +146,9 @@ union heapbuf_arg {
void *handle;
struct heapbuf_params *params;
u32 name_len;
u32 *shared_addr_srptr;
u32 *shared_buf_srptr;
void *knl_gate;
} create;
struct {
......@@ -156,6 +159,8 @@ union heapbuf_arg {
void *handle;
struct heapbuf_params *params;
u32 name_len;
u32 *shared_addr_srptr;
void *knl_gate;
} open;
struct {
......@@ -208,4 +213,3 @@ int heapbuf_ioctl(struct inode *pinode, struct file *filp,
unsigned int cmd, unsigned long args);
#endif /* _HEAPBUF_IOCTL_ */
......@@ -567,7 +567,7 @@ int gatepeterson_open(void **gphandle,
goto noentry_fail;
}
} else
sharedaddr = params->shared_addr;
sharedaddr = (u32) params->shared_addr;
if (unlikely(((struct gatepeterson_attrs *)sharedaddr)->status !=
GATEPETERSON_CREATED)) {
......
......@@ -28,6 +28,7 @@
#include <multiproc.h>
#include <nameserver.h>
#include <sharedregion.h>
#include <gatepeterson.h>
#include <heapbuf.h>
#include <listmp.h>
#include <listmp_sharedmemory.h>
......@@ -41,19 +42,21 @@
/* brief Macro to make a correct module magic number with refCount */
#define HEAPBUF_MAKE_MAGICSTAMP(x) ((HEAPBUF_MODULEID << 12) | (x))
#define VOLATILE volatile
/*
* Structure defining attribute parameters for the heapbuf module
*/
struct heapbuf_attrs {
volatile u32 version;
volatile u32 status;
volatile u32 num_free_blocks;
volatile u32 min_free_blocks;
volatile u32 block_size;
volatile u32 align;
volatile u32 num_blocks;
volatile u32 buf_size;
volatile char *buf;
VOLATILE u32 version;
VOLATILE u32 status;
VOLATILE u32 num_free_blocks;
VOLATILE u32 min_free_blocks;
VOLATILE u32 block_size;
VOLATILE u32 align;
VOLATILE u32 num_blocks;
VOLATILE u32 buf_size;
VOLATILE char *buf;
};
/*
......@@ -316,6 +319,7 @@ void heapbuf_params_init(void *handle,
memcpy(params, (void *)&obj->params,
sizeof(struct heapbuf_params));
}
return;
error:
printk(KERN_ERR "heapbuf_params_init failed status: %x\n", retval);
}
......@@ -435,7 +439,6 @@ int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params,
retval = -ENOMEM;
goto name_alloc_error;
}
strncpy(obj->params.name, params->name,
strlen(params->name) + 1);
}
......@@ -573,6 +576,7 @@ EXPORT_SYMBOL(heapbuf_create);
*/
int heapbuf_delete(void **handle_ptr)
{
int status = 0;
struct heap_object *handle = NULL;
struct heapbuf_obj *obj = NULL;
struct heapbuf_params *params = NULL;
......@@ -605,10 +609,12 @@ int heapbuf_delete(void **handle_ptr)
}
if (likely(obj->gate != NULL)) {
retval = mutex_lock_interruptible(obj->gate);
if (retval)
status = gatepeterson_enter(obj->gate);
if (status < 0) {
retval = -EINVAL;
goto gate_error;
}
}
if (obj->owner.open_count > 1) {
retval = -EBUSY;
......@@ -628,7 +634,6 @@ int heapbuf_delete(void **handle_ptr)
mutex_unlock(heapbuf_state.local_lock);
params = (struct heapbuf_params *) &obj->params;
if (likely(params->name != NULL)) {
kfree(params->name);
if (likely(heapbuf_state.cfg.use_nameserver == true)) {
retval = nameserver_remove(heapbuf_state.ns_handle,
params->name);
......@@ -636,10 +641,11 @@ int heapbuf_delete(void **handle_ptr)
goto ns_remove_error;
obj->ns_key = NULL;
}
kfree(params->name);
}
if (likely(obj->gate != NULL))
mutex_unlock(obj->gate);
gatepeterson_leave(obj->gate, 0);
retval = listmp_sharedmemory_delete(&obj->free_list);
kfree(obj);
kfree(handle);
......@@ -651,7 +657,7 @@ gate_error: /* Fall through */
local_lock_error: /* Fall through */
device_busy_error:
if (likely(obj->gate != NULL))
mutex_unlock(obj->gate);
gatepeterson_leave(obj->gate, 0);
error:
printk(KERN_ERR "heapbuf_delete failed status: %x\n", retval);
......@@ -772,6 +778,7 @@ EXPORT_SYMBOL(heapbuf_open);
*/
int heapbuf_close(void *handle_ptr)
{
int status = 0;
struct heap_object *handle = NULL;
struct heapbuf_obj *obj = NULL;
struct heapbuf_params *params = NULL;
......@@ -812,10 +819,12 @@ int heapbuf_close(void *handle_ptr)
/* Take the local lock */
if (likely(obj->gate != NULL)) {
retval = mutex_lock_interruptible(obj->gate);
if (retval)
status = gatepeterson_enter(obj->gate);
if (status < 0) {
retval = -EINVAL;
goto error;
}
}
params = (struct heapbuf_params *)&obj->params;
if (likely((params->name) != NULL))
......@@ -823,7 +832,7 @@ int heapbuf_close(void *handle_ptr)
/* Release the local lock */
if (likely(obj->gate != NULL))
mutex_unlock(obj->gate);
gatepeterson_leave(obj->gate, 0);
/* Delete the list */
listmp_sharedmemory_close((listmp_sharedmemory_handle *)
......@@ -848,6 +857,7 @@ EXPORT_SYMBOL(heapbuf_close);
*/
void *heapbuf_alloc(void *hphandle, u32 size, u32 align)
{
int status = 0;
struct heap_object *handle = NULL;
struct heapbuf_obj *obj = NULL;
char *block = NULL;
......@@ -878,10 +888,12 @@ void *heapbuf_alloc(void *hphandle, u32 size, u32 align)
goto error;
if (likely(obj->gate != NULL)) {
retval = mutex_lock_interruptible(obj->gate);
if (retval)
status = gatepeterson_enter(obj->gate);
if (status < 0) {
retval = -EINVAL;
goto error;
}
}
block = listmp_get_head((void *)obj->free_list);
if (block == NULL) {
......@@ -906,7 +918,7 @@ void *heapbuf_alloc(void *hphandle, u32 size, u32 align)
}
if (likely(obj->gate != NULL))
mutex_unlock(obj->gate);
gatepeterson_leave(obj->gate, 0);
return block;
error:
printk(KERN_ERR "heapbuf_alloc failed status: %x\n", retval);
......@@ -921,6 +933,7 @@ EXPORT_SYMBOL(heapbuf_alloc);
*/
int heapbuf_free(void *hphandle, void *block, u32 size)
{
int status = 0;
struct heap_object *handle = NULL;
struct heapbuf_obj *obj = NULL;
s32 retval = 0;
......@@ -945,14 +958,17 @@ int heapbuf_free(void *hphandle, void *block, u32 size)
handle = (struct heap_object *)(hphandle);
obj = (struct heapbuf_obj *)handle->obj;
if (likely(obj->gate != NULL)) {
retval = mutex_lock_interruptible(obj->gate);
if (retval)
status = gatepeterson_enter(obj->gate);
if (status < 0) {
retval = -EINVAL;
goto error;
}
}
retval = listmp_put_tail((void *)obj->free_list, block);
obj->attrs->num_free_blocks++;
if (likely(obj->gate != NULL))
mutex_unlock(obj->gate);
gatepeterson_leave(obj->gate, 0);
return 0;
error:
......@@ -968,6 +984,7 @@ EXPORT_SYMBOL(heapbuf_free);
*/
int heapbuf_get_stats(void *hphandle, struct memory_stats *stats)
{
int status = 0;
struct heap_object *object = NULL;
struct heapbuf_obj *obj = NULL;
u32 block_size;
......@@ -991,10 +1008,12 @@ int heapbuf_get_stats(void *hphandle, struct memory_stats *stats)
obj = (struct heapbuf_obj *)object->obj;
if (likely(obj->gate != NULL)) {
retval = mutex_lock_interruptible(obj->gate);
if (retval)
status = gatepeterson_enter(obj->gate);
if (status < 0) {
retval = -EINVAL;
goto error;
}
}
block_size = obj->attrs->block_size;
stats->total_size = (u32 *)(block_size * obj->attrs->num_blocks);
......@@ -1006,7 +1025,7 @@ int heapbuf_get_stats(void *hphandle, struct memory_stats *stats)
stats->largest_free_size = (u32 *)0;
if (likely(obj->gate != NULL))
mutex_unlock(obj->gate);
gatepeterson_leave(obj->gate, 0);
return 0;
error:
......@@ -1036,6 +1055,7 @@ bool heapbuf_isblocking(void *handle)
/* retval true Heap blocks during alloc/free calls */
/* retval false Heap does not block during alloc/free calls */
return isblocking;
error:
printk(KERN_ERR "heapbuf_isblocking status: %x\n", retval);
return isblocking;
......@@ -1050,6 +1070,7 @@ EXPORT_SYMBOL(heapbuf_isblocking);
int heapbuf_get_extended_stats(void *hphandle,
struct heapbuf_extended_stats *stats)
{
int status = 0;
struct heap_object *object = NULL;
struct heapbuf_obj *obj = NULL;
s32 retval = 0;
......@@ -1075,10 +1096,12 @@ int heapbuf_get_extended_stats(void *hphandle,
object = (struct heap_object *)(hphandle);
obj = (struct heapbuf_obj *)object->obj;
if (likely(obj->gate != NULL)) {
retval = mutex_lock_interruptible(obj->gate);
if (retval)
status = gatepeterson_enter(obj->gate);
if (status < 0) {
retval = -EINVAL;
goto error;
}
}
/*
* The maximum number of allocations for this heapbuf (for any given
......@@ -1102,7 +1125,7 @@ int heapbuf_get_extended_stats(void *hphandle,
stats->num_allocated_blocks = obj->attrs->num_blocks
- obj->attrs->num_free_blocks;
if (likely(obj->gate != NULL))
mutex_unlock(obj->gate);
gatepeterson_leave(obj->gate, 0);
error:
printk(KERN_ERR "heapbuf_get_extended_stats status: %x\n",
......@@ -1138,4 +1161,3 @@ int heapbuf_shared_memreq(const struct heapbuf_params *params, u32 *buf_size)
return state_size;
}
EXPORT_SYMBOL(heapbuf_shared_memreq);
......@@ -110,9 +110,8 @@ static int heapbuf_ioctl_create(struct heapbuf_cmd_args *cargs)
goto exit;
}
if (cargs->args.create.name_len >= 0) {
params.name = kmalloc(cargs->args.create.name_len + 1,
GFP_KERNEL);
if (cargs->args.create.name_len > 0) {
params.name = kmalloc(cargs->args.create.name_len, GFP_KERNEL);
if (params.name == NULL) {
status = -ENOMEM;
goto exit;
......@@ -129,7 +128,10 @@ static int heapbuf_ioctl_create(struct heapbuf_cmd_args *cargs)
}
params.shared_addr = sharedregion_get_ptr((u32 *)
cargs->args.create.params->shared_addr);
cargs->args.create.shared_addr_srptr);
params.shared_buf = sharedregion_get_ptr((u32 *)
cargs->args.create.shared_buf_srptr);
params.gate = cargs->args.create.knl_gate;
handle = heapbuf_create(&params);
cargs->args.create.handle = handle;
cargs->api_status = 0;
......@@ -173,9 +175,8 @@ static int heapbuf_ioctl_open(struct heapbuf_cmd_args *cargs)
goto exit;
}
if (cargs->args.open.name_len >= 0) {
params.name = kmalloc(cargs->args.open.name_len + 1,
GFP_KERNEL);
if (cargs->args.open.name_len > 0) {
params.name = kmalloc(cargs->args.open.name_len, GFP_KERNEL);
if (params.name == NULL) {
status = -ENOMEM;
goto exit;
......@@ -192,7 +193,9 @@ static int heapbuf_ioctl_open(struct heapbuf_cmd_args *cargs)
}
params.shared_addr = sharedregion_get_ptr((u32 *)
cargs->args.open.params->shared_addr);
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)
goto free_name;
......
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