diff options
-rw-r--r-- | drivers/char/hw_random/core.c | 12 | ||||
-rw-r--r-- | include/linux/hw_random.h | 3 |
2 files changed, 5 insertions, 10 deletions
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 6ec42252e46e..3dba2cf50241 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c | |||
@@ -60,7 +60,6 @@ static DEFINE_MUTEX(rng_mutex); | |||
60 | static DEFINE_MUTEX(reading_mutex); | 60 | static DEFINE_MUTEX(reading_mutex); |
61 | static int data_avail; | 61 | static int data_avail; |
62 | static u8 *rng_buffer, *rng_fillbuf; | 62 | static u8 *rng_buffer, *rng_fillbuf; |
63 | static DECLARE_WAIT_QUEUE_HEAD(rng_done); | ||
64 | static unsigned short current_quality; | 63 | static unsigned short current_quality; |
65 | static unsigned short default_quality; /* = 0; default to "off" */ | 64 | static unsigned short default_quality; /* = 0; default to "off" */ |
66 | 65 | ||
@@ -100,10 +99,7 @@ static inline void cleanup_rng(struct kref *kref) | |||
100 | if (rng->cleanup) | 99 | if (rng->cleanup) |
101 | rng->cleanup(rng); | 100 | rng->cleanup(rng); |
102 | 101 | ||
103 | /* cleanup_done should be updated after cleanup finishes */ | 102 | complete(&rng->cleanup_done); |
104 | smp_wmb(); | ||
105 | rng->cleanup_done = true; | ||
106 | wake_up_all(&rng_done); | ||
107 | } | 103 | } |
108 | 104 | ||
109 | static void set_current_rng(struct hwrng *rng) | 105 | static void set_current_rng(struct hwrng *rng) |
@@ -498,7 +494,7 @@ int hwrng_register(struct hwrng *rng) | |||
498 | add_early_randomness(rng); | 494 | add_early_randomness(rng); |
499 | } | 495 | } |
500 | 496 | ||
501 | rng->cleanup_done = false; | 497 | init_completion(&rng->cleanup_done); |
502 | 498 | ||
503 | out_unlock: | 499 | out_unlock: |
504 | mutex_unlock(&rng_mutex); | 500 | mutex_unlock(&rng_mutex); |
@@ -532,9 +528,7 @@ void hwrng_unregister(struct hwrng *rng) | |||
532 | } else | 528 | } else |
533 | mutex_unlock(&rng_mutex); | 529 | mutex_unlock(&rng_mutex); |
534 | 530 | ||
535 | /* Just in case rng is reading right now, wait. */ | 531 | wait_for_completion(&rng->cleanup_done); |
536 | wait_event(rng_done, rng->cleanup_done && | ||
537 | atomic_read(&rng->ref.refcount) == 0); | ||
538 | } | 532 | } |
539 | EXPORT_SYMBOL_GPL(hwrng_unregister); | 533 | EXPORT_SYMBOL_GPL(hwrng_unregister); |
540 | 534 | ||
diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h index 7832e5008959..eb7b414d232b 100644 --- a/include/linux/hw_random.h +++ b/include/linux/hw_random.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #ifndef LINUX_HWRANDOM_H_ | 12 | #ifndef LINUX_HWRANDOM_H_ |
13 | #define LINUX_HWRANDOM_H_ | 13 | #define LINUX_HWRANDOM_H_ |
14 | 14 | ||
15 | #include <linux/completion.h> | ||
15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
16 | #include <linux/list.h> | 17 | #include <linux/list.h> |
17 | #include <linux/kref.h> | 18 | #include <linux/kref.h> |
@@ -46,7 +47,7 @@ struct hwrng { | |||
46 | /* internal. */ | 47 | /* internal. */ |
47 | struct list_head list; | 48 | struct list_head list; |
48 | struct kref ref; | 49 | struct kref ref; |
49 | bool cleanup_done; | 50 | struct completion cleanup_done; |
50 | }; | 51 | }; |
51 | 52 | ||
52 | /** Register a new Hardware Random Number Generator driver. */ | 53 | /** Register a new Hardware Random Number Generator driver. */ |