aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/core.h7
-rw-r--r--net/tipc/dbg.c163
-rw-r--r--net/tipc/dbg.h4
3 files changed, 80 insertions, 94 deletions
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 325404fd4eb5..7042ef377262 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -66,7 +66,6 @@
66 66
67struct tipc_msg; 67struct tipc_msg;
68extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG; 68extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG;
69extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *);
70void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*); 69void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*);
71void tipc_printf(struct print_buf *, const char *fmt, ...); 70void tipc_printf(struct print_buf *, const char *fmt, ...);
72void tipc_dump(struct print_buf*,const char *fmt, ...); 71void tipc_dump(struct print_buf*,const char *fmt, ...);
@@ -98,11 +97,13 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
98 * TIPC_CONS : system console 97 * TIPC_CONS : system console
99 * TIPC_LOG : TIPC log buffer 98 * TIPC_LOG : TIPC log buffer
100 * &buf : user-defined buffer (struct print_buf *) 99 * &buf : user-defined buffer (struct print_buf *)
101 * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG)) 100 *
101 * Note: TIPC_LOG is configured to echo its output to the system console;
102 * user-defined buffers can be configured to do the same thing.
102 */ 103 */
103 104
104#ifndef TIPC_OUTPUT 105#ifndef TIPC_OUTPUT
105#define TIPC_OUTPUT TIPC_TEE(TIPC_CONS,TIPC_LOG) 106#define TIPC_OUTPUT TIPC_LOG
106#endif 107#endif
107 108
108#ifndef DBG_OUTPUT 109#ifndef DBG_OUTPUT
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c
index 834319e3b7e7..8ca9457250be 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/dbg.c
@@ -38,18 +38,44 @@
38#include "config.h" 38#include "config.h"
39#include "dbg.h" 39#include "dbg.h"
40 40
41static char print_string[TIPC_PB_MAX_STR]; 41/*
42static DEFINE_SPINLOCK(print_lock); 42 * TIPC pre-defines the following print buffers:
43 *
44 * TIPC_NULL : null buffer (i.e. print nowhere)
45 * TIPC_CONS : system console
46 * TIPC_LOG : TIPC log buffer
47 *
48 * Additional user-defined print buffers are also permitted.
49 */
43 50
44static struct print_buf null_buf = { NULL, 0, NULL, NULL }; 51static struct print_buf null_buf = { NULL, 0, NULL, 0 };
45struct print_buf *TIPC_NULL = &null_buf; 52struct print_buf *TIPC_NULL = &null_buf;
46 53
47static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; 54static struct print_buf cons_buf = { NULL, 0, NULL, 1 };
48struct print_buf *TIPC_CONS = &cons_buf; 55struct print_buf *TIPC_CONS = &cons_buf;
49 56
50static struct print_buf log_buf = { NULL, 0, NULL, NULL }; 57static struct print_buf log_buf = { NULL, 0, NULL, 1 };
51struct print_buf *TIPC_LOG = &log_buf; 58struct print_buf *TIPC_LOG = &log_buf;
52 59
60/*
61 * Locking policy when using print buffers.
62 *
63 * 1) tipc_printf() uses 'print_lock' to protect against concurrent access to
64 * 'print_string' when writing to a print buffer. This also protects against
65 * concurrent writes to the print buffer being written to.
66 *
67 * 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned
68 * use of 'print_lock' to protect against all types of concurrent operations
69 * on their associated print buffer (not just write operations).
70 *
71 * Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely
72 * on the caller to prevent simultaneous use of the print buffer(s) being
73 * manipulated.
74 */
75
76static char print_string[TIPC_PB_MAX_STR];
77static DEFINE_SPINLOCK(print_lock);
78
53 79
54#define FORMAT(PTR,LEN,FMT) \ 80#define FORMAT(PTR,LEN,FMT) \
55{\ 81{\
@@ -60,27 +86,14 @@ struct print_buf *TIPC_LOG = &log_buf;
60 *(PTR + LEN) = '\0';\ 86 *(PTR + LEN) = '\0';\
61} 87}
62 88
63/*
64 * Locking policy when using print buffers.
65 *
66 * The following routines use 'print_lock' for protection:
67 * 1) tipc_printf() - to protect its print buffer(s) and 'print_string'
68 * 2) TIPC_TEE() - to protect its print buffer(s)
69 * 3) tipc_dump() - to protect its print buffer(s) and 'print_string'
70 * 4) tipc_log_XXX() - 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.
74 */
75
76/** 89/**
77 * tipc_printbuf_init - initialize print buffer to empty 90 * tipc_printbuf_init - initialize print buffer to empty
78 * @pb: pointer to print buffer structure 91 * @pb: pointer to print buffer structure
79 * @raw: pointer to character array used by print buffer 92 * @raw: pointer to character array used by print buffer
80 * @size: size of character array 93 * @size: size of character array
81 * 94 *
82 * Makes the print buffer a null device that discards anything written to it 95 * Note: If the character array is too small (or absent), the print buffer
83 * if the character array is too small (or absent). 96 * becomes a null device that discards anything written to it.
84 */ 97 */
85 98
86void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) 99void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
@@ -88,7 +101,7 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
88 pb->buf = raw; 101 pb->buf = raw;
89 pb->crs = raw; 102 pb->crs = raw;
90 pb->size = size; 103 pb->size = size;
91 pb->next = NULL; 104 pb->echo = 0;
92 105
93 if (size < TIPC_PB_MIN_SIZE) { 106 if (size < TIPC_PB_MIN_SIZE) {
94 pb->buf = NULL; 107 pb->buf = NULL;
@@ -105,7 +118,11 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
105 118
106void tipc_printbuf_reset(struct print_buf *pb) 119void tipc_printbuf_reset(struct print_buf *pb)
107{ 120{
108 tipc_printbuf_init(pb, pb->buf, pb->size); 121 if (pb->buf != NULL) {
122 pb->crs = pb->buf;
123 pb->buf[0] = 0;
124 pb->buf[pb->size - 1] = ~0;
125 }
109} 126}
110 127
111/** 128/**
@@ -182,7 +199,6 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
182 strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***"); 199 strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***");
183 pb_to->buf[pb_to->size - 1] = ~0; 200 pb_to->buf[pb_to->size - 1] = ~0;
184 pb_to->crs = strchr(pb_to->buf, 0); 201 pb_to->crs = strchr(pb_to->buf, 0);
185 pb_to->next = NULL;
186 return; 202 return;
187 } 203 }
188 204
@@ -205,8 +221,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
205} 221}
206 222
207/** 223/**
208 * tipc_printf - append formatted output to print buffer chain 224 * tipc_printf - append formatted output to print buffer
209 * @pb: pointer to chain of print buffers (may be NULL) 225 * @pb: pointer to print buffer
210 * @fmt: formatted info to be printed 226 * @fmt: formatted info to be printed
211 */ 227 */
212 228
@@ -215,66 +231,36 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
215 int chars_to_add; 231 int chars_to_add;
216 int chars_left; 232 int chars_left;
217 char save_char; 233 char save_char;
218 struct print_buf *pb_next;
219 234
220 spin_lock_bh(&print_lock); 235 spin_lock_bh(&print_lock);
236
221 FORMAT(print_string, chars_to_add, fmt); 237 FORMAT(print_string, chars_to_add, fmt);
222 if (chars_to_add >= TIPC_PB_MAX_STR) 238 if (chars_to_add >= TIPC_PB_MAX_STR)
223 strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***"); 239 strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***");
224 240
225 while (pb) { 241 if (pb->buf) {
226 if (pb == TIPC_CONS) 242 chars_left = pb->buf + pb->size - pb->crs - 1;
227 printk(print_string); 243 if (chars_to_add <= chars_left) {
228 else if (pb->buf) { 244 strcpy(pb->crs, print_string);
229 chars_left = pb->buf + pb->size - pb->crs - 1; 245 pb->crs += chars_to_add;
230 if (chars_to_add <= chars_left) { 246 } else if (chars_to_add >= (pb->size - 1)) {
231 strcpy(pb->crs, print_string); 247 strcpy(pb->buf, print_string + chars_to_add + 1
232 pb->crs += chars_to_add; 248 - pb->size);
233 } else if (chars_to_add >= (pb->size - 1)) { 249 pb->crs = pb->buf + pb->size - 1;
234 strcpy(pb->buf, print_string + chars_to_add + 1 250 } else {
235 - pb->size); 251 strcpy(pb->buf, print_string + chars_left);
236 pb->crs = pb->buf + pb->size - 1; 252 save_char = print_string[chars_left];
237 } else { 253 print_string[chars_left] = 0;
238 strcpy(pb->buf, print_string + chars_left); 254 strcpy(pb->crs, print_string);
239 save_char = print_string[chars_left]; 255 print_string[chars_left] = save_char;
240 print_string[chars_left] = 0; 256 pb->crs = pb->buf + chars_to_add - chars_left;
241 strcpy(pb->crs, print_string);
242 print_string[chars_left] = save_char;
243 pb->crs = pb->buf + chars_to_add - chars_left;
244 }
245 } 257 }
246 pb_next = pb->next;
247 pb->next = NULL;
248 pb = pb_next;
249 } 258 }
250 spin_unlock_bh(&print_lock);
251}
252 259
253/** 260 if (pb->echo)
254 * TIPC_TEE - perform next output operation on both print buffers 261 printk(print_string);
255 * @b0: pointer to chain of print buffers (may be NULL)
256 * @b1: pointer to print buffer to add to chain
257 *
258 * Returns pointer to print buffer chain.
259 */
260
261struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
262{
263 struct print_buf *pb = b0;
264 262
265 if (!b0 || (b0 == b1))
266 return b1;
267
268 spin_lock_bh(&print_lock);
269 while (pb->next) {
270 if ((pb->next == b1) || (pb->next == b0))
271 pb->next = pb->next->next;
272 else
273 pb = pb->next;
274 }
275 pb->next = b1;
276 spin_unlock_bh(&print_lock); 263 spin_unlock_bh(&print_lock);
277 return b0;
278} 264}
279 265
280/** 266/**
@@ -323,31 +309,28 @@ static void printbuf_dump(struct print_buf *pb)
323} 309}
324 310
325/** 311/**
326 * tipc_dump - dump non-console print buffer(s) to console 312 * tipc_dump - dump (non-console) print buffer to console
327 * @pb: pointer to chain of print buffers 313 * @pb: pointer to print buffer
328 */ 314 */
329 315
330void tipc_dump(struct print_buf *pb, const char *fmt, ...) 316void tipc_dump(struct print_buf *pb, const char *fmt, ...)
331{ 317{
332 struct print_buf *pb_next;
333 int len; 318 int len;
334 319
320 if (pb == TIPC_CONS)
321 return;
322
335 spin_lock_bh(&print_lock); 323 spin_lock_bh(&print_lock);
324
336 FORMAT(print_string, len, fmt); 325 FORMAT(print_string, len, fmt);
337 printk(print_string); 326 printk(print_string);
338 327
339 for (; pb; pb = pb->next) { 328 printk("\n---- Start of %s log dump ----\n\n",
340 if (pb != TIPC_CONS) { 329 (pb == TIPC_LOG) ? "global" : "local");
341 printk("\n---- Start of %s log dump ----\n\n", 330 printbuf_dump(pb);
342 (pb == TIPC_LOG) ? "global" : "local"); 331 tipc_printbuf_reset(pb);
343 printbuf_dump(pb); 332 printk("\n---- End of dump ----\n");
344 tipc_printbuf_reset(pb); 333
345 printk("\n---- End of dump ----\n");
346 }
347 pb_next = pb->next;
348 pb->next = NULL;
349 pb = pb_next;
350 }
351 spin_unlock_bh(&print_lock); 334 spin_unlock_bh(&print_lock);
352} 335}
353 336
@@ -368,8 +351,10 @@ int tipc_log_resize(int log_size)
368 if (log_size) { 351 if (log_size) {
369 if (log_size < TIPC_PB_MIN_SIZE) 352 if (log_size < TIPC_PB_MIN_SIZE)
370 log_size = TIPC_PB_MIN_SIZE; 353 log_size = TIPC_PB_MIN_SIZE;
354 res = TIPC_LOG->echo;
371 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), 355 tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC),
372 log_size); 356 log_size);
357 TIPC_LOG->echo = res;
373 res = !TIPC_LOG->buf; 358 res = !TIPC_LOG->buf;
374 } 359 }
375 spin_unlock_bh(&print_lock); 360 spin_unlock_bh(&print_lock);
diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h
index 6b00062bf040..5ef1bc8f64ef 100644
--- a/net/tipc/dbg.h
+++ b/net/tipc/dbg.h
@@ -42,14 +42,14 @@
42 * @buf: pointer to character array containing print buffer contents 42 * @buf: pointer to character array containing print buffer contents
43 * @size: size of character array 43 * @size: size of character array
44 * @crs: pointer to first unused space in character array (i.e. final NUL) 44 * @crs: pointer to first unused space in character array (i.e. final NUL)
45 * @next: used to link print buffers when printing to more than one at a time 45 * @echo: echo output to system console if non-zero
46 */ 46 */
47 47
48struct print_buf { 48struct print_buf {
49 char *buf; 49 char *buf;
50 u32 size; 50 u32 size;
51 char *crs; 51 char *crs;
52 struct print_buf *next; 52 int echo;
53}; 53};
54 54
55#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */ 55#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */