From nobody Thu Sep 19 00:18:04 2024 Received: from mail-ed1-f45.google.com (mail-ed1-f45.google.com [209.85.208.45]) (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 126D014EC4B for ; Fri, 26 Jul 2024 20:00:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722024009; cv=none; b=FxoovdRD/pV3+53IZ4XPl2hcgB7jELYZd85S+LFViCAE25kWSNwl+WaCSnxsuZUkqukcir1XTQRD2i3KRulJ9YOklhG1n6po5yvFBYPKlg/nSYwHxB6rw0MmBP/JKaNVfAwRZE6X4Uc3VZby2uJKNZo4NHUVtgRbZ1lxEPwFdoM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722024009; c=relaxed/simple; bh=J14Wge9LcsEa7FQuC1M+/lsG9UZ/eoPKBj1txE0yej8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jTAqnYL9lISGIfMWoKxkUv5YdFtsCA+WCZ/uJz6P37IlIDMGJVpY/U4TvJken5fsvIA94W0bReG2vtbPVGPk4B937gMP0l3xRpqXNltx2QfUrPF7m9tjzZHKqXD5pOQWjTGkWySjBGGNVECHPvrLNibCLOFjg4/LYFIEWJJlMD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=yUFpBD0v; arc=none smtp.client-ip=209.85.208.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="yUFpBD0v" Received: by mail-ed1-f45.google.com with SMTP id 4fb4d7f45d1cf-5a309d1a788so2838647a12.3 for ; Fri, 26 Jul 2024 13:00:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1722024005; x=1722628805; 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; bh=CvEzDkwz6VWUUds2tie0+9vVLaqnWTgyheAACKxwxaM=; b=yUFpBD0v/GYuTjQmepxGGNxZrGzoRuOL+oz4PzCVuJwCRpzuwkErlQy/xZXsjTg0ny GtLcy/wbqJvxrm5+38f7bdGDJgI2dQEi+c/9WtZV5aqSWZwwMOzZhxKWtCnrSfj51bIs XnkY+o1XFWKzYOOxDf+Jtb+vF4ngbj7qyPykc8Bax9F1Qw1KXGe+7oh5S9sXXlINtmo8 +wgggMjsCcSRHKso1+U7U06nyHr0jvMSMccZOF/tbh5J1cYCO8wFBqtBraObjc2o6jWZ N91H/0FVb0YV4fuRoHJBjDMS5+roRiNZXdqYJ4wqHYp3wnCCerZi4O5OIYa+stLCBzeh CqNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722024005; x=1722628805; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CvEzDkwz6VWUUds2tie0+9vVLaqnWTgyheAACKxwxaM=; b=azbv3xmtANueznRO6CTMR1cmJEp84xOpBShx1gAhRQoK+RQJOM1TMBTQNi7fhDIGNR VVG1a9poN6U+1W9596UnfpH9xJxRg9p/iVv9rxQJ+auX1RqVuyuK5lotg9lZ6ULp8hjw 2Nq0+OREOttXac4AH1APUhCJD3OBdklES5VUDY/4VHvfC0YRQOuj0hOTS0TacSbXqtBi MyXep3kq0CKLc9cn018gthIb8/jujknUGx2cPr6W8RqBrcd0y8S9lKV/lRj6kXAR75CS h2Lu20sEOPRoOn2RbN9K3BMP1EwNYdeHo7c4JwmTjo5l5Dh2Z9ykBrTcKx652B/Fsz29 3ozw== X-Forwarded-Encrypted: i=1; AJvYcCWD+qYkEnrkEFByUzeY1cdXboeMHKWZI5ddpzXurykHRg3Zsn+KlTZ37+5NQ3+e2Je3cmvenKKgqMxsw6XjRSQU5Woe3troPthMBF62 X-Gm-Message-State: AOJu0YyOhaFjvb3KvXmbJ+7mmGvtUrrs3Y20NI8edwJoKwh40GFQh4TB 7n8RFjL4yH1qBRylUxZRmeBHheXJb43OoZjPLagIxA/EKIrxYaSuqLo1lROftIQ= X-Google-Smtp-Source: AGHT+IEoDGkSOlQQ1HqCH1hfBsQQjAOrogps53xCogk84g3vmjMcSvrVqFKhcBtYalOd4BgYXx9pIg== X-Received: by 2002:a17:907:9409:b0:a7a:b1a5:21a6 with SMTP id a640c23a62f3a-a7d400a037amr42049766b.33.1722024005422; Fri, 26 Jul 2024 13:00:05 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a245:8609:c1c4:a4f8:94c8:31f2]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a7acad90e1esm209999166b.151.2024.07.26.13.00.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Jul 2024 13:00:05 -0700 (PDT) From: Markus Schneider-Pargmann To: Chandrasekar Ramakrishnan , Marc Kleine-Budde , Vincent Mailhol , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Markus Schneider-Pargmann , =?UTF-8?q?Martin=20Hundeb=C3=B8ll?= , Michal Kubiak , Simon Horman , Tony Lindgren , Judith Mendez Cc: Matthias Schiffer , Linux regression tracking , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/7] can: m_can: Do not cancel timer from within timer Date: Fri, 26 Jul 2024 21:59:41 +0200 Message-ID: <20240726195944.2414812-5-msp@baylibre.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240726195944.2414812-1-msp@baylibre.com> References: <20240726195944.2414812-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On setups without interrupts, the interrupt handler is called from a timer callback. For non-peripheral receives napi is scheduled, interrupts are disabled and the timer is canceled with a blocking call. In case of an error this can happen as well. Check if napi is scheduled in the timer callback after the interrupt handler executed. If napi is scheduled, the timer is disabled. It will be reenabled by m_can_poll(). Return error values from the interrupt handler so that interrupt threads and timer callback can deal differently with it. In case of the timer we only disable the timer. The rest will be done when stopping the interface. Fixes: b382380c0d2d ("can: m_can: Add hrtimer to generate software interrup= t") Fixes: a163c5761019 ("can: m_can: Start/Cancel polling timer together with = interrupts") Signed-off-by: Markus Schneider-Pargmann --- drivers/net/can/m_can/m_can.c | 58 ++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 42ed7f0fea78..e70c7100a3c9 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -487,7 +487,7 @@ static inline void m_can_disable_all_interrupts(struct = m_can_classdev *cdev) =20 if (!cdev->net->irq) { dev_dbg(cdev->dev, "Stop hrtimer\n"); - hrtimer_cancel(&cdev->hrtimer); + hrtimer_try_to_cancel(&cdev->hrtimer); } } =20 @@ -1201,11 +1201,16 @@ static void m_can_coalescing_update(struct m_can_cl= assdev *cdev, u32 ir) HRTIMER_MODE_REL); } =20 -static irqreturn_t m_can_isr(int irq, void *dev_id) +/** + * This interrupt handler is called either from the interrupt thread or a + * hrtimer. This has implications like cancelling a timer won't be possible + * blocking. + */ +static int m_can_interrupt_handler(struct m_can_classdev *cdev) { - struct net_device *dev =3D (struct net_device *)dev_id; - struct m_can_classdev *cdev =3D netdev_priv(dev); + struct net_device *dev =3D cdev->net; u32 ir; + int ret; =20 if (pm_runtime_suspended(cdev->dev)) return IRQ_NONE; @@ -1232,11 +1237,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) m_can_disable_all_interrupts(cdev); napi_schedule(&cdev->napi); } else { - int pkts; - - pkts =3D m_can_rx_handler(dev, NAPI_POLL_WEIGHT, ir); - if (pkts < 0) - goto out_fail; + ret =3D m_can_rx_handler(dev, NAPI_POLL_WEIGHT, ir); + if (ret < 0) + return ret; } } =20 @@ -1254,8 +1257,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) } else { if (ir & (IR_TEFN | IR_TEFW)) { /* New TX FIFO Element arrived */ - if (m_can_echo_tx_event(dev) !=3D 0) - goto out_fail; + ret =3D m_can_echo_tx_event(dev); + if (ret !=3D 0) + return ret; } } =20 @@ -1263,16 +1267,31 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) can_rx_offload_threaded_irq_finish(&cdev->offload); =20 return IRQ_HANDLED; +} =20 -out_fail: - m_can_disable_all_interrupts(cdev); - return IRQ_HANDLED; +static irqreturn_t m_can_isr(int irq, void *dev_id) +{ + struct net_device *dev =3D (struct net_device *)dev_id; + struct m_can_classdev *cdev =3D netdev_priv(dev); + int ret; + + ret =3D m_can_interrupt_handler(cdev); + if (ret < 0) { + m_can_disable_all_interrupts(cdev); + return IRQ_HANDLED; + } + + return ret; } =20 static enum hrtimer_restart m_can_coalescing_timer(struct hrtimer *timer) { struct m_can_classdev *cdev =3D container_of(timer, struct m_can_classdev= , hrtimer); =20 + if (cdev->can.state =3D=3D CAN_STATE_BUS_OFF || + cdev->can.state =3D=3D CAN_STATE_STOPPED) + return HRTIMER_NORESTART; + irq_wake_thread(cdev->net->irq, cdev->net); =20 return HRTIMER_NORESTART; @@ -1973,8 +1992,17 @@ static enum hrtimer_restart hrtimer_callback(struct = hrtimer *timer) { struct m_can_classdev *cdev =3D container_of(timer, struct m_can_classdev, hrtimer); + int ret; =20 - m_can_isr(0, cdev->net); + if (cdev->can.state =3D=3D CAN_STATE_BUS_OFF || + cdev->can.state =3D=3D CAN_STATE_STOPPED) + return HRTIMER_NORESTART; + + ret =3D m_can_interrupt_handler(cdev); + + /* On error or if napi is scheduled to read, stop the timer */ + if (ret < 0 || napi_is_scheduled(&cdev->napi)) + return HRTIMER_NORESTART; =20 hrtimer_forward_now(timer, ms_to_ktime(HRTIMER_POLL_INTERVAL_MS)); =20 --=20 2.45.2