src/dpdk/lib/librte_eal/common/malloc_mp.c
static int
handle_sync_response(const struct rte_mp_msg *request,
		const struct rte_mp_reply *reply)
{
	enum malloc_req_result result;
	struct mp_request *entry;
	const struct malloc_mp_req *mpreq =
			(const struct malloc_mp_req *)request->param;
	int i;

	/* lock the request */
	pthread_mutex_lock(&mp_request_list.lock);

	entry = find_request_by_id(mpreq->id);
	if (entry == NULL) {
		RTE_LOG(ERR, EAL, "Wrong request ID\n");
		goto fail;
	}

	result = REQ_RESULT_SUCCESS;

	if (reply->nb_received != reply->nb_sent)
		result = REQ_RESULT_FAIL;

	for (i = 0; i < reply->nb_received; i++) {
		struct malloc_mp_req *resp =
				(struct malloc_mp_req *)reply->msgs[i].param;

		if (resp->t != REQ_TYPE_SYNC) {
			RTE_LOG(ERR, EAL, "Unexpected response to sync request\n");
			result = REQ_RESULT_FAIL;
			break;
		}
		if (resp->id != entry->user_req.id) {
			RTE_LOG(ERR, EAL, "Response to wrong sync request\n");
			result = REQ_RESULT_FAIL;
			break;
		}
		if (resp->result == REQ_RESULT_FAIL) {
			result = REQ_RESULT_FAIL;
			break;
		}
	}

	if (entry->user_req.t == REQ_TYPE_FREE) {
		struct rte_mp_msg msg;
		struct malloc_mp_req *resp = (struct malloc_mp_req *)msg.param;

		memset(&msg, 0, sizeof(msg));

		/* this is a free request, just sendmsg result */
		resp->t = REQ_TYPE_FREE;
		resp->result = result;
		resp->id = entry->user_req.id;
		msg.num_fds = 0;
		msg.len_param = sizeof(*resp);
		strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));

		if (rte_mp_sendmsg(&msg))
			RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");

		TAILQ_REMOVE(&mp_request_list.list, entry, next);
		free(entry);
	} else if (entry->user_req.t == REQ_TYPE_ALLOC &&
			result == REQ_RESULT_SUCCESS) {
		struct malloc_heap *heap = entry->alloc_state.heap;
		struct rte_mp_msg msg;
		struct malloc_mp_req *resp =
				(struct malloc_mp_req *)msg.param;

		memset(&msg, 0, sizeof(msg));

		heap->total_size += entry->alloc_state.map_len;

		/* result is success, so just notify secondary about this */
		resp->t = REQ_TYPE_ALLOC;
		resp->result = result;
		resp->id = entry->user_req.id;
		msg.num_fds = 0;
		msg.len_param = sizeof(*resp);
		strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));

		if (rte_mp_sendmsg(&msg))
			RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");

		TAILQ_REMOVE(&mp_request_list.list, entry, next);
		free(entry->alloc_state.ms);
		free(entry);
	} else if (entry->user_req.t == REQ_TYPE_ALLOC &&
			result == REQ_RESULT_FAIL) {
		struct rte_mp_msg rb_msg;
		struct malloc_mp_req *rb =
				(struct malloc_mp_req *)rb_msg.param;
		struct timespec ts;
		struct primary_alloc_req_state *state =
				&entry->alloc_state;
		int ret;

		memset(&rb_msg, 0, sizeof(rb_msg));

		/* we've failed to sync, so do a rollback */
		eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,
				state->map_addr, state->map_len);

		rollback_expand_heap(state->ms, state->ms_len, state->elem,
				state->map_addr, state->map_len);

		/* send rollback request */
		rb_msg.num_fds = 0;
		rb_msg.len_param = sizeof(*rb);
		strlcpy(rb_msg.name, MP_ACTION_ROLLBACK, sizeof(rb_msg.name));

		ts.tv_nsec = 0;
		ts.tv_sec = MP_TIMEOUT_S;

		/* sync requests carry no data */
		rb->t = REQ_TYPE_SYNC;
		rb->id = entry->user_req.id;

		/* there may be stray timeout still waiting */
		do {
			ret = rte_mp_request_async(&rb_msg, &ts,
					handle_rollback_response);
		} while (ret != 0 && rte_errno == EEXIST);
		if (ret != 0) {
			RTE_LOG(ERR, EAL, "Could not send rollback request to secondary process\n");

			/* we couldn't send rollback request, but that's OK -
			 * secondary will time out, and memory has been removed
			 * from heap anyway.
			 */
			TAILQ_REMOVE(&mp_request_list.list, entry, next);
			free(state->ms);
			free(entry);
			goto fail;
		}
	} else {
		RTE_LOG(ERR, EAL, " to sync request of unknown type\n");
		goto fail;
	}

	pthread_mutex_unlock(&mp_request_list.lock);
	return 0;
fail:
	pthread_mutex_unlock(&mp_request_list.lock);
	return -1;
}
/* callback for asynchronous sync requests for primary. this will either do a
 * sendmsg with results, or trigger rollback request.
 */
