Received: by 2002:a05:7412:2a91:b0:fc:a2b0:25d7 with SMTP id u17csp488686rdh; Wed, 14 Feb 2024 03:05:05 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUhOyfAofueTOYRU+rpL+Umos7xYW/wT9AqCkPecOBxZzMpIJzJs3qTNux/TX5UFzA1xgoZM0jKa86wvuErEUsgxkazcwQPDduASdYu2w== X-Google-Smtp-Source: AGHT+IHho7eig+Av5ej9MmxsSD4cIuRK03oveU3e+1Kxx2LQgNNztxM134kVtAu+s2sHgKTT4jLa X-Received: by 2002:aa7:9831:0:b0:6e0:8057:b2aa with SMTP id q17-20020aa79831000000b006e08057b2aamr1716790pfl.28.1707908704813; Wed, 14 Feb 2024 03:05:04 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707908704; cv=pass; d=google.com; s=arc-20160816; b=wolUCiSULYT1dxTRb7tjBtJs2bdIjUkrWT7HCjjXzSrHYB5HXXYrE7esZW3/0Yb1bh X/KVzFUrMPNvmexIIfgO/oA+B9U4pjCnMf9zhxIio5SA4kwu88g2QnZFjNrtni/uR5id TONi8l7U5dtKxShEJx06XG+svlx8gikOlWu7dDqMH7rO7tOujX1lW0vxJemaSAwBGS02 GoX50ex3IwlOty82EMXPQD/0wBvvFLHoMMK3lDPdKuV+MfRopI3sJubYKuDPNcjkzuZw J2zSE5MrGrKRVVtQktVy12nEXpSs/Bv4clfRx4dqAzQoiw2eLqv1jopIGVeoha4lad0M qooA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=zIiSCO0ufCQNhkPOVx50fCzadempFftheGS0Cre/qhw=; fh=GOiHYYqxOFyosBv7ZOgrO257dQ9GHGZoBhhqzrwiG6s=; b=K3EiauMc8wfORJe9XQALkP2a21UkIK6pDPZ3JTzllPuOpu3+gxTeqGS1qxd/163MYL 0R9A1cGIsW7Yes4jjwVebSlZMLPdR9m7gy+MMg9/qu53HQ7pUADtaOpymjn2FojYYb3Y MpZ+2N7vUHqlyFXx++UKyaXLa48keluDCV6X4tVzXOZkGki4ap5rzotmpueWsRK3Izlc JKEQlv4CBr2RDoatmdT/K2/5WgOPA027kCcGqmlthlvecZqVkZb4rmOSDZpmRj53omcN ZiyZ461OWJ01RrS5XUHAEkSVVzHawDIzJimQJBrJIHH/T1oOc4o/fVZS7PZcN5fKzLCd OLuQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@mev.co.uk header.s=20221208-6x11dpa4 header.b=vzUQ30EA; arc=pass (i=1 spf=pass spfdomain=mev.co.uk dkim=pass dkdomain=mev.co.uk dmarc=pass fromdomain=mev.co.uk); spf=pass (google.com: domain of linux-kernel+bounces-65075-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-65075-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=mev.co.uk X-Forwarded-Encrypted: i=2; AJvYcCW0BDXpML4ylvPRXqMkuXucZGvIw5I6mRGZyEsDZgTOPkEIShLCSOjNIccYn2lCNnYhV/TIVR71A+cXk32DsHFLwltL0nNbScMmSQ62og== Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id cp16-20020a056a00349000b006dbd19a0a0asi8601439pfb.185.2024.02.14.03.05.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Feb 2024 03:05:04 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-65075-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@mev.co.uk header.s=20221208-6x11dpa4 header.b=vzUQ30EA; arc=pass (i=1 spf=pass spfdomain=mev.co.uk dkim=pass dkdomain=mev.co.uk dmarc=pass fromdomain=mev.co.uk); spf=pass (google.com: domain of linux-kernel+bounces-65075-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-65075-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=mev.co.uk Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 838B9B284C7 for ; Wed, 14 Feb 2024 10:46:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4FFC518633; Wed, 14 Feb 2024 10:46:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mev.co.uk header.i=@mev.co.uk header.b="vzUQ30EA" Received: from smtp75.ord1d.emailsrvr.com (smtp75.ord1d.emailsrvr.com [184.106.54.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B54A114297 for ; Wed, 14 Feb 2024 10:46:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=184.106.54.75 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707907608; cv=none; b=av+tb4k0otLR+9igMQI1ULhme44KWF7zVdOwKGLBa6UEPR/xnPaQBjhIWYG5HpTFtf0qhLoE+dM7qxdVYI4O4Ya4qydJhslU0akBLImXD/dQ9sz5jhZU2l/8q4IQJf10X+odP1tghcKpaCXCwEmrK5yJtdE/YVFOEHbSaz4lYm4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707907608; c=relaxed/simple; bh=A/Wp/xcNVQglirA7W8fEyBnFOSJzJ+nmZV5D9Jsfm64=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IDoh6beEFCleM10M/1p2ysPxRR4U4G2mN6hvHXnQSa0tbnjD1a2HCjxp8TM6RP2/LcJzRFKw8uZOn7aLgaq2+FbH5sSNriMqzmh8RMXmfXO5Yd99Pre+D/10mrIfSWrreJjrZBHtQjgMoSesYHwUo6qsDABIBGX++ZaF5HWjumA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mev.co.uk; spf=pass smtp.mailfrom=mev.co.uk; dkim=pass (1024-bit key) header.d=mev.co.uk header.i=@mev.co.uk header.b=vzUQ30EA; arc=none smtp.client-ip=184.106.54.75 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=mev.co.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mev.co.uk DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mev.co.uk; s=20221208-6x11dpa4; t=1707905287; bh=A/Wp/xcNVQglirA7W8fEyBnFOSJzJ+nmZV5D9Jsfm64=; h=From:To:Subject:Date:From; b=vzUQ30EANgsjwShEqLhVDKDeb51yvsremF6e5v+bxaGEesKzqnD5VhohB+QnNMPvF kW3XKYWAZCJtTJlaKQhz0d0z6Uktw0I0mflHPuQOGShcQs5VTh+1xYnLXb3/50XAQ2 FoBBTRWjo7O4pzHMK8cGfDmYv3MEdFHeycQGqDiw= X-Auth-ID: abbotti@mev.co.uk Received: by smtp2.relay.ord1d.emailsrvr.com (Authenticated sender: abbotti-AT-mev.co.uk) with ESMTPSA id 07102200B5; Wed, 14 Feb 2024 05:08:06 -0500 (EST) From: Ian Abbott To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , Ian Abbott , H Hartley Sweeten , stable@vger.kernel.org Subject: [PATCH v2] comedi: comedi_test: Prevent timers rescheduling during deletion Date: Wed, 14 Feb 2024 10:07:25 +0000 Message-ID: <20240214100747.16203-1-abbotti@mev.co.uk> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240213181004.105072-1-abbotti@mev.co.uk> References: <20240213181004.105072-1-abbotti@mev.co.uk> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Classification-ID: 985f1548-0da3-4956-9f19-7cf2aaea3395-1-1 The comedi_test devices have a couple of timers (ai_timer and ao_timer) that can be started to simulate hardware interrupts. Their expiry functions normally reschedule the timer. The driver code calls either del_timer_sync() or del_timer() to delete the timers from the queue, but does not currently prevent the timers from rescheduling themselves so synchronized deletion may be ineffective. Add a couple of boolean members (one for each timer: ai_timer_enable and ao_timer_enable) to the device private data structure to indicate whether the timers are allowed to reschedule themselves. Set the member to true when adding the timer to the queue, and to false when deleting the timer from the queue in the waveform_ai_cancel() and waveform_ao_cancel() functions. The del_timer_sync() function is also called from the waveform_detach() function, but the timer enable members will already be set to false when that function is called, so no change is needed there. Fixes: 403fe7f34e33 ("staging: comedi: comedi_test: fix timer race conditions") Cc: # 4.4+ Signed-off-by: Ian Abbott --- v2: Use spin_lock_bh() instead of spin_lock_irqsave(). --- drivers/comedi/drivers/comedi_test.c | 30 ++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 30ea8b53ebf8..05ae9122823f 100644 --- a/drivers/comedi/drivers/comedi_test.c +++ b/drivers/comedi/drivers/comedi_test.c @@ -87,6 +87,8 @@ struct waveform_private { struct comedi_device *dev; /* parent comedi device */ u64 ao_last_scan_time; /* time of previous AO scan in usec */ unsigned int ao_scan_period; /* AO scan period in usec */ + bool ai_timer_enable:1; /* should AI timer be running? */ + bool ao_timer_enable:1; /* should AO timer be running? */ unsigned short ao_loopbacks[N_CHANS]; }; @@ -236,8 +238,12 @@ static void waveform_ai_timer(struct timer_list *t) time_increment = devpriv->ai_convert_time - now; else time_increment = 1; - mod_timer(&devpriv->ai_timer, - jiffies + usecs_to_jiffies(time_increment)); + spin_lock(&dev->spinlock); + if (devpriv->ai_timer_enable) { + mod_timer(&devpriv->ai_timer, + jiffies + usecs_to_jiffies(time_increment)); + } + spin_unlock(&dev->spinlock); } overrun: @@ -393,9 +399,12 @@ static int waveform_ai_cmd(struct comedi_device *dev, * Seem to need an extra jiffy here, otherwise timer expires slightly * early! */ + spin_lock_bh(&dev->spinlock); + devpriv->ai_timer_enable = true; devpriv->ai_timer.expires = jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1; add_timer(&devpriv->ai_timer); + spin_unlock_bh(&dev->spinlock); return 0; } @@ -404,6 +413,9 @@ static int waveform_ai_cancel(struct comedi_device *dev, { struct waveform_private *devpriv = dev->private; + spin_lock_bh(&dev->spinlock); + devpriv->ai_timer_enable = false; + spin_unlock_bh(&dev->spinlock); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ai_timer); @@ -495,8 +507,12 @@ static void waveform_ao_timer(struct timer_list *t) unsigned int time_inc = devpriv->ao_last_scan_time + devpriv->ao_scan_period - now; - mod_timer(&devpriv->ao_timer, - jiffies + usecs_to_jiffies(time_inc)); + spin_lock(&dev->spinlock); + if (devpriv->ao_timer_enable) { + mod_timer(&devpriv->ao_timer, + jiffies + usecs_to_jiffies(time_inc)); + } + spin_unlock(&dev->spinlock); } underrun: @@ -517,9 +533,12 @@ static int waveform_ao_inttrig_start(struct comedi_device *dev, async->inttrig = NULL; devpriv->ao_last_scan_time = ktime_to_us(ktime_get()); + spin_lock_bh(&dev->spinlock); + devpriv->ao_timer_enable = true; devpriv->ao_timer.expires = jiffies + usecs_to_jiffies(devpriv->ao_scan_period); add_timer(&devpriv->ao_timer); + spin_unlock_bh(&dev->spinlock); return 1; } @@ -604,6 +623,9 @@ static int waveform_ao_cancel(struct comedi_device *dev, struct waveform_private *devpriv = dev->private; s->async->inttrig = NULL; + spin_lock_bh(&dev->spinlock); + devpriv->ao_timer_enable = false; + spin_unlock_bh(&dev->spinlock); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ao_timer); -- 2.43.0