From: Mukesh Ojha <mojha@codeaurora.org>
To: Fabrice Gasnier <fabrice.gasnier@st.com>, jic23@kernel.org
Cc: lars@metafoo.de, alexandre.torgue@st.com,
linux-iio@vger.kernel.org, pmeerw@pmeerw.net,
linux-kernel@vger.kernel.org, mcoquelin.stm32@gmail.com,
knaack.h@gmx.de, linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] iio: adc: stm32: fix sleep inside atomic section when using DMA
Date: Wed, 27 Mar 2019 18:21:56 +0530 [thread overview]
Message-ID: <647777da-8077-6390-9778-08bef3d13074@codeaurora.org> (raw)
In-Reply-To: <1553604244-10922-1-git-send-email-fabrice.gasnier@st.com>
On 3/26/2019 6:14 PM, Fabrice Gasnier wrote:
> Enabling CONFIG_DEBUG_ATOMIC_SLEEP=y triggers this BUG message:
> BUG: sleeping function called from invalid context at kernel/irq/chip.c...
>
> Call stack is as follows:
> - __might_sleep
> - handle_nested_irq <-- Expects threaded irq
> - iio_trigger_poll_chained
> - stm32_adc_dma_buffer_done
> - vchan_complete
> - tasklet_action_common
> - tasklet_action
> - __do_softirq <-- DMA completion raises a tasklet
> - irq_exit
> - __handle_domain_irq <-- DMA IRQ
> - gic_handle_irq
>
> IIO expects threaded interrupt context when calling:
> - iio_trigger_poll_chained()
> Or it expects interrupt context when calling:
> - iio_trigger_poll()
>
> This patch triggers an IRQ upon stm32_adc_dma_buffer_done() DMA callback
> call, so the IIO trigger poll API gets called from IRQ context.
>
> Fixes: 2763ea0585c9 ("iio: adc: stm32: add optional dma support")
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Reviewed-by: Mukesh Ojha <mojha@codeaurora.org>
-Mukesh
> ---
> drivers/iio/adc/Kconfig | 1 +
> drivers/iio/adc/stm32-adc.c | 32 ++++++++++++++++++++++++++++++--
> 2 files changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 76db6e5..059407a 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -775,6 +775,7 @@ config STM32_ADC_CORE
> select MFD_STM32_TIMERS
> select IIO_STM32_TIMER_TRIGGER
> select IIO_TRIGGERED_BUFFER
> + select IRQ_WORK
> help
> Select this option to enable the core driver for STMicroelectronics
> STM32 analog-to-digital converter (ADC).
> diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
> index 205e169..1aa3189 100644
> --- a/drivers/iio/adc/stm32-adc.c
> +++ b/drivers/iio/adc/stm32-adc.c
> @@ -20,6 +20,7 @@
> #include <linux/interrupt.h>
> #include <linux/io.h>
> #include <linux/iopoll.h>
> +#include <linux/irq_work.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> @@ -297,6 +298,7 @@ struct stm32_adc_cfg {
> * @smpr_val: sampling time settings (e.g. smpr1 / smpr2)
> * @cal: optional calibration data on some devices
> * @chan_name: channel name array
> + * @work: irq work used to call trigger poll routine
> */
> struct stm32_adc {
> struct stm32_adc_common *common;
> @@ -320,6 +322,7 @@ struct stm32_adc {
> u32 smpr_val[2];
> struct stm32_adc_calib cal;
> char chan_name[STM32_ADC_CH_MAX][STM32_ADC_CH_SZ];
> + struct irq_work work;
> };
>
> struct stm32_adc_diff_channel {
> @@ -1473,11 +1476,32 @@ static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc)
> return 0;
> }
>
> +static void stm32_adc_dma_irq_work(struct irq_work *work)
> +{
> + struct stm32_adc *adc = container_of(work, struct stm32_adc, work);
> + struct iio_dev *indio_dev = iio_priv_to_dev(adc);
> +
> + /*
> + * iio_trigger_poll calls generic_handle_irq(). So, it requires hard
> + * irq context, and cannot be called directly from dma callback,
> + * dma cb has to schedule this work instead.
> + */
> + iio_trigger_poll(indio_dev->trig);
> +}
> +
> static void stm32_adc_dma_buffer_done(void *data)
> {
> struct iio_dev *indio_dev = data;
> + struct stm32_adc *adc = iio_priv(indio_dev);
>
> - iio_trigger_poll_chained(indio_dev->trig);
> + /*
> + * Invoques iio_trigger_poll() from hard irq context: We can't
> + * call iio_trigger_poll() nor iio_trigger_poll_chained()
> + * directly from DMA callback (under tasklet e.g. softirq).
> + * They require respectively HW IRQ and threaded IRQ context
> + * as it might sleep.
> + */
> + irq_work_queue(&adc->work);
> }
>
> static int stm32_adc_dma_start(struct iio_dev *indio_dev)
> @@ -1585,8 +1609,10 @@ static void __stm32_adc_buffer_predisable(struct iio_dev *indio_dev)
> if (!adc->dma_chan)
> stm32_adc_conv_irq_disable(adc);
>
> - if (adc->dma_chan)
> + if (adc->dma_chan) {
> dmaengine_terminate_all(adc->dma_chan);
> + irq_work_sync(&adc->work);
> + }
>
> if (stm32_adc_set_trig(indio_dev, NULL))
> dev_err(&indio_dev->dev, "Can't clear trigger\n");
> @@ -1872,6 +1898,8 @@ static int stm32_adc_dma_request(struct iio_dev *indio_dev)
> if (ret)
> goto err_free;
>
> + init_irq_work(&adc->work, stm32_adc_dma_irq_work);
> +
> return 0;
>
> err_free:
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-03-27 12:52 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-26 12:44 [PATCH] iio: adc: stm32: fix sleep inside atomic section when using DMA Fabrice Gasnier
2019-03-27 12:51 ` Mukesh Ojha [this message]
2019-03-27 13:22 ` Mukesh Ojha
2019-03-30 16:38 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=647777da-8077-6390-9778-08bef3d13074@codeaurora.org \
--to=mojha@codeaurora.org \
--cc=alexandre.torgue@st.com \
--cc=fabrice.gasnier@st.com \
--cc=jic23@kernel.org \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=pmeerw@pmeerw.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).