1136160c1SChristoph Böhmwalder /* SPDX-License-Identifier: GPL-2.0-only */ 2136160c1SChristoph Böhmwalder #ifndef DRBD_POLYMORPH_PRINTK_H 3136160c1SChristoph Böhmwalder #define DRBD_POLYMORPH_PRINTK_H 4136160c1SChristoph Böhmwalder 5aa034695SChristoph Böhmwalder #if !defined(CONFIG_DYNAMIC_DEBUG) 6aa034695SChristoph Böhmwalder #undef DEFINE_DYNAMIC_DEBUG_METADATA 7aa034695SChristoph Böhmwalder #undef __dynamic_pr_debug 8aa034695SChristoph Böhmwalder #undef DYNAMIC_DEBUG_BRANCH 9aa034695SChristoph Böhmwalder #define DEFINE_DYNAMIC_DEBUG_METADATA(D, F) const char *D = F; ((void)D) 10aa034695SChristoph Böhmwalder #define __dynamic_pr_debug(D, F, args...) do { (void)(D); if (0) printk(F, ## args); } while (0) 11aa034695SChristoph Böhmwalder #define DYNAMIC_DEBUG_BRANCH(D) false 12aa034695SChristoph Böhmwalder #endif 13aa034695SChristoph Böhmwalder 14aa034695SChristoph Böhmwalder 15aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_device_prep(device) \ 16aa034695SChristoph Böhmwalder const struct drbd_device *__d = (device); \ 17aa034695SChristoph Böhmwalder const struct drbd_resource *__r = __d->resource 18aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_device_fmt(fmt) "drbd %s/%u drbd%u: " fmt 19aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_device_args() __r->name, __d->vnr, __d->minor 20aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_device_unprep() 21aa034695SChristoph Böhmwalder 22aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_peer_device_prep(peer_device) \ 23aa034695SChristoph Böhmwalder const struct drbd_device *__d; \ 24aa034695SChristoph Böhmwalder const struct drbd_resource *__r; \ 25aa034695SChristoph Böhmwalder __d = (peer_device)->device; \ 26aa034695SChristoph Böhmwalder __r = __d->resource 27aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_peer_device_fmt(fmt) \ 28aa034695SChristoph Böhmwalder "drbd %s/%u drbd%u: " fmt 29aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_peer_device_args() \ 30aa034695SChristoph Böhmwalder __r->name, __d->vnr, __d->minor 31aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_peer_device_unprep() 32aa034695SChristoph Böhmwalder 33aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_resource_prep(resource) \ 34aa034695SChristoph Böhmwalder const struct drbd_resource *__r = resource 35aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_resource_fmt(fmt) "drbd %s: " fmt 36aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_resource_args() __r->name 37aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_resource_unprep(resource) 38aa034695SChristoph Böhmwalder 39aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_connection_prep(connection) \ 40aa034695SChristoph Böhmwalder const struct drbd_connection *__c = (connection); \ 41aa034695SChristoph Böhmwalder const struct drbd_resource *__r = __c->resource 42aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_connection_fmt(fmt) \ 43aa034695SChristoph Böhmwalder "drbd %s: " fmt 44aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_connection_args() \ 45aa034695SChristoph Böhmwalder __r->name 46aa034695SChristoph Böhmwalder #define __drbd_printk_drbd_connection_unprep() 47136160c1SChristoph Böhmwalder 48136160c1SChristoph Böhmwalder void drbd_printk_with_wrong_object_type(void); 49aa034695SChristoph Böhmwalder void drbd_dyn_dbg_with_wrong_object_type(void); 50136160c1SChristoph Böhmwalder 51aa034695SChristoph Böhmwalder #define __drbd_printk_choose_cond(obj, struct_name) \ 52aa034695SChristoph Böhmwalder (__builtin_types_compatible_p(typeof(obj), struct struct_name *) || \ 53aa034695SChristoph Böhmwalder __builtin_types_compatible_p(typeof(obj), const struct struct_name *)) 54aa034695SChristoph Böhmwalder #define __drbd_printk_if_same_type(obj, struct_name, level, fmt, args...) \ 55aa034695SChristoph Böhmwalder __drbd_printk_choose_cond(obj, struct_name), \ 56aa034695SChristoph Böhmwalder ({ \ 57aa034695SChristoph Böhmwalder __drbd_printk_ ## struct_name ## _prep((const struct struct_name *)(obj)); \ 58aa034695SChristoph Böhmwalder printk(level __drbd_printk_ ## struct_name ## _fmt(fmt), \ 59aa034695SChristoph Böhmwalder __drbd_printk_ ## struct_name ## _args(), ## args); \ 60aa034695SChristoph Böhmwalder __drbd_printk_ ## struct_name ## _unprep(); \ 61aa034695SChristoph Böhmwalder }) 62136160c1SChristoph Böhmwalder 63136160c1SChristoph Böhmwalder #define drbd_printk(level, obj, fmt, args...) \ 64136160c1SChristoph Böhmwalder __builtin_choose_expr( \ 65aa034695SChristoph Böhmwalder __drbd_printk_if_same_type(obj, drbd_device, level, fmt, ## args), \ 66136160c1SChristoph Böhmwalder __builtin_choose_expr( \ 67aa034695SChristoph Böhmwalder __drbd_printk_if_same_type(obj, drbd_resource, level, fmt, ## args), \ 68136160c1SChristoph Böhmwalder __builtin_choose_expr( \ 69aa034695SChristoph Böhmwalder __drbd_printk_if_same_type(obj, drbd_connection, level, fmt, ## args), \ 70136160c1SChristoph Böhmwalder __builtin_choose_expr( \ 71aa034695SChristoph Böhmwalder __drbd_printk_if_same_type(obj, drbd_peer_device, level, fmt, ## args), \ 72136160c1SChristoph Böhmwalder drbd_printk_with_wrong_object_type())))) 73136160c1SChristoph Böhmwalder 74aa034695SChristoph Böhmwalder #define __drbd_dyn_dbg_if_same_type(obj, struct_name, fmt, args...) \ 75aa034695SChristoph Böhmwalder __drbd_printk_choose_cond(obj, struct_name), \ 76aa034695SChristoph Böhmwalder ({ \ 77aa034695SChristoph Böhmwalder DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 78aa034695SChristoph Böhmwalder if (DYNAMIC_DEBUG_BRANCH(descriptor)) { \ 79aa034695SChristoph Böhmwalder __drbd_printk_ ## struct_name ## _prep((const struct struct_name *)(obj)); \ 80aa034695SChristoph Böhmwalder __dynamic_pr_debug(&descriptor, __drbd_printk_ ## struct_name ## _fmt(fmt), \ 81aa034695SChristoph Böhmwalder __drbd_printk_ ## struct_name ## _args(), ## args); \ 82aa034695SChristoph Böhmwalder __drbd_printk_ ## struct_name ## _unprep(); \ 83aa034695SChristoph Böhmwalder } \ 84aa034695SChristoph Böhmwalder }) 85136160c1SChristoph Böhmwalder 86aa034695SChristoph Böhmwalder #define dynamic_drbd_dbg(obj, fmt, args...) \ 87aa034695SChristoph Böhmwalder __builtin_choose_expr( \ 88aa034695SChristoph Böhmwalder __drbd_dyn_dbg_if_same_type(obj, drbd_device, fmt, ## args), \ 89aa034695SChristoph Böhmwalder __builtin_choose_expr( \ 90aa034695SChristoph Böhmwalder __drbd_dyn_dbg_if_same_type(obj, drbd_resource, fmt, ## args), \ 91aa034695SChristoph Böhmwalder __builtin_choose_expr( \ 92aa034695SChristoph Böhmwalder __drbd_dyn_dbg_if_same_type(obj, drbd_connection, fmt, ## args), \ 93aa034695SChristoph Böhmwalder __builtin_choose_expr( \ 94aa034695SChristoph Böhmwalder __drbd_dyn_dbg_if_same_type(obj, drbd_peer_device, fmt, ## args), \ 95aa034695SChristoph Böhmwalder drbd_dyn_dbg_with_wrong_object_type())))) 96aa034695SChristoph Böhmwalder 97aa034695SChristoph Böhmwalder #define drbd_emerg(device, fmt, args...) \ 98aa034695SChristoph Böhmwalder drbd_printk(KERN_EMERG, device, fmt, ## args) 99aa034695SChristoph Böhmwalder #define drbd_alert(device, fmt, args...) \ 100aa034695SChristoph Böhmwalder drbd_printk(KERN_ALERT, device, fmt, ## args) 101aa034695SChristoph Böhmwalder #define drbd_crit(device, fmt, args...) \ 102aa034695SChristoph Böhmwalder drbd_printk(KERN_CRIT, device, fmt, ## args) 103aa034695SChristoph Böhmwalder #define drbd_err(device, fmt, args...) \ 104aa034695SChristoph Böhmwalder drbd_printk(KERN_ERR, device, fmt, ## args) 105aa034695SChristoph Böhmwalder #define drbd_warn(device, fmt, args...) \ 106aa034695SChristoph Böhmwalder drbd_printk(KERN_WARNING, device, fmt, ## args) 107aa034695SChristoph Böhmwalder #define drbd_notice(device, fmt, args...) \ 108aa034695SChristoph Böhmwalder drbd_printk(KERN_NOTICE, device, fmt, ## args) 109aa034695SChristoph Böhmwalder #define drbd_info(device, fmt, args...) \ 110aa034695SChristoph Böhmwalder drbd_printk(KERN_INFO, device, fmt, ## args) 111aa034695SChristoph Böhmwalder 112136160c1SChristoph Böhmwalder 113e3fa02d7SChristoph Böhmwalder #define drbd_ratelimit() \ 114e3fa02d7SChristoph Böhmwalder ({ \ 115e3fa02d7SChristoph Böhmwalder static DEFINE_RATELIMIT_STATE(_rs, \ 116e3fa02d7SChristoph Böhmwalder DEFAULT_RATELIMIT_INTERVAL, \ 117e3fa02d7SChristoph Böhmwalder DEFAULT_RATELIMIT_BURST); \ 118e3fa02d7SChristoph Böhmwalder __ratelimit(&_rs); \ 119e3fa02d7SChristoph Böhmwalder }) 120e3fa02d7SChristoph Böhmwalder 121136160c1SChristoph Böhmwalder #define D_ASSERT(x, exp) \ 122136160c1SChristoph Böhmwalder do { \ 123136160c1SChristoph Böhmwalder if (!(exp)) \ 124136160c1SChristoph Böhmwalder drbd_err(x, "ASSERTION %s FAILED in %s\n", \ 125136160c1SChristoph Böhmwalder #exp, __func__); \ 126136160c1SChristoph Böhmwalder } while (0) 127136160c1SChristoph Böhmwalder 128136160c1SChristoph Böhmwalder /** 129136160c1SChristoph Böhmwalder * expect - Make an assertion 130136160c1SChristoph Böhmwalder * 131136160c1SChristoph Böhmwalder * Unlike the assert macro, this macro returns a boolean result. 132136160c1SChristoph Böhmwalder */ 133*677b3672SChristoph Böhmwalder #define expect(x, exp) ({ \ 134136160c1SChristoph Böhmwalder bool _bool = (exp); \ 135e3fa02d7SChristoph Böhmwalder if (!_bool && drbd_ratelimit()) \ 136*677b3672SChristoph Böhmwalder drbd_err(x, "ASSERTION %s FAILED in %s\n", \ 137136160c1SChristoph Böhmwalder #exp, __func__); \ 138136160c1SChristoph Böhmwalder _bool; \ 139136160c1SChristoph Böhmwalder }) 140136160c1SChristoph Böhmwalder 141136160c1SChristoph Böhmwalder #endif 142