linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/1] crypto: dcp - add power management support
@ 2021-03-19  0:22 Dragos Rosioru (OSS)
  2021-03-19  0:22 ` [RFC 1/1] " Dragos Rosioru (OSS)
  0 siblings, 1 reply; 3+ messages in thread
From: Dragos Rosioru (OSS) @ 2021-03-19  0:22 UTC (permalink / raw)
  To: Herbert Xu, David S . Miller, Shawn Guo, Sascha Hauer,
	Fabio Estevam, Rafael J . Wysocki, Petr Mladek, Jiri Kosina,
	Luis Chamberlain
  Cc: Marek Vasut, Horia Geanta, Pengutronix Kernel Team,
	NXP Linux Team, linux-crypto, linux-arm-kernel, linux-kernel

From: Dragos Rosioru <dragos.rosioru@nxp.com>

This patch aims to enable PM support in the DCP driver.
The values for DCP Control and Channel Control registers had to be saved
and restored due to the fact that the DCP block would remain in a
low-power mode and have its clocks gated after suspend/resume cycles.

A simple test consisting of running tcrypt speed tests in background and
attempting to put the system in a sleep state(both shallow and deep)
was used.
The test failed due to inability to freeze the kernel threads.
Freezing of tasks failed after 20.015 seconds
(1 tasks refusing to freeze, wq_busy=0)
The solution for this issue was to use the kthread freezer by
calling try_to_freeze() on the processing threads.
Would this be considered a correct solution in this particular case
or should another approach, that does not rely on kthread freezer,
be taken?
In the later case, what would be the suggested option?

modprobe tcrypt mode=500 sec=1 &
pm_suspend.sh 1 &

[  171.648351] tcrypt: test 1 (128 bit key, 64 byte blocks): 2485 operations in 1 seconds (159040 bytes)
[  172.651560] tcrypt: test 2 (128 bit key, 256 byte blocks): 1523 operations in 1 seconds (389888 bytes)
...
PM_SUSPEND    0  TINFO  :  PM_SUSPEND: Test WAIT and STOP mode times: 0
freeze standby mem
rtc_testapp_6    0  TINFO  :  Open RTC device successfully: /dev/rtc

rtc_testapp_6    0  TINFO  : [  196.270268] tcrypt: test 5 (128 bit key, 4096 byte blocks):
ALARM TEST: RTC_ALM_SET & RTC_ALM_[  196.755624] PM: suspend entry (shallow)
READ
rtc_testapp_6    0  TINFO  :    Read date/time...
rtc_testapp_6    0  TINFO  :      Current RTC date/time is 2-1-1970, 17:50:59.
rtc_testapp_6    0  TINFO  :    Set the alarm to 30 seconds in the future...
rtc_testapp_6    0  TINFO  :      Enable alarm interrupts
rtc_testapp_6    0  TINFO  :    Waiting 30 seconds for alarm.......
[  196.824708] Filesystems sync: 0.054 seconds
[  197.066653] Freezing user space processes ...
...
[  209.401137] tcrypt:
[  209.401137] testing speed of async cbc(aes) (cbc-aes-dcp) encryption
[  209.411104] tcrypt: test 0 (128 bit key, 16 byte blocks): 3228 operations in 1 seconds (51648 bytes)
[  210.419875] tcrypt: test 1 (128 bit key, 64 byte blocks): 3232 operations in 1 seconds (206848 bytes)
...
[  216.480736] tcrypt: test 7 (192 bit key, 64 byte blocks): 110395 operations in 1 seconds (7065280 bytes)
[  217.489804]
[  217.491391] Freezing of tasks failed after 20.423 seconds (1 tasks refusing to freeze, wq_busy=0):
[  217.500725] task:modprobe        state:R  running task     stack:    0 pid:  482 ppid:   477 flags:0x00000001
[  217.511782] [<c0e44368>] (__schedule) from [<c0e44b38>] (preempt_schedule_common+0x28/0x44)
[  217.520458] [<c0e44b38>] (preempt_schedule_common) from [<c0e44b90>] (_cond_resched+0x3c/0x44)
[  217.529380] [<c0e44b90>] (_cond_resched) from [<bf0003ec>] (test_skcipher_speed+0x31c/0x590 [tcrypt])
[  217.538881] [<bf0003ec>] (test_skcipher_speed [tcrypt]) from [<bf004460>] (do_test+0x1bbc/0x42cc [tcrypt])
[  217.548918] [<bf004460>] (do_test [tcrypt]) from [<bf00d05c>] (tcrypt_mod_init+0x5c/0x1000 [tcrypt])
[  217.558434] [<bf00d05c>] (tcrypt_mod_init [tcrypt]) from [<c01022c4>] (do_one_initcall+0x84/0x3c4)
[  217.567726] [<c01022c4>] (do_one_initcall) from [<c01e603c>] (do_init_module+0x5c/0x280)
[  217.576128] [<c01e603c>] (do_init_module) from [<c01e8d98>] (sys_finit_module+0xb4/0xf4)
[  217.584533] [<c01e8d98>] (sys_finit_module) from [<c0100080>] (ret_fast_syscall+0x0/0x2c)
[  217.593010] Exception stack(0xc5099fa8 to 0xc5099ff0)
[  217.598157] 9fa0:                   00000000 00000000 00000003 00759210 00000000 00040000
[  217.606604] 9fc0: 00000000 00000000 00000000 0000017b 00759240 00759630 0000000e 00000000
[  217.615048] 9fe0: be8c68e0 be8c68d0 004bce0d b6f083d2
[  217.620349]
[  217.621919] OOM killer enabled.
[  217.625126] Restarting tasks ... done.
[  217.860270] PM: suspend exit
rtc_testapp_6    1  TFAIL  :  rtc_test_6.c:449: Suspend operation failed on mode standby, please check
rtc_testapp_6    0  TINFO  :  Exit suspend operation....
...
rtc_testapp_6    0  TINFO  :  Open RTC device success[  224.738516] PM: suspend entry (deep)
fully: /dev/rtc

rtc_testapp_6    0  TINFO  :  ALA[  224.747606] Filesystems sync: 0.002 seconds
RM TEST: RTC_ALM_SET & RTC_ALM_READ
rtc_testapp_6    0  TINFO  :    Read date/time...
rtc_testapp_6    0  TINFO  :      Current RTC date/time is 2-1-1970, 17:51:27.
rtc_testapp_6    0  TINFO  :    Set the alarm to 30 seconds in the future...
rtc_testapp_6    0  TINFO  :      Enable alarm interrupts
rtc_testapp_6    0  TINFO  :    Waiting 30 seconds for alarm.......
...
[  247.142469] testing speed of async xts(aes) (xts(ecb-aes-dcp)) encryption
[  247.153739] tcrypt: test 0 (256 bit key, 16 byte blocks): 2899 operations in 1 seconds (46384 bytes)
[  248.158437] tcrypt: test 1 (256 bit key, 64 byte blocks):
[  248.905430]
[  248.912762] Freezing of tasks failed after 20.011 seconds (1 tasks refusing to freeze, wq_busy=0):
[  248.922195] task:modprobe        state:D stack:    0 pid:  482 ppid:   477 flags:0x0000000                                                                                                1
[  248.930926] [<c0e44368>] (__schedule) from [<c0e449ec>] (schedule+0x90/0x118)
[  248.938189] [<c0e449ec>] (schedule) from [<c0e49ad8>] (schedule_timeout+0xcc/0x120)
[  248.946156] [<c0e49ad8>] (schedule_timeout) from [<c0e45a20>] (wait_for_completion+0x90/0xf8)
[  248.955006] [<c0e45a20>] (wait_for_completion) from [<bf006c58>] (crypto_wait_req+0x20/0x30 [tcrypt])
[  248.964599] [<bf006c58>] (crypto_wait_req [tcrypt]) from [<bf0003d8>] (test_skcipher_speed+0x308/0x590 [tcrypt])
[  248.975137] [<bf0003d8>] (test_skcipher_speed [tcrypt]) from [<bf0044d4>] (do_test+0x1c30/0x42cc [tcrypt])
[  248.985152] [<bf0044d4>] (do_test [tcrypt]) from [<bf00d05c>] (tcrypt_mod_init+0x5c/0x1000 [tcrypt])
[  248.994649] [<bf00d05c>] (tcrypt_mod_init [tcrypt]) from [<c01022c4>] (do_one_initcall+0x84/0x3c4)
[  249.003935] [<c01022c4>] (do_one_initcall) from [<c01e603c>] (do_init_module+0x5c/0x280)
[  249.012331] [<c01e603c>] (do_init_module) from [<c01e8d98>] (sys_finit_module+0xb4/0xf4)
[  249.020708] [<c01e8d98>] (sys_finit_module) from [<c0100080>] (ret_fast_syscall+0x0/0x2c)
[  249.029180] Exception stack(0xc5099fa8 to 0xc5099ff0)
[  249.034325] 9fa0:                   00000000 00000000 00000003 00759210 00000000 00040000
[  249.042767] 9fc0: 00000000 00000000 00000000 0000017b 00759240 00759630 0000000e 00000000
[  249.051205] 9fe0: be8c68e0 be8c68d0 004bce0d b6f083d2
[  249.056347]
[  249.057912] OOM killer enabled.
[  249.061582] Restarting tasks ...
[  249.149290] 2457 operations in 1 seconds (157248 bytes)
[  249.157967] tcrypt: test 2 (256 bit key, 256 byte blocks):[  249.397200] done.
[  249.445234] PM: suspend exit
rtc_testapp_6    1  TFAIL  :  rtc_test_6.c:449: Suspend operation failed on mode mem, please check

Dragos Rosioru (1):
  crypto: dcp - add power management support

 drivers/crypto/mxs-dcp.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 74 insertions(+), 2 deletions(-)

-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [RFC 1/1] crypto: dcp - add power management support
  2021-03-19  0:22 [RFC 0/1] crypto: dcp - add power management support Dragos Rosioru (OSS)
@ 2021-03-19  0:22 ` Dragos Rosioru (OSS)
  2021-03-26  7:16   ` Herbert Xu
  0 siblings, 1 reply; 3+ messages in thread
From: Dragos Rosioru (OSS) @ 2021-03-19  0:22 UTC (permalink / raw)
  To: Herbert Xu, David S . Miller, Shawn Guo, Sascha Hauer,
	Fabio Estevam, Rafael J . Wysocki, Petr Mladek, Jiri Kosina,
	Luis Chamberlain
  Cc: Marek Vasut, Horia Geanta, Pengutronix Kernel Team,
	NXP Linux Team, linux-crypto, linux-arm-kernel, linux-kernel

From: Dragos Rosioru <dragos.rosioru@nxp.com>

Added suspend/resume operations for PM support in the DCP driver.
After a suspend/resume cycle DCP would still be in a low-power mode
and have its clocks gated, thus requiring state to be saved beforehand:
- Control register value(DCP_CTRL)
- Channel control register value(DCP_CHANNELCTRL)

Signed-off-by: Dragos Rosioru <dragos.rosioru@nxp.com>
---
 drivers/crypto/mxs-dcp.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 74 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
index d6a7784..6748a4a 100644
--- a/drivers/crypto/mxs-dcp.c
+++ b/drivers/crypto/mxs-dcp.c
@@ -23,6 +23,10 @@
 #include <crypto/internal/skcipher.h>
 #include <crypto/scatterwalk.h>
 
+#ifdef CONFIG_PM_SLEEP
+#include <linux/freezer.h>
+#endif
+
 #define DCP_MAX_CHANS	4
 #define DCP_BUF_SZ	PAGE_SIZE
 #define DCP_SHA_PAY_SZ  64
@@ -124,7 +128,10 @@ struct dcp_export_state {
  * design of Linux Crypto API.
  */
 static struct dcp *global_sdcp;
-
+#ifdef CONFIG_PM_SLEEP
+static uint32_t ctrl_bak;
+static int dcp_vmi_irq_bak, dcp_irq_bak;
+#endif
 /* DCP register layout. */
 #define MXS_DCP_CTRL				0x00
 #define MXS_DCP_CTRL_GATHER_RESIDUAL_WRITES	(1 << 23)
@@ -398,9 +405,15 @@ static int dcp_chan_thread_aes(void *data)
 
 	int ret;
 
+#ifdef CONFIG_PM_SLEEP
+	set_freezable();
+#endif
 	while (!kthread_should_stop()) {
 		set_current_state(TASK_INTERRUPTIBLE);
 
+#ifdef CONFIG_PM_SLEEP
+		try_to_freeze();
+#endif
 		spin_lock(&sdcp->lock[chan]);
 		backlog = crypto_get_backlog(&sdcp->queue[chan]);
 		arq = crypto_dequeue_request(&sdcp->queue[chan]);
@@ -438,6 +451,10 @@ static int mxs_dcp_block_fallback(struct skcipher_request *req, int enc)
 	skcipher_request_set_crypt(&rctx->fallback_req, req->src, req->dst,
 				   req->cryptlen, req->iv);
 
+#ifdef CONFIG_PM_SLEEP
+	set_freezable();
+	try_to_freeze();
+#endif
 	if (enc)
 		ret = crypto_skcipher_encrypt(&rctx->fallback_req);
 	else
@@ -686,9 +703,15 @@ static int dcp_chan_thread_sha(void *data)
 	struct crypto_async_request *arq;
 	int ret;
 
+#ifdef CONFIG_PM_SLEEP
+	set_freezable();
+#endif
 	while (!kthread_should_stop()) {
 		set_current_state(TASK_INTERRUPTIBLE);
 
+#ifdef CONFIG_PM_SLEEP
+		try_to_freeze();
+#endif
 		spin_lock(&sdcp->lock[chan]);
 		backlog = crypto_get_backlog(&sdcp->queue[chan]);
 		arq = crypto_dequeue_request(&sdcp->queue[chan]);
@@ -961,6 +984,49 @@ static irqreturn_t mxs_dcp_irq(int irq, void *context)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int mxs_dcp_resume(struct device *dev)
+{
+	struct dcp *sdcp = global_sdcp;
+	int ret;
+
+	/* Restart the DCP block */
+	ret = stmp_reset_block(sdcp->base);
+	if (ret) {
+		dev_err(dev, "Failed reset\n");
+		clk_disable_unprepare(sdcp->dcp_clk);
+		return ret;
+	}
+
+	/* Restore control register */
+	writel(ctrl_bak, sdcp->base + MXS_DCP_CTRL);
+	/* Enable all DCP DMA channels */
+	writel(MXS_DCP_CHANNELCTRL_ENABLE_CHANNEL_MASK,
+	       sdcp->base + MXS_DCP_CHANNELCTRL);
+
+	/* Re-enable DCP interrupts */
+	enable_irq(dcp_irq_bak);
+	enable_irq(dcp_vmi_irq_bak);
+
+	return 0;
+}
+
+static int mxs_dcp_suspend(struct device *dev)
+{
+	struct dcp *sdcp = global_sdcp;
+
+	/* Backup control register */
+	ctrl_bak = readl(sdcp->base + MXS_DCP_CTRL);
+	/* Temporarily disable DCP interrupts */
+	disable_irq(dcp_irq_bak);
+	disable_irq(dcp_vmi_irq_bak);
+
+	return 0;
+}
+
+SIMPLE_DEV_PM_OPS(mxs_dcp_pm_ops, mxs_dcp_suspend, mxs_dcp_resume);
+#endif
+
 static int mxs_dcp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -980,7 +1046,10 @@ static int mxs_dcp_probe(struct platform_device *pdev)
 	dcp_irq = platform_get_irq(pdev, 1);
 	if (dcp_irq < 0)
 		return dcp_irq;
-
+#ifdef CONFIG_PM_SLEEP
+	dcp_vmi_irq_bak = dcp_vmi_irq;
+	dcp_irq_bak = dcp_irq;
+#endif
 	sdcp = devm_kzalloc(dev, sizeof(*sdcp), GFP_KERNEL);
 	if (!sdcp)
 		return -ENOMEM;
@@ -1172,6 +1241,9 @@ static struct platform_driver mxs_dcp_driver = {
 	.driver	= {
 		.name		= "mxs-dcp",
 		.of_match_table	= mxs_dcp_dt_ids,
+#ifdef CONFIG_PM_SLEEP
+		.pm = &mxs_dcp_pm_ops
+#endif
 	},
 };
 
-- 
2.7.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [RFC 1/1] crypto: dcp - add power management support
  2021-03-19  0:22 ` [RFC 1/1] " Dragos Rosioru (OSS)
