From patchwork Thu Oct 15 19:33:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Long Li X-Patchwork-Id: 80977 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 051C2A04DB; Thu, 15 Oct 2020 21:33:37 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CFF2A1DDEF; Thu, 15 Oct 2020 21:33:35 +0200 (CEST) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by dpdk.org (Postfix) with ESMTP id E510D1DDE1; Thu, 15 Oct 2020 21:33:33 +0200 (CEST) Received: by linux.microsoft.com (Postfix, from userid 1004) id 3F0AA20B4905; Thu, 15 Oct 2020 12:33:32 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 3F0AA20B4905 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxonhyperv.com; s=default; t=1602790412; bh=LiE9ZnJoga01+v+tx63GAuzEKV8DlbXmEgpPZgmWdsw=; h=From:To:Cc:Subject:Date:From; b=ky5CU/+5gmWi8N4vpqqJSpnm1vKmHUh9AvPUE9K9OoA7Hs3/2d17P3VEcoTHHFYSz DgwVY8HcFK+G6LvUHBUfUbWKf1I5kIqfSwuA9ONmuVV3+LxIo+AbctRaVerkQ2BMsA HLjBvSP0sTJrgJP3qXSfQqtahUYoiylbZkon5drE= From: Long Li To: Matan Azrad Cc: dev@dpdk.org, Long Li , stable@dpdk.org Date: Thu, 15 Oct 2020 12:33:05 -0700 Message-Id: <1602790385-13032-1-git-send-email-longli@linuxonhyperv.com> X-Mailer: git-send-email 1.8.3.1 Subject: [dpdk-dev] [PATCH] net/vdev_netvsc: Prevent alarm lost on failed device probe X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Long Li If a device probe fails, the alarm is canceled and will no longer work for previously probed devices. Fix this by introducing a flag to track if alarm has been set. Because it's possible that an alarm is triggered while probing is in progress that may modify vdev_netvsc_ctx_list, introduce a lock to protect it. Cc: stable@dpdk.org Signed-off-by: Long Li --- drivers/net/vdev_netvsc/vdev_netvsc.c | 41 +++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/net/vdev_netvsc/vdev_netvsc.c b/drivers/net/vdev_netvsc/vdev_netvsc.c index be8f19c..bd7e308 100644 --- a/drivers/net/vdev_netvsc/vdev_netvsc.c +++ b/drivers/net/vdev_netvsc/vdev_netvsc.c @@ -76,6 +76,11 @@ struct vdev_netvsc_ctx { /** Context list is common to all driver instances. */ static LIST_HEAD(, vdev_netvsc_ctx) vdev_netvsc_ctx_list = LIST_HEAD_INITIALIZER(vdev_netvsc_ctx_list); +/* Lock to protect concurrent accesses to vdev_netvsc_ctx_list */ +static rte_rwlock_t vdev_netvsc_ctx_list_lock; + +/* Flag to track if alarm has been set */ +static int vdev_netvsc_alarm_set; /** Number of entries in context list. */ static unsigned int vdev_netvsc_ctx_count; @@ -454,19 +459,26 @@ static LIST_HEAD(, vdev_netvsc_ctx) vdev_netvsc_ctx_list = struct vdev_netvsc_ctx *ctx; int ret; + rte_rwlock_write_lock(&vdev_netvsc_ctx_list_lock); LIST_FOREACH(ctx, &vdev_netvsc_ctx_list, entry) { ret = vdev_netvsc_foreach_iface(vdev_netvsc_device_probe, 0, ctx); if (ret < 0) break; } - if (!vdev_netvsc_ctx_count) + rte_rwlock_write_unlock(&vdev_netvsc_ctx_list_lock); + + if (!vdev_netvsc_ctx_count) { + vdev_netvsc_alarm_set = 0; return; + } + ret = rte_eal_alarm_set(VDEV_NETVSC_PROBE_MS * 1000, vdev_netvsc_alarm, NULL); if (ret < 0) { DRV_LOG(ERR, "unable to reschedule alarm callback: %s", rte_strerror(-ret)); + vdev_netvsc_alarm_set = 0; } } @@ -698,34 +710,41 @@ static LIST_HEAD(, vdev_netvsc_ctx) vdev_netvsc_ctx_list = " device."); goto error; } - rte_eal_alarm_cancel(vdev_netvsc_alarm, NULL); + + rte_rwlock_write_lock(&vdev_netvsc_ctx_list_lock); /* Gather interfaces. */ ret = vdev_netvsc_foreach_iface(vdev_netvsc_netvsc_probe, 1, name, kvargs, specified, &matched); if (ret < 0) - goto error; + goto error_unlock; if (specified && matched < specified) { if (!force) { DRV_LOG(ERR, "Cannot find the specified netvsc device"); - goto error; + goto error_unlock; } /* Try to force probing on non-netvsc specified device. */ if (vdev_netvsc_foreach_iface(vdev_netvsc_netvsc_probe, 0, name, kvargs, specified, &matched) < 0) - goto error; + goto error_unlock; if (matched < specified) { DRV_LOG(ERR, "Cannot find the specified device"); - goto error; + goto error_unlock; } DRV_LOG(WARNING, "non-netvsc device was probed as netvsc"); } - ret = rte_eal_alarm_set(VDEV_NETVSC_PROBE_MS * 1000, + if (!vdev_netvsc_alarm_set) { + ret = rte_eal_alarm_set(VDEV_NETVSC_PROBE_MS * 1000, vdev_netvsc_alarm, NULL); - if (ret < 0) { - DRV_LOG(ERR, "unable to schedule alarm callback: %s", - rte_strerror(-ret)); - goto error; + if (ret < 0) + DRV_LOG(ERR, "unable to schedule alarm callback: %s", + rte_strerror(-ret)); + else + vdev_netvsc_alarm_set = 1; } + +error_unlock: + rte_rwlock_write_unlock(&vdev_netvsc_ctx_list_lock); + error: if (kvargs) rte_kvargs_free(kvargs);