X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Flibrte_eal%2Fcommon%2Fhotplug_mp.c;h=ee791903b3b74fe73240cbdcf2305128cda36b49;hb=5b183ff611fc7aa4414abb99a31609a379323722;hp=84f59d95b64189a31040b29fdb7eef5b74ebe9a2;hpb=ac9e4a17370f19497d41da46bdb2d89bd307e59f;p=dpdk.git diff --git a/lib/librte_eal/common/hotplug_mp.c b/lib/librte_eal/common/hotplug_mp.c index 84f59d95b6..ee791903b3 100644 --- a/lib/librte_eal/common/hotplug_mp.c +++ b/lib/librte_eal/common/hotplug_mp.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -87,7 +88,7 @@ __handle_secondary_request(void *param) const struct eal_dev_mp_req *req = (const struct eal_dev_mp_req *)msg->param; struct eal_dev_mp_req tmp_req; - struct rte_devargs *da; + struct rte_devargs da; struct rte_device *dev; struct rte_bus *bus; int ret = 0; @@ -114,15 +115,11 @@ __handle_secondary_request(void *param) goto rollback; } } else if (req->t == EAL_DEV_REQ_TYPE_DETACH) { - da = calloc(1, sizeof(*da)); - if (da == NULL) { - ret = -ENOMEM; - goto finish; - } - - ret = rte_devargs_parse(da, req->devargs); + ret = rte_devargs_parse(&da, req->devargs); if (ret != 0) goto finish; + free(da.args); /* we don't need those */ + da.args = NULL; ret = eal_dev_hotplug_request_to_secondary(&tmp_req); if (ret != 0) { @@ -131,16 +128,16 @@ __handle_secondary_request(void *param) goto rollback; } - bus = rte_bus_find_by_name(da->bus->name); + bus = rte_bus_find_by_name(da.bus->name); if (bus == NULL) { - RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", da->bus->name); + RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", da.bus->name); ret = -ENOENT; goto finish; } - dev = bus->find_device(NULL, cmp_dev_name, da->name); + dev = bus->find_device(NULL, cmp_dev_name, da.name); if (dev == NULL) { - RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", da->name); + RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", da.name); ret = -ENOENT; goto finish; } @@ -204,6 +201,11 @@ handle_secondary_request(const struct rte_mp_msg *msg, const void *peer) * when it is ready. */ bundle->peer = strdup(peer); + if (bundle->peer == NULL) { + free(bundle); + RTE_LOG(ERR, EAL, "not enough memory\n"); + return send_response_to_secondary(req, -ENOMEM, peer); + } /** * We are at IPC callback thread, sync IPC is not allowed due to @@ -212,6 +214,8 @@ handle_secondary_request(const struct rte_mp_msg *msg, const void *peer) ret = rte_eal_alarm_set(1, __handle_secondary_request, bundle); if (ret != 0) { RTE_LOG(ERR, EAL, "failed to add mp task\n"); + free(bundle->peer); + free(bundle); return send_response_to_secondary(req, ret, peer); } return 0; @@ -243,7 +247,7 @@ static void __handle_primary_request(void *param) da = calloc(1, sizeof(*da)); if (da == NULL) { ret = -ENOMEM; - goto quit; + break; } ret = rte_devargs_parse(da, req->devargs); @@ -264,8 +268,23 @@ static void __handle_primary_request(void *param) goto quit; } + if (!rte_dev_is_probed(dev)) { + if (req->t == EAL_DEV_REQ_TYPE_ATTACH_ROLLBACK) { + /** + * Don't fail the rollback just because there's + * nothing to do. + */ + ret = 0; + } else + ret = -ENODEV; + + goto quit; + } + ret = local_dev_remove(dev); quit: + free(da->args); + free(da); break; default: ret = -EINVAL; @@ -300,6 +319,7 @@ handle_primary_request(const struct rte_mp_msg *msg, const void *peer) bundle = calloc(1, sizeof(*bundle)); if (bundle == NULL) { + RTE_LOG(ERR, EAL, "not enough memory\n"); resp->result = -ENOMEM; ret = rte_mp_reply(&mp_resp, peer); if (ret) @@ -314,6 +334,15 @@ handle_primary_request(const struct rte_mp_msg *msg, const void *peer) * when it is ready. */ bundle->peer = (void *)strdup(peer); + if (bundle->peer == NULL) { + RTE_LOG(ERR, EAL, "not enough memory\n"); + free(bundle); + resp->result = -ENOMEM; + ret = rte_mp_reply(&mp_resp, peer); + if (ret) + RTE_LOG(ERR, EAL, "failed to send reply to primary request\n"); + return ret; + } /** * We are at IPC callback thread, sync IPC is not allowed due to @@ -321,6 +350,8 @@ handle_primary_request(const struct rte_mp_msg *msg, const void *peer) */ ret = rte_eal_alarm_set(1, __handle_primary_request, bundle); if (ret != 0) { + free(bundle->peer); + free(bundle); resp->result = ret; ret = rte_mp_reply(&mp_resp, peer); if (ret != 0) { @@ -346,7 +377,7 @@ int eal_dev_hotplug_request_to_primary(struct eal_dev_mp_req *req) ret = rte_mp_request_sync(&mp_req, &mp_reply, &ts); if (ret || mp_reply.nb_received != 1) { - RTE_LOG(ERR, EAL, "cannot send request to primary"); + RTE_LOG(ERR, EAL, "Cannot send request to primary\n"); if (!ret) return -1; return ret; @@ -355,6 +386,7 @@ int eal_dev_hotplug_request_to_primary(struct eal_dev_mp_req *req) resp = (struct eal_dev_mp_req *)mp_reply.msgs[0].param; req->result = resp->result; + free(mp_reply.msgs); return ret; } @@ -373,12 +405,17 @@ int eal_dev_hotplug_request_to_secondary(struct eal_dev_mp_req *req) ret = rte_mp_request_sync(&mp_req, &mp_reply, &ts); if (ret != 0) { - RTE_LOG(ERR, EAL, "rte_mp_request_sync failed\n"); + /* if IPC is not supported, behave as if the call succeeded */ + if (rte_errno != ENOTSUP) + RTE_LOG(ERR, EAL, "rte_mp_request_sync failed\n"); + else + ret = 0; return ret; } if (mp_reply.nb_sent != mp_reply.nb_received) { RTE_LOG(ERR, EAL, "not all secondary reply\n"); + free(mp_reply.msgs); return -1; } @@ -387,27 +424,29 @@ int eal_dev_hotplug_request_to_secondary(struct eal_dev_mp_req *req) struct eal_dev_mp_req *resp = (struct eal_dev_mp_req *)mp_reply.msgs[i].param; if (resp->result != 0) { - req->result = resp->result; if (req->t == EAL_DEV_REQ_TYPE_ATTACH && - req->result != -EEXIST) - break; + resp->result == -EEXIST) + continue; if (req->t == EAL_DEV_REQ_TYPE_DETACH && - req->result != -ENOENT) - break; + resp->result == -ENOENT) + continue; + req->result = resp->result; } } + free(mp_reply.msgs); return 0; } -int rte_mp_dev_hotplug_init(void) +int eal_mp_dev_hotplug_init(void) { int ret; if (rte_eal_process_type() == RTE_PROC_PRIMARY) { ret = rte_mp_action_register(EAL_DEV_MP_ACTION_REQUEST, handle_secondary_request); - if (ret != 0) { + /* primary is allowed to not support IPC */ + if (ret != 0 && rte_errno != ENOTSUP) { RTE_LOG(ERR, EAL, "Couldn't register '%s' action\n", EAL_DEV_MP_ACTION_REQUEST); return ret;