diff options
Diffstat (limited to 'net/tipc/dbg.c')
| -rw-r--r-- | net/tipc/dbg.c | 136 |
1 files changed, 89 insertions, 47 deletions
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index 55130655e1ed..d8af4c28695d 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * net/tipc/dbg.c: TIPC print buffer routines for debuggign | 2 | * net/tipc/dbg.c: TIPC print buffer routines for debugging |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 1996-2006, Ericsson AB | 4 | * Copyright (c) 1996-2006, Ericsson AB |
| 5 | * Copyright (c) 2005, Wind River Systems | 5 | * Copyright (c) 2005-2006, Wind River Systems |
| 6 | * All rights reserved. | 6 | * All rights reserved. |
| 7 | * | 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
| @@ -38,11 +38,12 @@ | |||
| 38 | #include "config.h" | 38 | #include "config.h" |
| 39 | #include "dbg.h" | 39 | #include "dbg.h" |
| 40 | 40 | ||
| 41 | #define MAX_STRING 512 | 41 | static char print_string[TIPC_PB_MAX_STR]; |
| 42 | |||
| 43 | static char print_string[MAX_STRING]; | ||
| 44 | static DEFINE_SPINLOCK(print_lock); | 42 | static DEFINE_SPINLOCK(print_lock); |
| 45 | 43 | ||
| 44 | static struct print_buf null_buf = { NULL, 0, NULL, NULL }; | ||
| 45 | struct print_buf *TIPC_NULL = &null_buf; | ||
| 46 | |||
| 46 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; | 47 | static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; |
| 47 | struct print_buf *TIPC_CONS = &cons_buf; | 48 | struct print_buf *TIPC_CONS = &cons_buf; |
| 48 | 49 | ||
| @@ -62,68 +63,83 @@ struct print_buf *TIPC_LOG = &log_buf; | |||
| 62 | /* | 63 | /* |
| 63 | * Locking policy when using print buffers. | 64 | * Locking policy when using print buffers. |
| 64 | * | 65 | * |
| 65 | * 1) Routines of the form printbuf_XXX() rely on the caller to prevent | 66 | * The following routines use 'print_lock' for protection: |
| 66 | * simultaneous use of the print buffer(s) being manipulated. | 67 | * 1) tipc_printf() - to protect its print buffer(s) and 'print_string' |
| 67 | * 2) tipc_printf() uses 'print_lock' to prevent simultaneous use of | 68 | * 2) TIPC_TEE() - to protect its print buffer(s) |
| 68 | * 'print_string' and to protect its print buffer(s). | 69 | * 3) tipc_dump() - to protect its print buffer(s) and 'print_string' |
| 69 | * 3) TIPC_TEE() uses 'print_lock' to protect its print buffer(s). | 70 | * 4) tipc_log_XXX() - to protect TIPC_LOG |
| 70 | * 4) Routines of the form log_XXX() uses 'print_lock' to protect TIPC_LOG. | 71 | * |
| 72 | * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent | ||
| 73 | * simultaneous use of the print buffer(s) being manipulated. | ||
| 71 | */ | 74 | */ |
| 72 | 75 | ||
| 73 | /** | 76 | /** |
| 74 | * tipc_printbuf_init - initialize print buffer to empty | 77 | * tipc_printbuf_init - initialize print buffer to empty |
| 78 | * @pb: pointer to print buffer structure | ||
| 79 | * @raw: pointer to character array used by print buffer | ||
| 80 | * @size: size of character array | ||
| 81 | * | ||
| 82 | * Makes the print buffer a null device that discards anything written to it | ||
| 83 | * if the character array is too small (or absent). | ||
| 75 | */ | 84 | */ |
| 76 | 85 | ||
| 77 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 sz) | 86 | void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) |
| 78 | { | 87 | { |
| 79 | if (!pb || !raw || (sz < (MAX_STRING + 1))) | 88 | pb->buf = raw; |
| 80 | return; | 89 | pb->crs = raw; |
| 81 | 90 | pb->size = size; | |
| 82 | pb->crs = pb->buf = raw; | ||
| 83 | pb->size = sz; | ||
| 84 | pb->next = NULL; | 91 | pb->next = NULL; |
| 85 | pb->buf[0] = 0; | 92 | |
| 86 | pb->buf[sz-1] = ~0; | 93 | if (size < TIPC_PB_MIN_SIZE) { |
| 94 | pb->buf = NULL; | ||
| 95 | } else if (raw) { | ||
| 96 | pb->buf[0] = 0; | ||
| 97 | pb->buf[size-1] = ~0; | ||
| 98 | } | ||
| 87 | } | 99 | } |
| 88 | 100 | ||
| 89 | /** | 101 | /** |
| 90 | * tipc_printbuf_reset - reinitialize print buffer to empty state | 102 | * tipc_printbuf_reset - reinitialize print buffer to empty state |
| 103 | * @pb: pointer to print buffer structure | ||
| 91 | */ | 104 | */ |
| 92 | 105 | ||
| 93 | void tipc_printbuf_reset(struct print_buf *pb) | 106 | void tipc_printbuf_reset(struct print_buf *pb) |
| 94 | { | 107 | { |
| 95 | if (pb && pb->buf) | 108 | tipc_printbuf_init(pb, pb->buf, pb->size); |
| 96 | tipc_printbuf_init(pb, pb->buf, pb->size); | ||
| 97 | } | 109 | } |
| 98 | 110 | ||
| 99 | /** | 111 | /** |
| 100 | * tipc_printbuf_empty - test if print buffer is in empty state | 112 | * tipc_printbuf_empty - test if print buffer is in empty state |
| 113 | * @pb: pointer to print buffer structure | ||
| 114 | * | ||
| 115 | * Returns non-zero if print buffer is empty. | ||
| 101 | */ | 116 | */ |
| 102 | 117 | ||
| 103 | int tipc_printbuf_empty(struct print_buf *pb) | 118 | int tipc_printbuf_empty(struct print_buf *pb) |
| 104 | { | 119 | { |
| 105 | return (!pb || !pb->buf || (pb->crs == pb->buf)); | 120 | return (!pb->buf || (pb->crs == pb->buf)); |
| 106 | } | 121 | } |
| 107 | 122 | ||
| 108 | /** | 123 | /** |
| 109 | * tipc_printbuf_validate - check for print buffer overflow | 124 | * tipc_printbuf_validate - check for print buffer overflow |
| 125 | * @pb: pointer to print buffer structure | ||
| 110 | * | 126 | * |
| 111 | * Verifies that a print buffer has captured all data written to it. | 127 | * Verifies that a print buffer has captured all data written to it. |
| 112 | * If data has been lost, linearize buffer and prepend an error message | 128 | * If data has been lost, linearize buffer and prepend an error message |
| 113 | * | 129 | * |
| 114 | * Returns length of print buffer data string (including trailing NULL) | 130 | * Returns length of print buffer data string (including trailing NUL) |
| 115 | */ | 131 | */ |
| 116 | 132 | ||
| 117 | int tipc_printbuf_validate(struct print_buf *pb) | 133 | int tipc_printbuf_validate(struct print_buf *pb) |
| 118 | { | 134 | { |
| 119 | char *err = " *** PRINT BUFFER WRAPPED AROUND ***\n"; | 135 | char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n"; |
| 120 | char *cp_buf; | 136 | char *cp_buf; |
| 121 | struct print_buf cb; | 137 | struct print_buf cb; |
| 122 | 138 | ||
| 123 | if (!pb || !pb->buf) | 139 | if (!pb->buf) |
| 124 | return 0; | 140 | return 0; |
| 125 | 141 | ||
| 126 | if (pb->buf[pb->size - 1] == '\0') { | 142 | if (pb->buf[pb->size - 1] == 0) { |
| 127 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); | 143 | cp_buf = kmalloc(pb->size, GFP_ATOMIC); |
| 128 | if (cp_buf != NULL){ | 144 | if (cp_buf != NULL){ |
| 129 | tipc_printbuf_init(&cb, cp_buf, pb->size); | 145 | tipc_printbuf_init(&cb, cp_buf, pb->size); |
| @@ -141,6 +157,8 @@ int tipc_printbuf_validate(struct print_buf *pb) | |||
| 141 | 157 | ||
| 142 | /** | 158 | /** |
| 143 | * tipc_printbuf_move - move print buffer contents to another print buffer | 159 | * tipc_printbuf_move - move print buffer contents to another print buffer |
| 160 | * @pb_to: pointer to destination print buffer structure | ||
| 161 | * @pb_from: pointer to source print buffer structure | ||
| 144 | * | 162 | * |
| 145 | * Current contents of destination print buffer (if any) are discarded. | 163 | * Current contents of destination print buffer (if any) are discarded. |
| 146 | * Source print buffer becomes empty if a successful move occurs. | 164 | * Source print buffer becomes empty if a successful move occurs. |
| @@ -152,21 +170,22 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
| 152 | 170 | ||
| 153 | /* Handle the cases where contents can't be moved */ | 171 | /* Handle the cases where contents can't be moved */ |
| 154 | 172 | ||
| 155 | if (!pb_to || !pb_to->buf) | 173 | if (!pb_to->buf) |
| 156 | return; | 174 | return; |
| 157 | 175 | ||
| 158 | if (!pb_from || !pb_from->buf) { | 176 | if (!pb_from->buf) { |
| 159 | tipc_printbuf_reset(pb_to); | 177 | tipc_printbuf_reset(pb_to); |
| 160 | return; | 178 | return; |
| 161 | } | 179 | } |
| 162 | 180 | ||
| 163 | if (pb_to->size < pb_from->size) { | 181 | if (pb_to->size < pb_from->size) { |
| 164 | tipc_printbuf_reset(pb_to); | 182 | tipc_printbuf_reset(pb_to); |
| 165 | tipc_printf(pb_to, "*** PRINT BUFFER OVERFLOW ***"); | 183 | tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***"); |
| 166 | return; | 184 | return; |
| 167 | } | 185 | } |
| 168 | 186 | ||
| 169 | /* Copy data from char after cursor to end (if used) */ | 187 | /* Copy data from char after cursor to end (if used) */ |
| 188 | |||
| 170 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; | 189 | len = pb_from->buf + pb_from->size - pb_from->crs - 2; |
| 171 | if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { | 190 | if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { |
| 172 | strcpy(pb_to->buf, pb_from->crs + 1); | 191 | strcpy(pb_to->buf, pb_from->crs + 1); |
| @@ -175,6 +194,7 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
| 175 | pb_to->crs = pb_to->buf; | 194 | pb_to->crs = pb_to->buf; |
| 176 | 195 | ||
| 177 | /* Copy data from start to cursor (always) */ | 196 | /* Copy data from start to cursor (always) */ |
| 197 | |||
| 178 | len = pb_from->crs - pb_from->buf; | 198 | len = pb_from->crs - pb_from->buf; |
| 179 | strcpy(pb_to->crs, pb_from->buf); | 199 | strcpy(pb_to->crs, pb_from->buf); |
| 180 | pb_to->crs += len; | 200 | pb_to->crs += len; |
| @@ -184,6 +204,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) | |||
| 184 | 204 | ||
| 185 | /** | 205 | /** |
| 186 | * tipc_printf - append formatted output to print buffer chain | 206 | * tipc_printf - append formatted output to print buffer chain |
| 207 | * @pb: pointer to chain of print buffers (may be NULL) | ||
| 208 | * @fmt: formatted info to be printed | ||
| 187 | */ | 209 | */ |
| 188 | 210 | ||
| 189 | void tipc_printf(struct print_buf *pb, const char *fmt, ...) | 211 | void tipc_printf(struct print_buf *pb, const char *fmt, ...) |
| @@ -195,8 +217,8 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
| 195 | 217 | ||
| 196 | spin_lock_bh(&print_lock); | 218 | spin_lock_bh(&print_lock); |
| 197 | FORMAT(print_string, chars_to_add, fmt); | 219 | FORMAT(print_string, chars_to_add, fmt); |
| 198 | if (chars_to_add >= MAX_STRING) | 220 | if (chars_to_add >= TIPC_PB_MAX_STR) |
| 199 | strcpy(print_string, "*** STRING TOO LONG ***"); | 221 | strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); |
| 200 | 222 | ||
| 201 | while (pb) { | 223 | while (pb) { |
| 202 | if (pb == TIPC_CONS) | 224 | if (pb == TIPC_CONS) |
| @@ -206,6 +228,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
| 206 | if (chars_to_add <= chars_left) { | 228 | if (chars_to_add <= chars_left) { |
| 207 | strcpy(pb->crs, print_string); | 229 | strcpy(pb->crs, print_string); |
| 208 | pb->crs += chars_to_add; | 230 | pb->crs += chars_to_add; |
| 231 | } else if (chars_to_add >= (pb->size - 1)) { | ||
| 232 | strcpy(pb->buf, print_string + chars_to_add + 1 | ||
| 233 | - pb->size); | ||
| 234 | pb->crs = pb->buf + pb->size - 1; | ||
| 209 | } else { | 235 | } else { |
| 210 | strcpy(pb->buf, print_string + chars_left); | 236 | strcpy(pb->buf, print_string + chars_left); |
| 211 | save_char = print_string[chars_left]; | 237 | save_char = print_string[chars_left]; |
| @@ -224,6 +250,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...) | |||
| 224 | 250 | ||
| 225 | /** | 251 | /** |
| 226 | * TIPC_TEE - perform next output operation on both print buffers | 252 | * TIPC_TEE - perform next output operation on both print buffers |
| 253 | * @b0: pointer to chain of print buffers (may be NULL) | ||
| 254 | * @b1: pointer to print buffer to add to chain | ||
| 255 | * | ||
| 256 | * Returns pointer to print buffer chain. | ||
| 227 | */ | 257 | */ |
| 228 | 258 | ||
| 229 | struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) | 259 | struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) |
| @@ -232,8 +262,6 @@ struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1) | |||
| 232 | 262 | ||
| 233 | if (!b0 || (b0 == b1)) | 263 | if (!b0 || (b0 == b1)) |
| 234 | return b1; | 264 | return b1; |
| 235 | if (!b1) | ||
| 236 | return b0; | ||
| 237 | 265 | ||
| 238 | spin_lock_bh(&print_lock); | 266 | spin_lock_bh(&print_lock); |
| 239 | while (pb->next) { | 267 | while (pb->next) { |
| @@ -256,7 +284,7 @@ static void print_to_console(char *crs, int len) | |||
| 256 | int rest = len; | 284 | int rest = len; |
| 257 | 285 | ||
| 258 | while (rest > 0) { | 286 | while (rest > 0) { |
| 259 | int sz = rest < MAX_STRING ? rest : MAX_STRING; | 287 | int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR; |
| 260 | char c = crs[sz]; | 288 | char c = crs[sz]; |
| 261 | 289 | ||
| 262 | crs[sz] = 0; | 290 | crs[sz] = 0; |
| @@ -275,36 +303,48 @@ static void printbuf_dump(struct print_buf *pb) | |||
| 275 | { | 303 | { |
| 276 | int len; | 304 | int len; |
| 277 | 305 | ||
| 306 | if (!pb->buf) { | ||
| 307 | printk("*** PRINT BUFFER NOT ALLOCATED ***"); | ||
| 308 | return; | ||
| 309 | } | ||
| 310 | |||
| 278 | /* Dump print buffer from char after cursor to end (if used) */ | 311 | /* Dump print buffer from char after cursor to end (if used) */ |
| 312 | |||
| 279 | len = pb->buf + pb->size - pb->crs - 2; | 313 | len = pb->buf + pb->size - pb->crs - 2; |
| 280 | if ((pb->buf[pb->size - 1] == 0) && (len > 0)) | 314 | if ((pb->buf[pb->size - 1] == 0) && (len > 0)) |
| 281 | print_to_console(pb->crs + 1, len); | 315 | print_to_console(pb->crs + 1, len); |
| 282 | 316 | ||
| 283 | /* Dump print buffer from start to cursor (always) */ | 317 | /* Dump print buffer from start to cursor (always) */ |
| 318 | |||
| 284 | len = pb->crs - pb->buf; | 319 | len = pb->crs - pb->buf; |
| 285 | print_to_console(pb->buf, len); | 320 | print_to_console(pb->buf, len); |
| 286 | } | 321 | } |
| 287 | 322 | ||
| 288 | /** | 323 | /** |
| 289 | * tipc_dump - dump non-console print buffer(s) to console | 324 | * tipc_dump - dump non-console print buffer(s) to console |
| 325 | * @pb: pointer to chain of print buffers | ||
| 290 | */ | 326 | */ |
| 291 | 327 | ||
| 292 | void tipc_dump(struct print_buf *pb, const char *fmt, ...) | 328 | void tipc_dump(struct print_buf *pb, const char *fmt, ...) |
| 293 | { | 329 | { |
| 330 | struct print_buf *pb_next; | ||
| 294 | int len; | 331 | int len; |
| 295 | 332 | ||
| 296 | spin_lock_bh(&print_lock); | 333 | spin_lock_bh(&print_lock); |
| 297 | FORMAT(TIPC_CONS->buf, len, fmt); | 334 | FORMAT(print_string, len, fmt); |
| 298 | printk(TIPC_CONS->buf); | 335 | printk(print_string); |
| 299 | 336 | ||
| 300 | for (; pb; pb = pb->next) { | 337 | for (; pb; pb = pb->next) { |
| 301 | if (pb == TIPC_CONS) | 338 | if (pb != TIPC_CONS) { |
| 302 | continue; | 339 | printk("\n---- Start of %s log dump ----\n\n", |
| 303 | printk("\n---- Start of dump,%s log ----\n\n", | 340 | (pb == TIPC_LOG) ? "global" : "local"); |
| 304 | (pb == TIPC_LOG) ? "global" : "local"); | 341 | printbuf_dump(pb); |
| 305 | printbuf_dump(pb); | 342 | tipc_printbuf_reset(pb); |
| 306 | tipc_printbuf_reset(pb); | 343 | printk("\n---- End of dump ----\n"); |
| 307 | printk("\n-------- End of dump --------\n"); | 344 | } |
| 345 | pb_next = pb->next; | ||
| 346 | pb->next = NULL; | ||
| 347 | pb = pb_next; | ||
| 308 | } | 348 | } |
| 309 | spin_unlock_bh(&print_lock); | 349 | spin_unlock_bh(&print_lock); |
| 310 | } | 350 | } |
| @@ -324,7 +364,8 @@ void tipc_log_stop(void) | |||
| 324 | } | 364 | } |
| 325 | 365 | ||
| 326 | /** | 366 | /** |
| 327 | * tipc_log_reinit - set TIPC log print buffer to specified size | 367 | * tipc_log_reinit - (re)initialize TIPC log print buffer |
| 368 | * @log_size: print buffer size to use | ||
| 328 | */ | 369 | */ |
| 329 | 370 | ||
| 330 | void tipc_log_reinit(int log_size) | 371 | void tipc_log_reinit(int log_size) |
| @@ -332,10 +373,11 @@ void tipc_log_reinit(int log_size) | |||
| 332 | tipc_log_stop(); | 373 | tipc_log_stop(); |
| 333 | 374 | ||
| 334 | if (log_size) { | 375 | if (log_size) { |
| 335 | if (log_size <= MAX_STRING) | 376 | if (log_size < TIPC_PB_MIN_SIZE) |
| 336 | log_size = MAX_STRING + 1; | 377 | log_size = TIPC_PB_MIN_SIZE; |
| 337 | spin_lock_bh(&print_lock); | 378 | spin_lock_bh(&print_lock); |
| 338 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size); | 379 | tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), |
| 380 | log_size); | ||
| 339 | spin_unlock_bh(&print_lock); | 381 | spin_unlock_bh(&print_lock); |
| 340 | } | 382 | } |
| 341 | } | 383 | } |
