From patchwork Tue Feb 13 18:10:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Abbott X-Patchwork-Id: 200546 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:bc8a:b0:106:860b:bbdd with SMTP id dn10csp717360dyb; Tue, 13 Feb 2024 10:11:06 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWINBQ+9OleUz9StfkRv/i5xlsJbjykdn2PXcGxtX53XqO/nvRMy4H1Jc/SIrVpyFlXt3SMB3FRjG8ixyfGBAHdw36zmg== X-Google-Smtp-Source: AGHT+IElZLzHEXFq/t+qdMvqwaBxEiuflBtm7hIrgqLDmvqIWjoBZGHd4yqpPtEK+sxR5bbJFj9c X-Received: by 2002:a05:620a:40ca:b0:785:ca44:278a with SMTP id g10-20020a05620a40ca00b00785ca44278amr372307qko.58.1707847866205; Tue, 13 Feb 2024 10:11:06 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707847866; cv=pass; d=google.com; s=arc-20160816; b=f2YVGDegNWgLFSKu/TexmOeSbBKIv/LDXY5TtZCd7dmqWfahA6kOz6qhoVxNLXWVay MrvtTNRTiLaiS6/ntIU6jYYG3PWU/bcO+BmBz4bwfQ2mzRgDR5BjAVW4L5ult78aOnTq mhCwP3vQpjWx3ScUhP6PdWrjdva9lGOWwrfkEs//i5lQvgmCYxxJQSmDtKxXIHzw8F/C ydBwnGQTBlWVUipZcayF5FRiP5ujXNJe/WiJGkgt5amxZnBXs+wg+iBN6ozqJhNUnRRm l4odiKMyoecxlJOTp8G83/rZ9zpX7FlADWuxqlxqs6cNvxu0rW3jWKQrhWJujByB4EB4 Tu/g== 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:message-id:date:subject:cc:to :from:dkim-signature; bh=hAxom2fpaOzsVKiYwPOFiIHf5ir7JuqKcxjXsAGRotE=; fh=UyOH6RbNXfpahRNKr7xu/CBlsLdzZynbBJCDIR6jQLo=; b=izWyXCqyfx18t70B2Pxlv/GzUoRCJp3TIJQEoDXHHiE0BihlFYwBI3h0dt45xanBFj jGdD+JceoZD2pJVkhrCca/Cc2mTLMftz1OXpU3uJBMlWMkTjU1EJmKvfkbubyKLkCHTC 61Qai2IAH4o8Gh9MGckkJeNydHZisXjcBzM6rpcp9x+aWmuNeD32ClYhs8F8iwgasclb Y3PdvwqYq19vDaICYL/No441uhfWAFkwdJhpiT5JktX6rB1tS2IOkHmeCbLqRNRMw7gq AdOoheFWLjbzP46/j+7kQYK5dwJSor0D3HRIKdQ4GdXmZaC7/JqZOnrZiWBGtkWnRwGd lLRg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@mev.co.uk header.s=20221208-6x11dpa4 header.b=SHOGLMNv; 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-64061-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-64061-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=mev.co.uk X-Forwarded-Encrypted: i=2; AJvYcCXWegUkG8lQC/kMGUNcwEMWNy1Gh81U6jDo5LqKdW8stavbk9UP/ZbDmtIk6z/HthW4PVfwB+KOv+K5FaDYwNvP+qeilQ== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id c21-20020a05620a201500b0078585f1ecdcsi8498853qka.360.2024.02.13.10.11.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Feb 2024 10:11:06 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-64061-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@mev.co.uk header.s=20221208-6x11dpa4 header.b=SHOGLMNv; 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-64061-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-64061-ouuuleilei=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 ny.mirrors.kernel.org (Postfix) with ESMTPS id 68B8B1C2318B for ; Tue, 13 Feb 2024 18:10:59 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1A998605B3; Tue, 13 Feb 2024 18:10:31 +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="SHOGLMNv" Received: from smtp102.iad3a.emailsrvr.com (smtp102.iad3a.emailsrvr.com [173.203.187.102]) (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 BEF96605B1 for ; Tue, 13 Feb 2024 18:10:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=173.203.187.102 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707847827; cv=none; b=oofjfHTMs6NX8QclPJHMr5oZWwVr++xDJmUl+OBx3da3PT5i7xW7xbE0fmmNImmZu3xycPb3zK66et33TmmlOZphIPo5dkmhtWyK2lfNsVnh4q6a9MksMg5iIeFnt6+dHiWTIZUpOzuNQfe9yvUfLisu8GdSQBIZJp4ntOC9mrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707847827; c=relaxed/simple; bh=pjbuxl8oRQ0+R+g36gg/gBcvAmBulWkgzcftiFFzEzc=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=dm6aXamRHG+rU3texM2N93VpMgzmVuNVabt+v+einzTdhr1uvUbL7XqQC1WJDikSv15777kZ7awAbOAc/ylCw4DVa9dbHsth7IN71AYSamtbVnKXllTdVsRySocXUdmNi8ww7bvQH6GlFSKc7U1txyaTWrd/ymq1GRiveHvyNy0= 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=SHOGLMNv; arc=none smtp.client-ip=173.203.187.102 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=1707847819; bh=pjbuxl8oRQ0+R+g36gg/gBcvAmBulWkgzcftiFFzEzc=; h=From:To:Subject:Date:From; b=SHOGLMNv4peTulwzUKMCjCrkHdXPCQtzjvUY+5UrWYuajT9QGy2WRexnZM/yWArAs 21aO1AbTAWmhXg5Lg/qSCLLVS0pIOi7DZqaQAvQ0Djju3ofC7QTy8OqCeqGP9QpdHn aeoxWzuP+LDqrC8kd8TdHGRMBD6rl2Xi28slCsXQ= X-Auth-ID: abbotti@mev.co.uk Received: by smtp29.relay.iad3a.emailsrvr.com (Authenticated sender: abbotti-AT-mev.co.uk) with ESMTPSA id 4D98124EB0; Tue, 13 Feb 2024 13:10:18 -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] comedi: comedi_test: Prevent timers rescheduling during deletion Date: Tue, 13 Feb 2024 18:10:04 +0000 Message-ID: <20240213181004.105072-1-abbotti@mev.co.uk> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Classification-ID: 969d28ca-18e8-4879-92d9-b2ffe5639bd8-1-1 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790808284002029523 X-GMAIL-MSGID: 1790808284002029523 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 --- drivers/comedi/drivers/comedi_test.c | 37 +++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 30ea8b53ebf8..7fefe0de0bcc 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]; }; @@ -232,12 +234,18 @@ static void waveform_ai_timer(struct timer_list *t) if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) { async->events |= COMEDI_CB_EOA; } else { + unsigned long flags; + if (devpriv->ai_convert_time > now) time_increment = devpriv->ai_convert_time - now; else time_increment = 1; - mod_timer(&devpriv->ai_timer, - jiffies + usecs_to_jiffies(time_increment)); + spin_lock_irqsave(&dev->spinlock, flags); + if (devpriv->ai_timer_enable) { + mod_timer(&devpriv->ai_timer, + jiffies + usecs_to_jiffies(time_increment)); + } + spin_unlock_irqrestore(&dev->spinlock, flags); } overrun: @@ -352,6 +360,7 @@ static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_cmd *cmd = &s->async->cmd; unsigned int first_convert_time; u64 wf_current; + unsigned long flags; if (cmd->flags & CMDF_PRIORITY) { dev_err(dev->class_dev, @@ -393,9 +402,12 @@ static int waveform_ai_cmd(struct comedi_device *dev, * Seem to need an extra jiffy here, otherwise timer expires slightly * early! */ + spin_lock_irqsave(&dev->spinlock, flags); + 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_irqrestore(&dev->spinlock, flags); return 0; } @@ -403,7 +415,11 @@ static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct waveform_private *devpriv = dev->private; + unsigned long flags; + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->ai_timer_enable = false; + spin_unlock_irqrestore(&dev->spinlock, flags); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ai_timer); @@ -494,9 +510,14 @@ static void waveform_ao_timer(struct timer_list *t) } else { unsigned int time_inc = devpriv->ao_last_scan_time + devpriv->ao_scan_period - now; + unsigned long flags; - mod_timer(&devpriv->ao_timer, - jiffies + usecs_to_jiffies(time_inc)); + spin_lock_irqsave(&dev->spinlock, flags); + if (devpriv->ao_timer_enable) { + mod_timer(&devpriv->ao_timer, + jiffies + usecs_to_jiffies(time_inc)); + } + spin_unlock_irqrestore(&dev->spinlock, flags); } underrun: @@ -510,6 +531,7 @@ static int waveform_ao_inttrig_start(struct comedi_device *dev, struct waveform_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; + unsigned long flags; if (trig_num != cmd->start_arg) return -EINVAL; @@ -517,9 +539,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_irqsave(&dev->spinlock, flags); + devpriv->ao_timer_enable = true; devpriv->ao_timer.expires = jiffies + usecs_to_jiffies(devpriv->ao_scan_period); add_timer(&devpriv->ao_timer); + spin_unlock_irqrestore(&dev->spinlock, flags); return 1; } @@ -602,8 +627,12 @@ static int waveform_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct waveform_private *devpriv = dev->private; + unsigned long flags; s->async->inttrig = NULL; + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->ao_timer_enable = false; + spin_unlock_irqrestore(&dev->spinlock, flags); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ao_timer);