diff options
author | Theodore Ts'o <tytso@mit.edu> | 2013-10-03 12:02:37 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-10-10 14:32:23 -0400 |
commit | f80bbd8b92987f55f26691cd53785c4a54622eb0 (patch) | |
tree | 390c761123de9fe3784c147a01be2f3be8f7b7e0 | |
parent | 6265e169cd313d6f3aad3c33d0a5b0d9624f69f5 (diff) |
random: convert DEBUG_ENT to tracepoints
Instead of using the random driver's ad-hoc DEBUG_ENT() mechanism, use
tracepoints instead. This allows for a much more fine-grained control
of which debugging mechanism which a developer might need, and unifies
the debugging messages with all of the existing tracepoints.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | drivers/char/random.c | 52 | ||||
-rw-r--r-- | include/trace/events/random.h | 128 |
2 files changed, 144 insertions, 36 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 84c576ec20e9..f126bd2f69fe 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -404,17 +404,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); | |||
404 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); | 404 | static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); |
405 | static struct fasync_struct *fasync; | 405 | static struct fasync_struct *fasync; |
406 | 406 | ||
407 | static bool debug; | ||
408 | module_param(debug, bool, 0644); | ||
409 | #define DEBUG_ENT(fmt, arg...) do { \ | ||
410 | if (debug) \ | ||
411 | printk(KERN_DEBUG "random %04d %04d %04d: " \ | ||
412 | fmt,\ | ||
413 | input_pool.entropy_count,\ | ||
414 | blocking_pool.entropy_count,\ | ||
415 | nonblocking_pool.entropy_count,\ | ||
416 | ## arg); } while (0) | ||
417 | |||
418 | /********************************************************************** | 407 | /********************************************************************** |
419 | * | 408 | * |
420 | * OS independent entropy store. Here are the functions which handle | 409 | * OS independent entropy store. Here are the functions which handle |
@@ -612,7 +601,6 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits) | |||
612 | if (!nbits) | 601 | if (!nbits) |
613 | return; | 602 | return; |
614 | 603 | ||
615 | DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name); | ||
616 | retry: | 604 | retry: |
617 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); | 605 | entropy_count = orig = ACCESS_ONCE(r->entropy_count); |
618 | if (nfrac < 0) { | 606 | if (nfrac < 0) { |
@@ -655,7 +643,9 @@ retry: | |||
655 | } | 643 | } |
656 | 644 | ||
657 | if (entropy_count < 0) { | 645 | if (entropy_count < 0) { |
658 | DEBUG_ENT("negative entropy/overflow\n"); | 646 | pr_warn("random: negative entropy/overflow: pool %s count %d\n", |
647 | r->name, entropy_count); | ||
648 | WARN_ON(1); | ||
659 | entropy_count = 0; | 649 | entropy_count = 0; |
660 | } else if (entropy_count > pool_size) | 650 | } else if (entropy_count > pool_size) |
661 | entropy_count = pool_size; | 651 | entropy_count = pool_size; |
@@ -832,10 +822,10 @@ void add_input_randomness(unsigned int type, unsigned int code, | |||
832 | if (value == last_value) | 822 | if (value == last_value) |
833 | return; | 823 | return; |
834 | 824 | ||
835 | DEBUG_ENT("input event\n"); | ||
836 | last_value = value; | 825 | last_value = value; |
837 | add_timer_randomness(&input_timer_state, | 826 | add_timer_randomness(&input_timer_state, |
838 | (type << 4) ^ code ^ (code >> 4) ^ value); | 827 | (type << 4) ^ code ^ (code >> 4) ^ value); |
828 | trace_add_input_randomness(ENTROPY_BITS(&input_pool)); | ||
839 | } | 829 | } |
840 | EXPORT_SYMBOL_GPL(add_input_randomness); | 830 | EXPORT_SYMBOL_GPL(add_input_randomness); |
841 | 831 | ||
@@ -890,10 +880,8 @@ void add_disk_randomness(struct gendisk *disk) | |||
890 | if (!disk || !disk->random) | 880 | if (!disk || !disk->random) |
891 | return; | 881 | return; |
892 | /* first major is 1, so we get >= 0x200 here */ | 882 | /* first major is 1, so we get >= 0x200 here */ |
893 | DEBUG_ENT("disk event %d:%d\n", | ||
894 | MAJOR(disk_devt(disk)), MINOR(disk_devt(disk))); | ||
895 | |||
896 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); | 883 | add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); |
884 | trace_add_disk_randomness(disk_devt(disk), ENTROPY_BITS(&input_pool)); | ||
897 | } | 885 | } |
898 | #endif | 886 | #endif |
899 | 887 | ||
@@ -941,10 +929,8 @@ static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) | |||
941 | /* but never more than the buffer size */ | 929 | /* but never more than the buffer size */ |
942 | bytes = min_t(int, bytes, sizeof(tmp)); | 930 | bytes = min_t(int, bytes, sizeof(tmp)); |
943 | 931 | ||
944 | DEBUG_ENT("going to reseed %s with %d bits (%zu of %d requested)\n", | 932 | trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, |
945 | r->name, bytes * 8, nbytes * 8, | 933 | ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); |
946 | r->entropy_count >> ENTROPY_SHIFT); | ||
947 | |||
948 | bytes = extract_entropy(r->pull, tmp, bytes, | 934 | bytes = extract_entropy(r->pull, tmp, bytes, |
949 | random_read_wakeup_thresh / 8, rsvd); | 935 | random_read_wakeup_thresh / 8, rsvd); |
950 | mix_pool_bytes(r, tmp, bytes, NULL); | 936 | mix_pool_bytes(r, tmp, bytes, NULL); |
@@ -992,8 +978,6 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
992 | spin_lock_irqsave(&r->lock, flags); | 978 | spin_lock_irqsave(&r->lock, flags); |
993 | 979 | ||
994 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); | 980 | BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); |
995 | DEBUG_ENT("trying to extract %zu bits from %s\n", | ||
996 | nbytes * 8, r->name); | ||
997 | 981 | ||
998 | /* Can we pull enough? */ | 982 | /* Can we pull enough? */ |
999 | retry: | 983 | retry: |
@@ -1019,12 +1003,9 @@ retry: | |||
1019 | < random_write_wakeup_thresh) | 1003 | < random_write_wakeup_thresh) |
1020 | wakeup_write = 1; | 1004 | wakeup_write = 1; |
1021 | } | 1005 | } |
1022 | |||
1023 | DEBUG_ENT("debiting %zu entropy credits from %s%s\n", | ||
1024 | ibytes * 8, r->name, r->limit ? "" : " (unlimited)"); | ||
1025 | |||
1026 | spin_unlock_irqrestore(&r->lock, flags); | 1006 | spin_unlock_irqrestore(&r->lock, flags); |
1027 | 1007 | ||
1008 | trace_debit_entropy(r->name, 8 * ibytes); | ||
1028 | if (wakeup_write) { | 1009 | if (wakeup_write) { |
1029 | wake_up_interruptible(&random_write_wait); | 1010 | wake_up_interruptible(&random_write_wait); |
1030 | kill_fasync(&fasync, SIGIO, POLL_OUT); | 1011 | kill_fasync(&fasync, SIGIO, POLL_OUT); |
@@ -1303,8 +1284,6 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1303 | if (n > SEC_XFER_SIZE) | 1284 | if (n > SEC_XFER_SIZE) |
1304 | n = SEC_XFER_SIZE; | 1285 | n = SEC_XFER_SIZE; |
1305 | 1286 | ||
1306 | DEBUG_ENT("reading %zu bits\n", n*8); | ||
1307 | |||
1308 | n = extract_entropy_user(&blocking_pool, buf, n); | 1287 | n = extract_entropy_user(&blocking_pool, buf, n); |
1309 | 1288 | ||
1310 | if (n < 0) { | 1289 | if (n < 0) { |
@@ -1312,8 +1291,9 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1312 | break; | 1291 | break; |
1313 | } | 1292 | } |
1314 | 1293 | ||
1315 | DEBUG_ENT("read got %zd bits (%zd still needed)\n", | 1294 | trace_random_read(n*8, (nbytes-n)*8, |
1316 | n*8, (nbytes-n)*8); | 1295 | ENTROPY_BITS(&blocking_pool), |
1296 | ENTROPY_BITS(&input_pool)); | ||
1317 | 1297 | ||
1318 | if (n == 0) { | 1298 | if (n == 0) { |
1319 | if (file->f_flags & O_NONBLOCK) { | 1299 | if (file->f_flags & O_NONBLOCK) { |
@@ -1321,14 +1301,10 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1321 | break; | 1301 | break; |
1322 | } | 1302 | } |
1323 | 1303 | ||
1324 | DEBUG_ENT("sleeping?\n"); | ||
1325 | |||
1326 | wait_event_interruptible(random_read_wait, | 1304 | wait_event_interruptible(random_read_wait, |
1327 | ENTROPY_BITS(&input_pool) >= | 1305 | ENTROPY_BITS(&input_pool) >= |
1328 | random_read_wakeup_thresh); | 1306 | random_read_wakeup_thresh); |
1329 | 1307 | ||
1330 | DEBUG_ENT("awake\n"); | ||
1331 | |||
1332 | if (signal_pending(current)) { | 1308 | if (signal_pending(current)) { |
1333 | retval = -ERESTARTSYS; | 1309 | retval = -ERESTARTSYS; |
1334 | break; | 1310 | break; |
@@ -1350,7 +1326,11 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | |||
1350 | static ssize_t | 1326 | static ssize_t |
1351 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) | 1327 | urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) |
1352 | { | 1328 | { |
1353 | return extract_entropy_user(&nonblocking_pool, buf, nbytes); | 1329 | int ret = extract_entropy_user(&nonblocking_pool, buf, nbytes); |
1330 | |||
1331 | trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool), | ||
1332 | ENTROPY_BITS(&input_pool)); | ||
1333 | return ret; | ||
1354 | } | 1334 | } |
1355 | 1335 | ||
1356 | static unsigned int | 1336 | static unsigned int |
diff --git a/include/trace/events/random.h b/include/trace/events/random.h index 527b5dc1b416..805af6db41cc 100644 --- a/include/trace/events/random.h +++ b/include/trace/events/random.h | |||
@@ -109,6 +109,89 @@ TRACE_EVENT(push_to_pool, | |||
109 | __entry->input_bits) | 109 | __entry->input_bits) |
110 | ); | 110 | ); |
111 | 111 | ||
112 | TRACE_EVENT(debit_entropy, | ||
113 | TP_PROTO(const char *pool_name, int debit_bits), | ||
114 | |||
115 | TP_ARGS(pool_name, debit_bits), | ||
116 | |||
117 | TP_STRUCT__entry( | ||
118 | __field( const char *, pool_name ) | ||
119 | __field( int, debit_bits ) | ||
120 | ), | ||
121 | |||
122 | TP_fast_assign( | ||
123 | __entry->pool_name = pool_name; | ||
124 | __entry->debit_bits = debit_bits; | ||
125 | ), | ||
126 | |||
127 | TP_printk("%s: debit_bits %d", __entry->pool_name, | ||
128 | __entry->debit_bits) | ||
129 | ); | ||
130 | |||
131 | TRACE_EVENT(add_input_randomness, | ||
132 | TP_PROTO(int input_bits), | ||
133 | |||
134 | TP_ARGS(input_bits), | ||
135 | |||
136 | TP_STRUCT__entry( | ||
137 | __field( int, input_bits ) | ||
138 | ), | ||
139 | |||
140 | TP_fast_assign( | ||
141 | __entry->input_bits = input_bits; | ||
142 | ), | ||
143 | |||
144 | TP_printk("input_pool_bits %d", __entry->input_bits) | ||
145 | ); | ||
146 | |||
147 | TRACE_EVENT(add_disk_randomness, | ||
148 | TP_PROTO(dev_t dev, int input_bits), | ||
149 | |||
150 | TP_ARGS(dev, input_bits), | ||
151 | |||
152 | TP_STRUCT__entry( | ||
153 | __field( dev_t, dev ) | ||
154 | __field( int, input_bits ) | ||
155 | ), | ||
156 | |||
157 | TP_fast_assign( | ||
158 | __entry->dev = dev; | ||
159 | __entry->input_bits = input_bits; | ||
160 | ), | ||
161 | |||
162 | TP_printk("dev %d,%d input_pool_bits %d", MAJOR(__entry->dev), | ||
163 | MINOR(__entry->dev), __entry->input_bits) | ||
164 | ); | ||
165 | |||
166 | TRACE_EVENT(xfer_secondary_pool, | ||
167 | TP_PROTO(const char *pool_name, int xfer_bits, int request_bits, | ||
168 | int pool_entropy, int input_entropy), | ||
169 | |||
170 | TP_ARGS(pool_name, xfer_bits, request_bits, pool_entropy, | ||
171 | input_entropy), | ||
172 | |||
173 | TP_STRUCT__entry( | ||
174 | __field( const char *, pool_name ) | ||
175 | __field( int, xfer_bits ) | ||
176 | __field( int, request_bits ) | ||
177 | __field( int, pool_entropy ) | ||
178 | __field( int, input_entropy ) | ||
179 | ), | ||
180 | |||
181 | TP_fast_assign( | ||
182 | __entry->pool_name = pool_name; | ||
183 | __entry->xfer_bits = xfer_bits; | ||
184 | __entry->request_bits = request_bits; | ||
185 | __entry->pool_entropy = pool_entropy; | ||
186 | __entry->input_entropy = input_entropy; | ||
187 | ), | ||
188 | |||
189 | TP_printk("pool %s xfer_bits %d request_bits %d pool_entropy %d " | ||
190 | "input_entropy %d", __entry->pool_name, __entry->xfer_bits, | ||
191 | __entry->request_bits, __entry->pool_entropy, | ||
192 | __entry->input_entropy) | ||
193 | ); | ||
194 | |||
112 | DECLARE_EVENT_CLASS(random__get_random_bytes, | 195 | DECLARE_EVENT_CLASS(random__get_random_bytes, |
113 | TP_PROTO(int nbytes, unsigned long IP), | 196 | TP_PROTO(int nbytes, unsigned long IP), |
114 | 197 | ||
@@ -179,7 +262,52 @@ DEFINE_EVENT(random__extract_entropy, extract_entropy_user, | |||
179 | TP_ARGS(pool_name, nbytes, entropy_count, IP) | 262 | TP_ARGS(pool_name, nbytes, entropy_count, IP) |
180 | ); | 263 | ); |
181 | 264 | ||
265 | TRACE_EVENT(random_read, | ||
266 | TP_PROTO(int got_bits, int need_bits, int pool_left, int input_left), | ||
182 | 267 | ||
268 | TP_ARGS(got_bits, need_bits, pool_left, input_left), | ||
269 | |||
270 | TP_STRUCT__entry( | ||
271 | __field( int, got_bits ) | ||
272 | __field( int, need_bits ) | ||
273 | __field( int, pool_left ) | ||
274 | __field( int, input_left ) | ||
275 | ), | ||
276 | |||
277 | TP_fast_assign( | ||
278 | __entry->got_bits = got_bits; | ||
279 | __entry->need_bits = need_bits; | ||
280 | __entry->pool_left = pool_left; | ||
281 | __entry->input_left = input_left; | ||
282 | ), | ||
283 | |||
284 | TP_printk("got_bits %d still_needed_bits %d " | ||
285 | "blocking_pool_entropy_left %d input_entropy_left %d", | ||
286 | __entry->got_bits, __entry->got_bits, __entry->pool_left, | ||
287 | __entry->input_left) | ||
288 | ); | ||
289 | |||
290 | TRACE_EVENT(urandom_read, | ||
291 | TP_PROTO(int got_bits, int pool_left, int input_left), | ||
292 | |||
293 | TP_ARGS(got_bits, pool_left, input_left), | ||
294 | |||
295 | TP_STRUCT__entry( | ||
296 | __field( int, got_bits ) | ||
297 | __field( int, pool_left ) | ||
298 | __field( int, input_left ) | ||
299 | ), | ||
300 | |||
301 | TP_fast_assign( | ||
302 | __entry->got_bits = got_bits; | ||
303 | __entry->pool_left = pool_left; | ||
304 | __entry->input_left = input_left; | ||
305 | ), | ||
306 | |||
307 | TP_printk("got_bits %d nonblocking_pool_entropy_left %d " | ||
308 | "input_entropy_left %d", __entry->got_bits, | ||
309 | __entry->pool_left, __entry->input_left) | ||
310 | ); | ||
183 | 311 | ||
184 | #endif /* _TRACE_RANDOM_H */ | 312 | #endif /* _TRACE_RANDOM_H */ |
185 | 313 | ||