aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiaoqing Pan <miaoqing@codeaurora.org>2016-03-18 05:54:56 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2016-04-04 10:07:28 -0400
commita2cb3d5f043e4cc646c396a3e188a171b38c15a0 (patch)
tree241f363eca151d521e9667a97a03404da736d8a8
parent69218a48005d0c93b8e9ec483f42ead481a43034 (diff)
ath9k: fix rng high cpu load
If no valid ADC randomness output, ath9k rng will continuously reading ADC, which will cause high CPU load. So increase the delay to wait for ADC ready. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114261 Signed-off-by: Miaoqing Pan <miaoqing@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/rng.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c
index c9cb2aad7b6f..d38e50f96db7 100644
--- a/drivers/net/wireless/ath/ath9k/rng.c
+++ b/drivers/net/wireless/ath/ath9k/rng.c
@@ -55,11 +55,26 @@ static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size)
55 return j << 2; 55 return j << 2;
56} 56}
57 57
58static u32 ath9k_rng_delay_get(u32 fail_stats)
59{
60 u32 delay;
61
62 if (fail_stats < 100)
63 delay = 10;
64 else if (fail_stats < 105)
65 delay = 1000;
66 else
67 delay = 10000;
68
69 return delay;
70}
71
58static int ath9k_rng_kthread(void *data) 72static int ath9k_rng_kthread(void *data)
59{ 73{
60 int bytes_read; 74 int bytes_read;
61 struct ath_softc *sc = data; 75 struct ath_softc *sc = data;
62 u32 *rng_buf; 76 u32 *rng_buf;
77 u32 delay, fail_stats = 0;
63 78
64 rng_buf = kmalloc_array(ATH9K_RNG_BUF_SIZE, sizeof(u32), GFP_KERNEL); 79 rng_buf = kmalloc_array(ATH9K_RNG_BUF_SIZE, sizeof(u32), GFP_KERNEL);
65 if (!rng_buf) 80 if (!rng_buf)
@@ -69,10 +84,13 @@ static int ath9k_rng_kthread(void *data)
69 bytes_read = ath9k_rng_data_read(sc, rng_buf, 84 bytes_read = ath9k_rng_data_read(sc, rng_buf,
70 ATH9K_RNG_BUF_SIZE); 85 ATH9K_RNG_BUF_SIZE);
71 if (unlikely(!bytes_read)) { 86 if (unlikely(!bytes_read)) {
72 msleep_interruptible(10); 87 delay = ath9k_rng_delay_get(++fail_stats);
88 msleep_interruptible(delay);
73 continue; 89 continue;
74 } 90 }
75 91
92 fail_stats = 0;
93
76 /* sleep until entropy bits under write_wakeup_threshold */ 94 /* sleep until entropy bits under write_wakeup_threshold */
77 add_hwgenerator_randomness((void *)rng_buf, bytes_read, 95 add_hwgenerator_randomness((void *)rng_buf, bytes_read,
78 ATH9K_RNG_ENTROPY(bytes_read)); 96 ATH9K_RNG_ENTROPY(bytes_read));