1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 #ifndef DRBD_POLYMORPH_PRINTK_H 3 #define DRBD_POLYMORPH_PRINTK_H 4 5 #if !defined(CONFIG_DYNAMIC_DEBUG) 6 #undef DEFINE_DYNAMIC_DEBUG_METADATA 7 #undef __dynamic_pr_debug 8 #undef DYNAMIC_DEBUG_BRANCH 9 #define DEFINE_DYNAMIC_DEBUG_METADATA(D, F) const char *D = F; ((void)D) 10 #define __dynamic_pr_debug(D, F, args...) do { (void)(D); if (0) printk(F, ## args); } while (0) 11 #define DYNAMIC_DEBUG_BRANCH(D) false 12 #endif 13 14 15 #define __drbd_printk_drbd_device_prep(device) \ 16 const struct drbd_device *__d = (device); \ 17 const struct drbd_resource *__r = __d->resource 18 #define __drbd_printk_drbd_device_fmt(fmt) "drbd %s/%u drbd%u: " fmt 19 #define __drbd_printk_drbd_device_args() __r->name, __d->vnr, __d->minor 20 #define __drbd_printk_drbd_device_unprep() 21 22 #define __drbd_printk_drbd_peer_device_prep(peer_device) \ 23 const struct drbd_device *__d; \ 24 const struct drbd_resource *__r; \ 25 __d = (peer_device)->device; \ 26 __r = __d->resource 27 #define __drbd_printk_drbd_peer_device_fmt(fmt) \ 28 "drbd %s/%u drbd%u: " fmt 29 #define __drbd_printk_drbd_peer_device_args() \ 30 __r->name, __d->vnr, __d->minor 31 #define __drbd_printk_drbd_peer_device_unprep() 32 33 #define __drbd_printk_drbd_resource_prep(resource) \ 34 const struct drbd_resource *__r = resource 35 #define __drbd_printk_drbd_resource_fmt(fmt) "drbd %s: " fmt 36 #define __drbd_printk_drbd_resource_args() __r->name 37 #define __drbd_printk_drbd_resource_unprep(resource) 38 39 #define __drbd_printk_drbd_connection_prep(connection) \ 40 const struct drbd_connection *__c = (connection); \ 41 const struct drbd_resource *__r = __c->resource 42 #define __drbd_printk_drbd_connection_fmt(fmt) \ 43 "drbd %s: " fmt 44 #define __drbd_printk_drbd_connection_args() \ 45 __r->name 46 #define __drbd_printk_drbd_connection_unprep() 47 48 void drbd_printk_with_wrong_object_type(void); 49 void drbd_dyn_dbg_with_wrong_object_type(void); 50 51 #define __drbd_printk_choose_cond(obj, struct_name) \ 52 (__builtin_types_compatible_p(typeof(obj), struct struct_name *) || \ 53 __builtin_types_compatible_p(typeof(obj), const struct struct_name *)) 54 #define __drbd_printk_if_same_type(obj, struct_name, level, fmt, args...) \ 55 __drbd_printk_choose_cond(obj, struct_name), \ 56 ({ \ 57 __drbd_printk_ ## struct_name ## _prep((const struct struct_name *)(obj)); \ 58 printk(level __drbd_printk_ ## struct_name ## _fmt(fmt), \ 59 __drbd_printk_ ## struct_name ## _args(), ## args); \ 60 __drbd_printk_ ## struct_name ## _unprep(); \ 61 }) 62 63 #define drbd_printk(level, obj, fmt, args...) \ 64 __builtin_choose_expr( \ 65 __drbd_printk_if_same_type(obj, drbd_device, level, fmt, ## args), \ 66 __builtin_choose_expr( \ 67 __drbd_printk_if_same_type(obj, drbd_resource, level, fmt, ## args), \ 68 __builtin_choose_expr( \ 69 __drbd_printk_if_same_type(obj, drbd_connection, level, fmt, ## args), \ 70 __builtin_choose_expr( \ 71 __drbd_printk_if_same_type(obj, drbd_peer_device, level, fmt, ## args), \ 72 drbd_printk_with_wrong_object_type())))) 73 74 #define __drbd_dyn_dbg_if_same_type(obj, struct_name, fmt, args...) \ 75 __drbd_printk_choose_cond(obj, struct_name), \ 76 ({ \ 77 DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 78 if (DYNAMIC_DEBUG_BRANCH(descriptor)) { \ 79 __drbd_printk_ ## struct_name ## _prep((const struct struct_name *)(obj)); \ 80 __dynamic_pr_debug(&descriptor, __drbd_printk_ ## struct_name ## _fmt(fmt), \ 81 __drbd_printk_ ## struct_name ## _args(), ## args); \ 82 __drbd_printk_ ## struct_name ## _unprep(); \ 83 } \ 84 }) 85 86 #define dynamic_drbd_dbg(obj, fmt, args...) \ 87 __builtin_choose_expr( \ 88 __drbd_dyn_dbg_if_same_type(obj, drbd_device, fmt, ## args), \ 89 __builtin_choose_expr( \ 90 __drbd_dyn_dbg_if_same_type(obj, drbd_resource, fmt, ## args), \ 91 __builtin_choose_expr( \ 92 __drbd_dyn_dbg_if_same_type(obj, drbd_connection, fmt, ## args), \ 93 __builtin_choose_expr( \ 94 __drbd_dyn_dbg_if_same_type(obj, drbd_peer_device, fmt, ## args), \ 95 drbd_dyn_dbg_with_wrong_object_type())))) 96 97 #define drbd_emerg(device, fmt, args...) \ 98 drbd_printk(KERN_EMERG, device, fmt, ## args) 99 #define drbd_alert(device, fmt, args...) \ 100 drbd_printk(KERN_ALERT, device, fmt, ## args) 101 #define drbd_crit(device, fmt, args...) \ 102 drbd_printk(KERN_CRIT, device, fmt, ## args) 103 #define drbd_err(device, fmt, args...) \ 104 drbd_printk(KERN_ERR, device, fmt, ## args) 105 #define drbd_warn(device, fmt, args...) \ 106 drbd_printk(KERN_WARNING, device, fmt, ## args) 107 #define drbd_notice(device, fmt, args...) \ 108 drbd_printk(KERN_NOTICE, device, fmt, ## args) 109 #define drbd_info(device, fmt, args...) \ 110 drbd_printk(KERN_INFO, device, fmt, ## args) 111 112 113 #define drbd_ratelimit() \ 114 ({ \ 115 static DEFINE_RATELIMIT_STATE(_rs, \ 116 DEFAULT_RATELIMIT_INTERVAL, \ 117 DEFAULT_RATELIMIT_BURST); \ 118 __ratelimit(&_rs); \ 119 }) 120 121 #define D_ASSERT(x, exp) \ 122 do { \ 123 if (!(exp)) \ 124 drbd_err(x, "ASSERTION %s FAILED in %s\n", \ 125 #exp, __func__); \ 126 } while (0) 127 128 /** 129 * expect - Make an assertion 130 * 131 * Unlike the assert macro, this macro returns a boolean result. 132 */ 133 #define expect(x, exp) ({ \ 134 bool _bool = (exp); \ 135 if (!_bool && drbd_ratelimit()) \ 136 drbd_err(x, "ASSERTION %s FAILED in %s\n", \ 137 #exp, __func__); \ 138 _bool; \ 139 }) 140 141 #endif 142