Re: [PATCH] Allocate cpg_dispatch message buffer in heap instead of stack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Friday 19 April 2013 12:36:15 Jan Friesse wrote:
> Jose,
> I was thinking about that problem a little deeper and what about
> implementing this:
> - Store buffer in cpg_inst (so alloc in cpg_initialize, free in
> cpg_finalize)
> - When dispatch is called, set variable in cpg_inst (something like
> is_in_dispatch) before callback and unset it after callback.
> - IF is_in_dispatch is set, allocate new buffer, else use buffer from
> cpg_inst
> 
> Basically, this should solve all problems with (in practice) no perf
> hit, because 99.9999% code doesn't reenter *_dispatch function, and make
> rest of 0.0001% code work correctly.

A tentative patch is attached, just for cpg for now. Freeing in finalize
is a bit tricky, as dispatch might still be running.

But this seems to be too much trouble when there is a decent workaround
(i.e., changing JVM's stack size with a simple command line parameter)
for my initial problem. So, I'm not pushing very hard for this
to get accepted.

-- 
Jose Orlando Pereira

diff --git a/lib/cpg.c b/lib/cpg.c
index b96df4e..cc589dc 100644
--- a/lib/cpg.c
+++ b/lib/cpg.c
@@ -54,6 +54,7 @@
 #include <qb/qbdefs.h>
 #include <qb/qbipcc.h>
 #include <qb/qblog.h>
+#include <qb/qbatomic.h>
 
 #include <corosync/hdb.h>
 #include <corosync/list.h>
@@ -72,6 +73,8 @@ struct cpg_inst {
 	qb_ipcc_connection_t *c;
 	int finalize;
 	void *context;
+	char *dispatch_buf;
+	int in_dispatch;
 	union {
 		cpg_model_data_t model_data;
 		cpg_model_v1_data_t model_v1_data;
@@ -169,6 +172,7 @@ cs_error_t cpg_model_initialize (
 {
 	cs_error_t error;
 	struct cpg_inst *cpg_inst;
+	char* dispatch_buf = NULL;
 
 	if (model != CPG_MODEL_V1) {
 		error = CS_ERR_INVALID_PARAM;
@@ -191,6 +195,13 @@ cs_error_t cpg_model_initialize (
 		goto error_put_destroy;
 	}
 
+	dispatch_buf = malloc(IPC_REQUEST_SIZE);
+	if (dispatch_buf == NULL) {
+		error = CS_ERR_NO_MEMORY;
+		goto error_destroy;
+	}
+	cpg_inst->dispatch_buf = dispatch_buf;
+
 	if (model_data != NULL) {
 		switch (model) {
 		case CPG_MODEL_V1:
@@ -216,6 +227,7 @@ cs_error_t cpg_model_initialize (
 error_put_destroy:
 	hdb_handle_put (&cpg_handle_t_db, *handle);
 error_destroy:
+	free(dispatch_buf);
 	hdb_handle_destroy (&cpg_handle_t_db, *handle);
 error_no_destroy:
 	return (error);
@@ -246,6 +258,13 @@ cs_error_t cpg_finalize (
 	cpg_inst->finalize = 1;
 
 	/*
+	 * Free buffer only if dispatch is not currently using it
+	 */
+	if (qb_atomic_int_compare_and_exchange(&cpg_inst->in_dispatch, 0, 1)) {
+		free(cpg_inst->dispatch_buf);
+	}
+
+	/*
 	 * Send service request
 	 */
 	req_lib_cpg_finalize.header.size = sizeof (struct req_lib_cpg_finalize);
@@ -346,7 +365,8 @@ cs_error_t cpg_dispatch (
 	struct cpg_ring_id ring_id;
 	uint32_t totem_member_list[CPG_MEMBERS_MAX];
 	int32_t errno_res;
-	char dispatch_buf[IPC_DISPATCH_SIZE];
+	char* dispatch_buf = NULL;
+	int owner = 0;
 
 	error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
 	if (error != CS_OK) {
@@ -361,6 +381,17 @@ cs_error_t cpg_dispatch (
 		timeout = 0;
 	}
 
+	if (qb_atomic_int_compare_and_exchange(&cpg_inst->in_dispatch, 0, 1)) {
+		dispatch_buf = cpg_inst->dispatch_buf;
+	} else {
+		owner = 1;
+		dispatch_buf = malloc(IPC_DISPATCH_SIZE);
+		if (dispatch_buf == NULL) {
+			error = CS_ERR_NO_MEMORY;
+			goto error_put;
+		}
+	}
+
 	dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
 	do {
 		errno_res = qb_ipcc_event_recv (
@@ -503,6 +534,11 @@ cs_error_t cpg_dispatch (
 	} while (cont);
 
 error_put:
+	if (owner || cpg_inst->finalize) {
+		free(dispatch_buf);
+	} else {
+		qb_atomic_int_set(&cpg_inst->in_dispatch, 0);
+	}
 	hdb_handle_put (&cpg_handle_t_db, handle);
 	return (error);
 }

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss

[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux