X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Feal_common_proc.c;h=c649789a52756e26555c125cc10745b701167540;hb=b2a0b9f0447a64dd03aa210c49d70572077555ea;hp=f65ef56c01a27f6d24b733b9eebdb22f57e76087;hpb=45e5f49e87fba07c1e63f1630a3c76fc89a198a4;p=dpdk.git diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c index f65ef56c01..c649789a52 100644 --- a/lib/librte_eal/common/eal_common_proc.c +++ b/lib/librte_eal/common/eal_common_proc.c @@ -37,6 +37,7 @@ static int mp_fd = -1; static char mp_filter[PATH_MAX]; /* Filter for secondary process sockets */ static char mp_dir_path[PATH_MAX]; /* The directory path for all mp sockets */ static pthread_mutex_t mp_mutex_action = PTHREAD_MUTEX_INITIALIZER; +static char peer_name[PATH_MAX]; struct action_entry { TAILQ_ENTRY(action_entry) next; @@ -196,14 +197,22 @@ validate_action_name(const char *name) return 0; } -int __rte_experimental +int rte_mp_action_register(const char *name, rte_mp_t action) { struct action_entry *entry; + const struct internal_config *internal_conf = + eal_get_internal_configuration(); - if (validate_action_name(name)) + if (validate_action_name(name) != 0) return -1; + if (internal_conf->no_shconf) { + RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n"); + rte_errno = ENOTSUP; + return -1; + } + entry = malloc(sizeof(struct action_entry)); if (entry == NULL) { rte_errno = ENOMEM; @@ -224,14 +233,21 @@ rte_mp_action_register(const char *name, rte_mp_t action) return 0; } -void __rte_experimental +void rte_mp_action_unregister(const char *name) { struct action_entry *entry; + const struct internal_config *internal_conf = + eal_get_internal_configuration(); - if (validate_action_name(name)) + if (validate_action_name(name) != 0) return; + if (internal_conf->no_shconf) { + RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n"); + return; + } + pthread_mutex_lock(&mp_mutex_action); entry = find_action_entry_by_name(name); if (entry == NULL) { @@ -271,7 +287,7 @@ read_msg(struct mp_msg_internal *m, struct sockaddr_un *s) } if (msglen != buflen || (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) { - RTE_LOG(ERR, EAL, "truncted msg\n"); + RTE_LOG(ERR, EAL, "truncated msg\n"); return -1; } @@ -284,7 +300,15 @@ read_msg(struct mp_msg_internal *m, struct sockaddr_un *s) break; } } - + /* sanity-check the response */ + if (m->msg.num_fds < 0 || m->msg.num_fds > RTE_MP_MAX_FD_NUM) { + RTE_LOG(ERR, EAL, "invalid number of fd's received\n"); + return -1; + } + if (m->msg.len_param < 0 || m->msg.len_param > RTE_MP_MAX_PARAM_LEN) { + RTE_LOG(ERR, EAL, "invalid received data length\n"); + return -1; + } return 0; } @@ -295,6 +319,8 @@ process_msg(struct mp_msg_internal *m, struct sockaddr_un *s) struct action_entry *entry; struct rte_mp_msg *msg = &m->msg; rte_mp_t action = NULL; + const struct internal_config *internal_conf = + eal_get_internal_configuration(); RTE_LOG(DEBUG, EAL, "msg: %s\n", msg->name); @@ -330,7 +356,7 @@ process_msg(struct mp_msg_internal *m, struct sockaddr_un *s) pthread_mutex_unlock(&mp_mutex_action); if (!action) { - if (m->type == MP_REQ && !internal_config.init_complete) { + if (m->type == MP_REQ && !internal_conf->init_complete) { /* if this is a request, and init is not yet complete, * and callback wasn't registered, we should tell the * requester to ignore our existence because we're not @@ -511,9 +537,9 @@ async_reply_handle(void *arg) static int open_socket_fd(void) { - char peer_name[PATH_MAX] = {0}; struct sockaddr_un un; + peer_name[0] = '\0'; if (rte_eal_process_type() == RTE_PROC_SECONDARY) snprintf(peer_name, sizeof(peer_name), "%d_%"PRIx64, getpid(), rte_rdtsc()); @@ -542,27 +568,17 @@ open_socket_fd(void) return mp_fd; } -static int -unlink_sockets(const char *filter) +static void +close_socket_fd(void) { - int dir_fd; - DIR *mp_dir; - struct dirent *ent; - - mp_dir = opendir(mp_dir_path); - if (!mp_dir) { - RTE_LOG(ERR, EAL, "Unable to open directory %s\n", mp_dir_path); - return -1; - } - dir_fd = dirfd(mp_dir); + char path[PATH_MAX]; - while ((ent = readdir(mp_dir))) { - if (fnmatch(filter, ent->d_name, 0) == 0) - unlinkat(dir_fd, ent->d_name, 0); - } + if (mp_fd < 0) + return; - closedir(mp_dir); - return 0; + close(mp_fd); + create_socket_path(peer_name, path, sizeof(path)); + unlink(path); } int @@ -571,13 +587,16 @@ rte_mp_channel_init(void) char path[PATH_MAX]; int dir_fd; pthread_t mp_handle_tid; + const struct internal_config *internal_conf = + eal_get_internal_configuration(); /* in no shared files mode, we do not have secondary processes support, * so no need to initialize IPC. */ - if (internal_config.no_shconf) { + if (internal_conf->no_shconf) { RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC will be disabled\n"); - return 0; + rte_errno = ENOTSUP; + return -1; } /* create filter path */ @@ -603,13 +622,6 @@ rte_mp_channel_init(void) return -1; } - if (rte_eal_process_type() == RTE_PROC_PRIMARY && - unlink_sockets(mp_filter)) { - RTE_LOG(ERR, EAL, "failed to unlink mp sockets\n"); - close(dir_fd); - return -1; - } - if (open_socket_fd() < 0) { close(dir_fd); return -1; @@ -632,6 +644,12 @@ rte_mp_channel_init(void) return 0; } +void +rte_mp_channel_cleanup(void) +{ + close_socket_fd(); +} + /** * Return -1, as fail to send message and it's caused by the local side. * Return 0, as fail to send message and it's caused by the remote side. @@ -688,11 +706,6 @@ send_msg(const char *dst_path, struct rte_mp_msg *msg, int type) unlink(dst_path); return 0; } - if (errno == ENOBUFS) { - RTE_LOG(ERR, EAL, "Peer cannot receive message %s\n", - dst_path); - return 0; - } RTE_LOG(ERR, EAL, "failed to send to (%s) due to %s\n", dst_path, strerror(errno)); return -1; @@ -756,40 +769,61 @@ mp_send(struct rte_mp_msg *msg, const char *peer, int type) return ret; } -static bool +static int check_input(const struct rte_mp_msg *msg) { if (msg == NULL) { RTE_LOG(ERR, EAL, "Msg cannot be NULL\n"); rte_errno = EINVAL; - return false; + return -1; } - if (validate_action_name(msg->name)) - return false; + if (validate_action_name(msg->name) != 0) + return -1; + + if (msg->len_param < 0) { + RTE_LOG(ERR, EAL, "Message data length is negative\n"); + rte_errno = EINVAL; + return -1; + } + + if (msg->num_fds < 0) { + RTE_LOG(ERR, EAL, "Number of fd's is negative\n"); + rte_errno = EINVAL; + return -1; + } if (msg->len_param > RTE_MP_MAX_PARAM_LEN) { RTE_LOG(ERR, EAL, "Message data is too long\n"); rte_errno = E2BIG; - return false; + return -1; } if (msg->num_fds > RTE_MP_MAX_FD_NUM) { RTE_LOG(ERR, EAL, "Cannot send more than %d FDs\n", RTE_MP_MAX_FD_NUM); rte_errno = E2BIG; - return false; + return -1; } - return true; + return 0; } -int __rte_experimental +int rte_mp_sendmsg(struct rte_mp_msg *msg) { - if (!check_input(msg)) + const struct internal_config *internal_conf = + eal_get_internal_configuration(); + + if (check_input(msg) != 0) return -1; + if (internal_conf->no_shconf) { + RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n"); + rte_errno = ENOTSUP; + return -1; + } + RTE_LOG(DEBUG, EAL, "sendmsg: %s\n", msg->name); return mp_send(msg, NULL, MP_MSG); } @@ -827,28 +861,6 @@ mp_request_async(const char *dst, struct rte_mp_msg *req, goto fail; } - /* - * set the alarm before sending message. there are two possible error - * scenarios to consider here: - * - * - if the alarm set fails, we free the memory right there - * - if the alarm set succeeds but sending message fails, then the alarm - * will trigger and clean up the memory - * - * Even if the alarm triggers too early (i.e. immediately), we're still - * holding the lock to pending requests queue, so the interrupt thread - * will just spin until we release the lock, and either release the - * memory, or doesn't find any pending requests in the queue because we - * never added any due to send message failure. - */ - if (rte_eal_alarm_set(ts->tv_sec * 1000000 + ts->tv_nsec / 1000, - async_reply_handle, pending_req) < 0) { - RTE_LOG(ERR, EAL, "Fail to set alarm for request %s:%s\n", - dst, req->name); - ret = -1; - goto fail; - } - ret = send_msg(dst, req, MP_REQ); if (ret < 0) { RTE_LOG(ERR, EAL, "Fail to send request %s:%s\n", @@ -859,10 +871,18 @@ mp_request_async(const char *dst, struct rte_mp_msg *req, ret = 0; goto fail; } - TAILQ_INSERT_TAIL(&pending_requests.requests, pending_req, next); - param->user_reply.nb_sent++; + /* if alarm set fails, we simply ignore the reply */ + if (rte_eal_alarm_set(ts->tv_sec * 1000000 + ts->tv_nsec / 1000, + async_reply_handle, pending_req) < 0) { + RTE_LOG(ERR, EAL, "Fail to set alarm for request %s:%s\n", + dst, req->name); + ret = -1; + goto fail; + } + TAILQ_INSERT_TAIL(&pending_requests.requests, pending_req, next); + return 0; fail: free(pending_req); @@ -939,34 +959,37 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req, return 0; } -int __rte_experimental +int rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, const struct timespec *ts) { - int dir_fd, ret = 0; + int dir_fd, ret = -1; DIR *mp_dir; struct dirent *ent; struct timeval now; struct timespec end; + const struct internal_config *internal_conf = + eal_get_internal_configuration(); RTE_LOG(DEBUG, EAL, "request: %s\n", req->name); - if (check_input(req) == false) - return -1; - reply->nb_sent = 0; reply->nb_received = 0; reply->msgs = NULL; - if (internal_config.no_shconf) { + if (check_input(req) != 0) + goto end; + + if (internal_conf->no_shconf) { RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n"); - return 0; + rte_errno = ENOTSUP; + return -1; } if (gettimeofday(&now, NULL) < 0) { RTE_LOG(ERR, EAL, "Failed to get current time\n"); rte_errno = errno; - return -1; + goto end; } end.tv_nsec = (now.tv_usec * 1000 + ts->tv_nsec) % 1000000000; @@ -978,7 +1001,7 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, pthread_mutex_lock(&pending_requests.lock); ret = mp_request_sync(eal_mp_socket_path(), req, reply, &end); pthread_mutex_unlock(&pending_requests.lock); - return ret; + goto end; } /* for primary process, broadcast request, and collect reply 1 by 1 */ @@ -986,7 +1009,7 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, if (!mp_dir) { RTE_LOG(ERR, EAL, "Unable to open directory %s\n", mp_dir_path); rte_errno = errno; - return -1; + goto end; } dir_fd = dirfd(mp_dir); @@ -994,9 +1017,8 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, if (flock(dir_fd, LOCK_SH)) { RTE_LOG(ERR, EAL, "Unable to lock directory %s\n", mp_dir_path); - closedir(mp_dir); rte_errno = errno; - return -1; + goto close_end; } pthread_mutex_lock(&pending_requests.lock); @@ -1013,18 +1035,29 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply, * locks on receive */ if (mp_request_sync(path, req, reply, &end)) - ret = -1; + goto unlock_end; } + ret = 0; + +unlock_end: pthread_mutex_unlock(&pending_requests.lock); /* unlock the directory */ flock(dir_fd, LOCK_UN); +close_end: /* dir_fd automatically closed on closedir */ closedir(mp_dir); + +end: + if (ret) { + free(reply->msgs); + reply->nb_received = 0; + reply->msgs = NULL; + } return ret; } -int __rte_experimental +int rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, rte_mp_async_reply_t clb) { @@ -1038,19 +1071,22 @@ rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts, struct timeval now; struct timespec *end; bool dummy_used = false; + const struct internal_config *internal_conf = + eal_get_internal_configuration(); RTE_LOG(DEBUG, EAL, "request: %s\n", req->name); - if (check_input(req) == false) + if (check_input(req) != 0) return -1; - if (internal_config.no_shconf) { + if (internal_conf->no_shconf) { RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n"); - return 0; + rte_errno = ENOTSUP; + return -1; } if (gettimeofday(&now, NULL) < 0) { - RTE_LOG(ERR, EAL, "Faile to get current time\n"); + RTE_LOG(ERR, EAL, "Failed to get current time\n"); rte_errno = errno; return -1; } @@ -1173,12 +1209,14 @@ fail: return -1; } -int __rte_experimental +int rte_mp_reply(struct rte_mp_msg *msg, const char *peer) { RTE_LOG(DEBUG, EAL, "reply: %s\n", msg->name); + const struct internal_config *internal_conf = + eal_get_internal_configuration(); - if (check_input(msg) == false) + if (check_input(msg) != 0) return -1; if (peer == NULL) { @@ -1187,7 +1225,7 @@ rte_mp_reply(struct rte_mp_msg *msg, const char *peer) return -1; } - if (internal_config.no_shconf) { + if (internal_conf->no_shconf) { RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n"); return 0; }