162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci#ifndef DRBD_POLYMORPH_PRINTK_H 362306a36Sopenharmony_ci#define DRBD_POLYMORPH_PRINTK_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#if !defined(CONFIG_DYNAMIC_DEBUG) 662306a36Sopenharmony_ci#undef DEFINE_DYNAMIC_DEBUG_METADATA 762306a36Sopenharmony_ci#undef __dynamic_pr_debug 862306a36Sopenharmony_ci#undef DYNAMIC_DEBUG_BRANCH 962306a36Sopenharmony_ci#define DEFINE_DYNAMIC_DEBUG_METADATA(D, F) const char *D = F; ((void)D) 1062306a36Sopenharmony_ci#define __dynamic_pr_debug(D, F, args...) do { (void)(D); if (0) printk(F, ## args); } while (0) 1162306a36Sopenharmony_ci#define DYNAMIC_DEBUG_BRANCH(D) false 1262306a36Sopenharmony_ci#endif 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define __drbd_printk_drbd_device_prep(device) \ 1662306a36Sopenharmony_ci const struct drbd_device *__d = (device); \ 1762306a36Sopenharmony_ci const struct drbd_resource *__r = __d->resource 1862306a36Sopenharmony_ci#define __drbd_printk_drbd_device_fmt(fmt) "drbd %s/%u drbd%u: " fmt 1962306a36Sopenharmony_ci#define __drbd_printk_drbd_device_args() __r->name, __d->vnr, __d->minor 2062306a36Sopenharmony_ci#define __drbd_printk_drbd_device_unprep() 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define __drbd_printk_drbd_peer_device_prep(peer_device) \ 2362306a36Sopenharmony_ci const struct drbd_device *__d; \ 2462306a36Sopenharmony_ci const struct drbd_resource *__r; \ 2562306a36Sopenharmony_ci __d = (peer_device)->device; \ 2662306a36Sopenharmony_ci __r = __d->resource 2762306a36Sopenharmony_ci#define __drbd_printk_drbd_peer_device_fmt(fmt) \ 2862306a36Sopenharmony_ci "drbd %s/%u drbd%u: " fmt 2962306a36Sopenharmony_ci#define __drbd_printk_drbd_peer_device_args() \ 3062306a36Sopenharmony_ci __r->name, __d->vnr, __d->minor 3162306a36Sopenharmony_ci#define __drbd_printk_drbd_peer_device_unprep() 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define __drbd_printk_drbd_resource_prep(resource) \ 3462306a36Sopenharmony_ci const struct drbd_resource *__r = resource 3562306a36Sopenharmony_ci#define __drbd_printk_drbd_resource_fmt(fmt) "drbd %s: " fmt 3662306a36Sopenharmony_ci#define __drbd_printk_drbd_resource_args() __r->name 3762306a36Sopenharmony_ci#define __drbd_printk_drbd_resource_unprep(resource) 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define __drbd_printk_drbd_connection_prep(connection) \ 4062306a36Sopenharmony_ci const struct drbd_connection *__c = (connection); \ 4162306a36Sopenharmony_ci const struct drbd_resource *__r = __c->resource 4262306a36Sopenharmony_ci#define __drbd_printk_drbd_connection_fmt(fmt) \ 4362306a36Sopenharmony_ci "drbd %s: " fmt 4462306a36Sopenharmony_ci#define __drbd_printk_drbd_connection_args() \ 4562306a36Sopenharmony_ci __r->name 4662306a36Sopenharmony_ci#define __drbd_printk_drbd_connection_unprep() 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_civoid drbd_printk_with_wrong_object_type(void); 4962306a36Sopenharmony_civoid drbd_dyn_dbg_with_wrong_object_type(void); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define __drbd_printk_choose_cond(obj, struct_name) \ 5262306a36Sopenharmony_ci (__builtin_types_compatible_p(typeof(obj), struct struct_name *) || \ 5362306a36Sopenharmony_ci __builtin_types_compatible_p(typeof(obj), const struct struct_name *)) 5462306a36Sopenharmony_ci#define __drbd_printk_if_same_type(obj, struct_name, level, fmt, args...) \ 5562306a36Sopenharmony_ci __drbd_printk_choose_cond(obj, struct_name), \ 5662306a36Sopenharmony_ci({ \ 5762306a36Sopenharmony_ci __drbd_printk_ ## struct_name ## _prep((const struct struct_name *)(obj)); \ 5862306a36Sopenharmony_ci printk(level __drbd_printk_ ## struct_name ## _fmt(fmt), \ 5962306a36Sopenharmony_ci __drbd_printk_ ## struct_name ## _args(), ## args); \ 6062306a36Sopenharmony_ci __drbd_printk_ ## struct_name ## _unprep(); \ 6162306a36Sopenharmony_ci}) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#define drbd_printk(level, obj, fmt, args...) \ 6462306a36Sopenharmony_ci __builtin_choose_expr( \ 6562306a36Sopenharmony_ci __drbd_printk_if_same_type(obj, drbd_device, level, fmt, ## args), \ 6662306a36Sopenharmony_ci __builtin_choose_expr( \ 6762306a36Sopenharmony_ci __drbd_printk_if_same_type(obj, drbd_resource, level, fmt, ## args), \ 6862306a36Sopenharmony_ci __builtin_choose_expr( \ 6962306a36Sopenharmony_ci __drbd_printk_if_same_type(obj, drbd_connection, level, fmt, ## args), \ 7062306a36Sopenharmony_ci __builtin_choose_expr( \ 7162306a36Sopenharmony_ci __drbd_printk_if_same_type(obj, drbd_peer_device, level, fmt, ## args), \ 7262306a36Sopenharmony_ci drbd_printk_with_wrong_object_type())))) 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci#define __drbd_dyn_dbg_if_same_type(obj, struct_name, fmt, args...) \ 7562306a36Sopenharmony_ci __drbd_printk_choose_cond(obj, struct_name), \ 7662306a36Sopenharmony_ci({ \ 7762306a36Sopenharmony_ci DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ 7862306a36Sopenharmony_ci if (DYNAMIC_DEBUG_BRANCH(descriptor)) { \ 7962306a36Sopenharmony_ci __drbd_printk_ ## struct_name ## _prep((const struct struct_name *)(obj)); \ 8062306a36Sopenharmony_ci __dynamic_pr_debug(&descriptor, __drbd_printk_ ## struct_name ## _fmt(fmt), \ 8162306a36Sopenharmony_ci __drbd_printk_ ## struct_name ## _args(), ## args); \ 8262306a36Sopenharmony_ci __drbd_printk_ ## struct_name ## _unprep(); \ 8362306a36Sopenharmony_ci } \ 8462306a36Sopenharmony_ci}) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci#define dynamic_drbd_dbg(obj, fmt, args...) \ 8762306a36Sopenharmony_ci __builtin_choose_expr( \ 8862306a36Sopenharmony_ci __drbd_dyn_dbg_if_same_type(obj, drbd_device, fmt, ## args), \ 8962306a36Sopenharmony_ci __builtin_choose_expr( \ 9062306a36Sopenharmony_ci __drbd_dyn_dbg_if_same_type(obj, drbd_resource, fmt, ## args), \ 9162306a36Sopenharmony_ci __builtin_choose_expr( \ 9262306a36Sopenharmony_ci __drbd_dyn_dbg_if_same_type(obj, drbd_connection, fmt, ## args), \ 9362306a36Sopenharmony_ci __builtin_choose_expr( \ 9462306a36Sopenharmony_ci __drbd_dyn_dbg_if_same_type(obj, drbd_peer_device, fmt, ## args), \ 9562306a36Sopenharmony_ci drbd_dyn_dbg_with_wrong_object_type())))) 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define drbd_emerg(device, fmt, args...) \ 9862306a36Sopenharmony_ci drbd_printk(KERN_EMERG, device, fmt, ## args) 9962306a36Sopenharmony_ci#define drbd_alert(device, fmt, args...) \ 10062306a36Sopenharmony_ci drbd_printk(KERN_ALERT, device, fmt, ## args) 10162306a36Sopenharmony_ci#define drbd_crit(device, fmt, args...) \ 10262306a36Sopenharmony_ci drbd_printk(KERN_CRIT, device, fmt, ## args) 10362306a36Sopenharmony_ci#define drbd_err(device, fmt, args...) \ 10462306a36Sopenharmony_ci drbd_printk(KERN_ERR, device, fmt, ## args) 10562306a36Sopenharmony_ci#define drbd_warn(device, fmt, args...) \ 10662306a36Sopenharmony_ci drbd_printk(KERN_WARNING, device, fmt, ## args) 10762306a36Sopenharmony_ci#define drbd_notice(device, fmt, args...) \ 10862306a36Sopenharmony_ci drbd_printk(KERN_NOTICE, device, fmt, ## args) 10962306a36Sopenharmony_ci#define drbd_info(device, fmt, args...) \ 11062306a36Sopenharmony_ci drbd_printk(KERN_INFO, device, fmt, ## args) 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci#define drbd_ratelimit() \ 11462306a36Sopenharmony_ci({ \ 11562306a36Sopenharmony_ci static DEFINE_RATELIMIT_STATE(_rs, \ 11662306a36Sopenharmony_ci DEFAULT_RATELIMIT_INTERVAL, \ 11762306a36Sopenharmony_ci DEFAULT_RATELIMIT_BURST); \ 11862306a36Sopenharmony_ci __ratelimit(&_rs); \ 11962306a36Sopenharmony_ci}) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci#define D_ASSERT(x, exp) \ 12262306a36Sopenharmony_ci do { \ 12362306a36Sopenharmony_ci if (!(exp)) \ 12462306a36Sopenharmony_ci drbd_err(x, "ASSERTION %s FAILED in %s\n", \ 12562306a36Sopenharmony_ci #exp, __func__); \ 12662306a36Sopenharmony_ci } while (0) 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/** 12962306a36Sopenharmony_ci * expect - Make an assertion 13062306a36Sopenharmony_ci * 13162306a36Sopenharmony_ci * Unlike the assert macro, this macro returns a boolean result. 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_ci#define expect(x, exp) ({ \ 13462306a36Sopenharmony_ci bool _bool = (exp); \ 13562306a36Sopenharmony_ci if (!_bool && drbd_ratelimit()) \ 13662306a36Sopenharmony_ci drbd_err(x, "ASSERTION %s FAILED in %s\n", \ 13762306a36Sopenharmony_ci #exp, __func__); \ 13862306a36Sopenharmony_ci _bool; \ 13962306a36Sopenharmony_ci }) 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci#endif 142