From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7ACAA43F08C for ; Thu, 30 Jul 2026 14:56:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785423370; cv=none; b=tDepGEN6x8AOUkdf/0xZvRnCFob3BMb0z2wxM3Lhp0MPS6qUXfF7wxg7VIC+5yvpVxYj3L/Ewk2Mdf6zFBGILPbINF+cB1Zj+VYl1BOgcQ+ULlQQReC7whN1Scm7YeXAY3sITzPYOJBCkyHqUempRshcByYBdqrZwHkIJRTnlMA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785423370; c=relaxed/simple; bh=1IwhCeOSGfHIUTSp68RI4myZPbDSYzd3+jmAO1Nv/P0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EZQP5LvJTgNnXAlwGCw/pgj6+SwpthvOEjRTKHlZYKCIdO116cKbIJh/MYwDlq7wLyjzICUhYUTA9xPgpl1ITZnpWctRYOYzbDmYYbPsykZUyF0QH5WZd9ho5/cDX+AtmNajtqIDDxKpq2bcfkjNrQhfCpSZkmn9STX8l2CXVM4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lYpDI9da; arc=none smtp.client-ip=209.85.128.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lYpDI9da" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-4953e04ef16so21668185e9.2 for ; Thu, 30 Jul 2026 07:56:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785423367; x=1786028167; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ehAlYsFHvV0gZg+DHaBIyQIOf2PYndruWsclXbIjl3U=; b=lYpDI9daCVt1Q2ec4ABi5C4ig9Xkf4+O6ZYA0/MDXAH/1YGijNjPyEuXi/VoipJL2g Si05+FweKJ1sL5lMS3LAfqLYUU4EiM3yuVVtX7j28NUOGXLhNcdkuPK1RjsfgiEkyB+4 NKy+nGbYdbmIpUtvWF+yy2nEY92LjOJ4Ly2jMSGEtJNzu9SBlXb5GnlX9y4PKKr7F8tY O26tU/rSCFeV82bQpyDdlFuG7+dwWPew0oYPvAq21CHCKCfC8i0lacmM6R1H58VXnKtv 2w73NZ3Ib/pgRGq8/U8z6PkxMXtrByOKFcxC00lIUd1O19gMuNwZLkayeS5RqFw7T9gL UzQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785423367; x=1786028167; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=ehAlYsFHvV0gZg+DHaBIyQIOf2PYndruWsclXbIjl3U=; b=Ig8TbB5PCYnxvcmwGTuIfRB5GE4kv6zjp00bEudoJPTlh32+F9ID2I13tn7IJdFFaB IWOJJo8JH8pMaL7Tu9VK0i59/h90w9gy3+PsBHRopme/GhLbeRrqew6SJroVityzt2My NXBE0hF4n/OsRaVy/GfAL2nhPwNPdGEEsYLsx2rRPjYwHtwN93qfLdX87BtB5RyjH86X koIe49RVB0IRoAxBjCloNYnuCMdpfaHRAKakeHZmXXiG54+eAiOarP28FUDXU+z0EbK+ ZutPiijykzLdvn9jR/uyFh4q24A/zyo4fGs6rLM4TOuTI+j2HaIhSCrq97OifU5YyPoo qDBQ== X-Gm-Message-State: AOJu0Yw2Xi5+X9CDxjeaQiAo8l/o3BNNd/Pdh0oCBYsJyKAkK+epW8G5 h5XVRNOGOn9yAa8OyS10Hg27RJB7iFj+e8h+Pc5XSohnHCzTzM0mdVyN X-Gm-Gg: AR+sD12DJQXE+gdpvONTWcoTT85Wbk6cTo9kuB2opCC4hZgEMwsF0Way7Zyju2yHN89 p2hmRsEEfX98tBtsRfWxHbEofrI9E4nHSDxREWzs5D/774U61V5mnSDeI/67LO2OsH3XuTV1Tmi tYqcu9LtjMXoXfOuZqP9t+ubMZIkGjIMmB9IdAn0afe18LuCwozFJQBW2MbC9zina/om0io14Yv OzjKCHEsX0rNoxCFmzh856tKOmussThXubZdXOQRD12Khc9HA+F7w+tpt5wD8Ft7hFBGhmoqaP4 cUy5FE8wxWOkIKeO+/ikDbiN8UfZ7qjtS74u3FrQhhghrm4RgfRLDg5PYlbYBA5cQZVSEp0IboO 6m7AWX4yZM2V3Xp05Utv+l5lu5HAKGXdB4hPzlplK9y6f8VyOR8IxLuLTnRVUt0i2Vg0E7LSFuB xZSCEaBOqvxJimWjyrg3PepBG4AtF1UQM3Bt//0fvkAIud/vfTZLaYzeSVrEAaIsxA7jtKITej+ MTEZ91O66NxB26lBR/UCPV6xDHL5DqrUiEsTqYO3Bm3fZ4DZ8YW X-Received: by 2002:a05:600c:470d:b0:495:7538:d4ea with SMTP id 5b1f17b1804b1-4980122085cmr40583505e9.0.1785423366435; Thu, 30 Jul 2026 07:56:06 -0700 (PDT) Received: from fedora ([105.190.201.81]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47fc88d985csm7257138f8f.1.2026.07.30.07.56.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jul 2026 07:56:06 -0700 (PDT) From: Jad Keskes To: linux-edac@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Borislav Petkov , Mauro Carvalho Chehab , Tony Luck , James Morse , Robert Richter , Jad Keskes Subject: [PATCH 2/2] EDAC/device: Serialize poll_msec store against device teardown Date: Thu, 30 Jul 2026 15:55:49 +0100 Message-ID: <20260730145549.148229-2-inasj268@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260730145549.148229-1-inasj268@gmail.com> References: <20260730145549.148229-1-inasj268@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit edac_device_reset_delay_period() unconditionally calls edac_mod_work() to re-arm the workqueue timer when the poll_msec sysfs attribute is written. This has two issues: 1) Interrupt-driven devices (op_state = OP_RUNNING_INTERRUPT) have no initialized workqueue, so calling edac_mod_work() would operate on uninitialized timer state. 2) A concurrent write to poll_msec during device removal can race with edac_device_del_device(). Even with an OP_OFFLINE state check, the check and edac_mod_work() are not atomic, allowing the workqueue to be re-armed after teardown. Fix both by holding device_ctls_mutex around the state check and edac_mod_work() call in reset_delay_period(), and moving the workqueue teardown inside the same mutex in del_device(). With the mutex held in both paths: - reset_delay_period() atomically verifies op_state == OP_RUNNING_POLL before re-arming; any other state skips the call entirely. - del_device() sets OP_OFFLINE and tears down the workqueue while holding the mutex, so any racing reset_delay_period() completes before teardown or sees OP_OFFLINE and bails. Also fix the parameter type from unsigned long to unsigned int to match the poll_msec field, and fix a latent bug where round_jiffies_relative() received a millisecond value instead of jiffies. Signed-off-by: Jad Keskes --- drivers/edac/edac_device.c | 15 +++++++++++---- drivers/edac/edac_module.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index 19522c568aa5..3fb4de3ed28c 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c @@ -394,17 +394,24 @@ static void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev) * Then restart the workq on the new delay */ void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev, - unsigned long value) + unsigned int value) { unsigned long jiffs = msecs_to_jiffies(value); if (value == 1000) - jiffs = round_jiffies_relative(value); + jiffs = round_jiffies_relative(jiffs); + + mutex_lock(&device_ctls_mutex); + if (edac_dev->op_state != OP_RUNNING_POLL) { + mutex_unlock(&device_ctls_mutex); + return; + } edac_dev->poll_msec = value; edac_dev->delay = jiffs; edac_mod_work(&edac_dev->work, jiffs); + mutex_unlock(&device_ctls_mutex); } int edac_device_alloc_index(void) @@ -492,11 +499,11 @@ struct edac_device_ctl_info *edac_device_del_device(struct device *dev) /* deregister from global list */ del_edac_device_from_global_list(edac_dev); - mutex_unlock(&device_ctls_mutex); - /* clear workq processing on this instance */ edac_device_workq_teardown(edac_dev); + mutex_unlock(&device_ctls_mutex); + /* Tear down the sysfs entries for this instance */ edac_device_remove_sysfs(edac_dev); diff --git a/drivers/edac/edac_module.h b/drivers/edac/edac_module.h index 96f6de0c8ff6..e03ec7daa64a 100644 --- a/drivers/edac/edac_module.h +++ b/drivers/edac/edac_module.h @@ -56,7 +56,7 @@ bool edac_stop_work(struct delayed_work *work); bool edac_mod_work(struct delayed_work *work, unsigned long delay); extern void edac_device_reset_delay_period(struct edac_device_ctl_info - *edac_dev, unsigned long value); + *edac_dev, unsigned int value); extern void edac_mc_reset_delay_period(unsigned long value); /* -- 2.55.0