callback for asynchronous sync requests for primary. this will either do a
sendmsg with results, or trigger rollback request.
callback for asynchronous sync requests for primary . this will either do a sendmsg with results or trigger rollback request .
static int
handle_sync_response(const struct rte_mp_msg *request,
		const struct rte_mp_reply *reply)
{
	enum malloc_req_result result;
	struct mp_request *entry;
	const struct malloc_mp_req *mpreq =
			(const struct malloc_mp_req *)request->param;
	int i;
	pthread_mutex_lock(&mp_request_list.lock);
	entry = find_request_by_id(mpreq->id);
	if (entry == NULL) {
		RTE_LOG(ERR, EAL, "Wrong request ID\n");
		goto fail;
	}
	result = REQ_RESULT_SUCCESS;
	if (reply->nb_received != reply->nb_sent)
		result = REQ_RESULT_FAIL;
	for (i = 0; i < reply->nb_received; i++) {
		struct malloc_mp_req *resp =
				(struct malloc_mp_req *)reply->msgs[i].param;
		if (resp->t != REQ_TYPE_SYNC) {
			RTE_LOG(ERR, EAL, "Unexpected response to sync request\n");
			result = REQ_RESULT_FAIL;
			break;
		}
		if (resp->id != entry->user_req.id) {
			RTE_LOG(ERR, EAL, "Response to wrong sync request\n");
			result = REQ_RESULT_FAIL;
			break;
		}
		if (resp->result == REQ_RESULT_FAIL) {
			result = REQ_RESULT_FAIL;
			break;
		}
	}
	if (entry->user_req.t == REQ_TYPE_FREE) {
		struct rte_mp_msg msg;
		struct malloc_mp_req *resp = (struct malloc_mp_req *)msg.param;
		memset(&msg, 0, sizeof(msg));
		resp->t = REQ_TYPE_FREE;
		resp->result = result;
		resp->id = entry->user_req.id;
		msg.num_fds = 0;
		msg.len_param = sizeof(*resp);
		strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
		if (rte_mp_sendmsg(&msg))
			RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
		TAILQ_REMOVE(&mp_request_list.list, entry, next);
		free(entry);
	} else if (entry->user_req.t == REQ_TYPE_ALLOC &&
			result == REQ_RESULT_SUCCESS) {
		struct malloc_heap *heap = entry->alloc_state.heap;
		struct rte_mp_msg msg;
		struct malloc_mp_req *resp =
				(struct malloc_mp_req *)msg.param;
		memset(&msg, 0, sizeof(msg));
		heap->total_size += entry->alloc_state.map_len;
		resp->t = REQ_TYPE_ALLOC;
		resp->result = result;
		resp->id = entry->user_req.id;
		msg.num_fds = 0;
		msg.len_param = sizeof(*resp);
		strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
		if (rte_mp_sendmsg(&msg))
			RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
		TAILQ_REMOVE(&mp_request_list.list, entry, next);
		free(entry->alloc_state.ms);
		free(entry);
	} else if (entry->user_req.t == REQ_TYPE_ALLOC &&
			result == REQ_RESULT_FAIL) {
		struct rte_mp_msg rb_msg;
		struct malloc_mp_req *rb =
				(struct malloc_mp_req *)rb_msg.param;
		struct timespec ts;
		struct primary_alloc_req_state *state =
				&entry->alloc_state;
		int ret;
		memset(&rb_msg, 0, sizeof(rb_msg));
		eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,
				state->map_addr, state->map_len);
		rollback_expand_heap(state->ms, state->ms_len, state->elem,
				state->map_addr, state->map_len);
		rb_msg.num_fds = 0;
		rb_msg.len_param = sizeof(*rb);
		strlcpy(rb_msg.name, MP_ACTION_ROLLBACK, sizeof(rb_msg.name));
		ts.tv_nsec = 0;
		ts.tv_sec = MP_TIMEOUT_S;
		rb->t = REQ_TYPE_SYNC;
		rb->id = entry->user_req.id;
		do {
			ret = rte_mp_request_async(&rb_msg, &ts,
					handle_rollback_response);
		} while (ret != 0 && rte_errno == EEXIST);
		if (ret != 0) {
			RTE_LOG(ERR, EAL, "Could not send rollback request to secondary process\n");
			TAILQ_REMOVE(&mp_request_list.list, entry, next);
			free(state->ms);
			free(entry);
			goto fail;
		}
	} else {
		RTE_LOG(ERR, EAL, " to sync request of unknown type\n");
		goto fail;
	}
	pthread_mutex_unlock(&mp_request_list.lock);
	return 0;