@ 2021-03-26  7:16   ` Herbert Xu
  0 siblings, 0 replies; 3+ messages in thread
From: Herbert Xu @ 2021-03-26  7:16 UTC (permalink / raw)
  To: Dragos Rosioru (OSS)
  Cc: David S . Miller, Shawn Guo, Sascha Hauer, Fabio Estevam,
	Rafael J . Wysocki, Petr Mladek, Jiri Kosina, Luis Chamberlain,
	Marek Vasut, Horia Geanta, Pengutronix Kernel Team,
	NXP Linux Team, linux-crypto, linux-arm-kernel, linux-kernel

On Fri, Mar 19, 2021 at 02:22:57AM +0200, Dragos Rosioru (OSS) wrote:
> From: Dragos Rosioru <dragos.rosioru@nxp.com>
> 
> Added suspend/resume operations for PM support in the DCP driver.
> After a suspend/resume cycle DCP would still be in a low-power mode
> and have its clocks gated, thus requiring state to be saved beforehand:
> - Control register value(DCP_CTRL)
> - Channel control register value(DCP_CHANNELCTRL)
> 
> Signed-off-by: Dragos Rosioru <dragos.rosioru@nxp.com>
> ---
>  drivers/crypto/mxs-dcp.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 74 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c
> index d6a7784..6748a4a 100644
> --- a/drivers/crypto/mxs-dcp.c
> +++ b/drivers/crypto/mxs-dcp.c
> @@ -23,6 +23,10 @@
>  #include <crypto/internal/skcipher.h>
>  #include <crypto/scatterwalk.h>
>  
> +#ifdef CONFIG_PM_SLEEP
> +#include <linux/freezer.h>
> +#endif

Please find a way to rework this patch so that it's not full of
these ifdefs.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-03-26  7:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-19  0:22 [RFC 0/1] crypto: dcp - add power management support Dragos Rosioru (OSS)
2021-03-19  0:22 ` [RFC 1/1] " Dragos Rosioru (OSS)
2021-03-26  7:16   ` Herbert Xu

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).