fail:
	pthread_mutex_unlock(&mp_request_list.lock);
	return -1;
}
static int handle_sync_response ( const struct rte_mp_msg * request , const struct rte_mp_reply * reply ) { enum malloc_req_result result ; struct mp_request * entry ; const struct malloc_mp_req * mpreq = ( const struct malloc_mp_req * ) request -> param ; int i ; pthread_mutex_lock ( & mp_request_list . lock ) ; entry = find_request_by_id ( mpreq -> id ) ; if ( entry == NULL ) { RTE_LOG ( ERR , EAL , " \n " ) ; goto fail ; } result = REQ_RESULT_SUCCESS ; if ( reply -> nb_received != reply -> nb_sent ) result = REQ_RESULT_FAIL ; for ( i = 0 ; i < reply -> nb_received ; i ++ ) { struct malloc_mp_req * resp = ( struct malloc_mp_req * ) reply -> msgs [ i ] . param ; if ( resp -> t != REQ_TYPE_SYNC ) { RTE_LOG ( ERR , EAL , " \n " ) ; result = REQ_RESULT_FAIL ; break ; } if ( resp -> id != entry -> user_req . id ) { RTE_LOG ( ERR , EAL , " \n " ) ; result = REQ_RESULT_FAIL ; break ; } if ( resp -> result == REQ_RESULT_FAIL ) { result = REQ_RESULT_FAIL ; break ; } } if ( entry -> user_req . t == REQ_TYPE_FREE ) { struct rte_mp_msg msg ; struct malloc_mp_req * resp = ( struct malloc_mp_req * ) msg . param ; memset ( & msg , 0 , sizeof ( msg ) ) ; resp -> t = REQ_TYPE_FREE ; resp -> result = result ; resp -> id = entry -> user_req . id ; msg . num_fds = 0 ; msg . len_param = sizeof ( * resp ) ; strlcpy ( msg . name , MP_ACTION_RESPONSE , sizeof ( msg . name ) ) ; if ( rte_mp_sendmsg ( & msg ) ) RTE_LOG ( ERR , EAL , " \n " ) ; TAILQ_REMOVE ( & mp_request_list . list , entry , next ) ; free ( entry ) ; } else if ( entry -> user_req . t == REQ_TYPE_ALLOC && result == REQ_RESULT_SUCCESS ) { struct malloc_heap * heap = entry -> alloc_state . heap ; struct rte_mp_msg msg ; struct malloc_mp_req * resp = ( struct malloc_mp_req * ) msg . param ; memset ( & msg , 0 , sizeof ( msg ) ) ; heap -> total_size += entry -> alloc_state . map_len ; resp -> t = REQ_TYPE_ALLOC ; resp -> result = result ; resp -> id = entry -> user_req . id ; msg . num_fds = 0 ; msg . len_param = sizeof ( * resp ) ; strlcpy ( msg . name , MP_ACTION_RESPONSE , sizeof ( msg . name ) ) ; if ( rte_mp_sendmsg ( & msg ) ) RTE_LOG ( ERR , EAL , " \n " ) ; TAILQ_REMOVE ( & mp_request_list . list , entry , next ) ; free ( entry -> alloc_state . ms ) ; free ( entry ) ; } else if ( entry -> user_req . t == REQ_TYPE_ALLOC && result == REQ_RESULT_FAIL ) { struct rte_mp_msg rb_msg ; struct malloc_mp_req * rb = ( struct malloc_mp_req * ) rb_msg . param ; struct timespec ts ; struct primary_alloc_req_state * state = & entry -> alloc_state ; int ret ; memset ( & rb_msg , 0 , sizeof ( rb_msg ) ) ; eal_memalloc_mem_event_notify ( RTE_MEM_EVENT_FREE , state -> map_addr , state -> map_len ) ; rollback_expand_heap ( state -> ms , state -> ms_len , state -> elem , state -> map_addr , state -> map_len ) ; rb_msg . num_fds = 0 ; rb_msg . len_param = sizeof ( * rb ) ; strlcpy ( rb_msg . name , MP_ACTION_ROLLBACK , sizeof ( rb_msg . name ) ) ; ts . tv_nsec = 0 ; ts . tv_sec = MP_TIMEOUT_S ; rb -> t = REQ_TYPE_SYNC ; rb -> id = entry -> user_req . id ; do { ret = rte_mp_request_async ( & rb_msg , & ts , handle_rollback_response ) ; } while ( ret != 0 && rte_errno == EEXIST ) ; if ( ret != 0 ) { RTE_LOG ( ERR , EAL , " \n " ) ; TAILQ_REMOVE ( & mp_request_list . list , entry , next ) ; free ( state -> ms ) ; free ( entry ) ; goto fail ; } } else { RTE_LOG ( ERR , EAL , " \n " ) ; goto fail ; } pthread_mutex_unlock ( & mp_request_list . lock ) ; return 0 ; fail : pthread_mutex_unlock ( & mp_request_list . lock ) ; return -1 ; }
callback for asynchronous sync requests for primary.
callback for asynchronous sync requests for primary .
/* lock the request */ /* this is a free request, just sendmsg result */ /* result is success, so just notify secondary about this */ /* we've failed to sync, so do a rollback */ /* send rollback request */ /* sync requests carry no data */ /* there may be stray timeout still waiting */ /* we couldn't send rollback request, but that's OK -
			 * secondary will time out, and memory has been removed
			 * from heap anyway.
			 */