xref: /linux/drivers/gpu/drm/xe/xe_assert.h (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
11975b591SMichal Wajdeczko /* SPDX-License-Identifier: MIT */
21975b591SMichal Wajdeczko /*
31975b591SMichal Wajdeczko  * Copyright © 2023 Intel Corporation
41975b591SMichal Wajdeczko  */
51975b591SMichal Wajdeczko 
61975b591SMichal Wajdeczko #ifndef _XE_ASSERT_H_
71975b591SMichal Wajdeczko #define _XE_ASSERT_H_
81975b591SMichal Wajdeczko 
91975b591SMichal Wajdeczko #include <linux/string_helpers.h>
101975b591SMichal Wajdeczko 
111975b591SMichal Wajdeczko #include <drm/drm_print.h>
121975b591SMichal Wajdeczko 
131975b591SMichal Wajdeczko #include "xe_device_types.h"
141975b591SMichal Wajdeczko #include "xe_step.h"
151975b591SMichal Wajdeczko 
161975b591SMichal Wajdeczko /**
171975b591SMichal Wajdeczko  * DOC: Xe ASSERTs
181975b591SMichal Wajdeczko  *
191975b591SMichal Wajdeczko  * While Xe driver aims to be simpler than legacy i915 driver it is still
201975b591SMichal Wajdeczko  * complex enough that some changes introduced while adding new functionality
211975b591SMichal Wajdeczko  * could break the existing code.
221975b591SMichal Wajdeczko  *
231975b591SMichal Wajdeczko  * Adding &drm_WARN or &drm_err to catch unwanted programming usage could lead
241975b591SMichal Wajdeczko  * to undesired increased driver footprint and may impact production driver
251975b591SMichal Wajdeczko  * performance as this additional code will be always present.
261975b591SMichal Wajdeczko  *
271975b591SMichal Wajdeczko  * To allow annotate functions with additional detailed debug checks to assert
281975b591SMichal Wajdeczko  * that all prerequisites are satisfied, without worrying about footprint or
291975b591SMichal Wajdeczko  * performance penalty on production builds where all potential misuses
301975b591SMichal Wajdeczko  * introduced during code integration were already fixed, we introduce family
311975b591SMichal Wajdeczko  * of Xe assert macros that try to follow classic assert() utility:
321975b591SMichal Wajdeczko  *
331975b591SMichal Wajdeczko  *  * xe_assert()
341975b591SMichal Wajdeczko  *  * xe_tile_assert()
351975b591SMichal Wajdeczko  *  * xe_gt_assert()
361975b591SMichal Wajdeczko  *
371975b591SMichal Wajdeczko  * These macros are implemented on top of &drm_WARN, but unlikely to the origin,
381975b591SMichal Wajdeczko  * warning is triggered when provided condition is false. Additionally all above
391975b591SMichal Wajdeczko  * assert macros cannot be used in expressions or as a condition, since
401975b591SMichal Wajdeczko  * underlying code will be compiled out on non-debug builds.
411975b591SMichal Wajdeczko  *
421975b591SMichal Wajdeczko  * Note that these macros are not intended for use to cover known gaps in the
431975b591SMichal Wajdeczko  * implementation; for such cases use regular &drm_WARN or &drm_err and provide
441975b591SMichal Wajdeczko  * valid safe fallback.
451975b591SMichal Wajdeczko  *
461975b591SMichal Wajdeczko  * Also in cases where performance or footprint is not an issue, developers
471975b591SMichal Wajdeczko  * should continue to use the regular &drm_WARN or &drm_err to ensure that bug
481975b591SMichal Wajdeczko  * reports from production builds will contain meaningful diagnostics data.
491975b591SMichal Wajdeczko  *
501975b591SMichal Wajdeczko  * Below code shows how asserts could help in debug to catch unplanned use::
511975b591SMichal Wajdeczko  *
521975b591SMichal Wajdeczko  *	static void one_igfx(struct xe_device *xe)
531975b591SMichal Wajdeczko  *	{
541975b591SMichal Wajdeczko  *		xe_assert(xe, xe->info.is_dgfx == false);
551975b591SMichal Wajdeczko  *		xe_assert(xe, xe->info.tile_count == 1);
561975b591SMichal Wajdeczko  *	}
571975b591SMichal Wajdeczko  *
581975b591SMichal Wajdeczko  *	static void two_dgfx(struct xe_device *xe)
591975b591SMichal Wajdeczko  *	{
601975b591SMichal Wajdeczko  *		xe_assert(xe, xe->info.is_dgfx);
611975b591SMichal Wajdeczko  *		xe_assert(xe, xe->info.tile_count == 2);
621975b591SMichal Wajdeczko  *	}
631975b591SMichal Wajdeczko  *
641975b591SMichal Wajdeczko  *	void foo(struct xe_device *xe)
651975b591SMichal Wajdeczko  *	{
661975b591SMichal Wajdeczko  *		if (xe->info.dgfx)
671975b591SMichal Wajdeczko  *			return two_dgfx(xe);
681975b591SMichal Wajdeczko  *		return one_igfx(xe);
691975b591SMichal Wajdeczko  *	}
701975b591SMichal Wajdeczko  *
711975b591SMichal Wajdeczko  *	void bar(struct xe_device *xe)
721975b591SMichal Wajdeczko  *	{
731975b591SMichal Wajdeczko  *		if (drm_WARN_ON(xe->drm, xe->info.tile_count > 2))
741975b591SMichal Wajdeczko  *			return;
751975b591SMichal Wajdeczko  *
761975b591SMichal Wajdeczko  *		if (xe->info.tile_count == 2)
771975b591SMichal Wajdeczko  *			return two_dgfx(xe);
781975b591SMichal Wajdeczko  *		return one_igfx(xe);
791975b591SMichal Wajdeczko  *	}
801975b591SMichal Wajdeczko  */
811975b591SMichal Wajdeczko 
821975b591SMichal Wajdeczko #if IS_ENABLED(CONFIG_DRM_XE_DEBUG)
831975b591SMichal Wajdeczko #define __xe_assert_msg(xe, condition, msg, arg...) ({						\
84*9f6b4790SMichal Wajdeczko 	(void)drm_WARN(&(xe)->drm, !(condition), "Assertion `%s` failed!\n" msg,		\
851975b591SMichal Wajdeczko 		       __stringify(condition), ## arg);						\
861975b591SMichal Wajdeczko })
871975b591SMichal Wajdeczko #else
881975b591SMichal Wajdeczko #define __xe_assert_msg(xe, condition, msg, arg...) ({						\
89babba646SLucas De Marchi 	typecheck(const struct xe_device *, xe);						\
901975b591SMichal Wajdeczko 	BUILD_BUG_ON_INVALID(condition);							\
911975b591SMichal Wajdeczko })
921975b591SMichal Wajdeczko #endif
931975b591SMichal Wajdeczko 
941975b591SMichal Wajdeczko /**
951975b591SMichal Wajdeczko  * xe_assert - warn if condition is false when debugging.
961975b591SMichal Wajdeczko  * @xe: the &struct xe_device pointer to which &condition applies
971975b591SMichal Wajdeczko  * @condition: condition to check
981975b591SMichal Wajdeczko  *
991975b591SMichal Wajdeczko  * xe_assert() uses &drm_WARN to emit a warning and print additional information
1001975b591SMichal Wajdeczko  * that could be read from the &xe pointer if provided &condition is false.
1011975b591SMichal Wajdeczko  *
1021975b591SMichal Wajdeczko  * Contrary to &drm_WARN, xe_assert() is effective only on debug builds
1031975b591SMichal Wajdeczko  * (&CONFIG_DRM_XE_DEBUG must be enabled) and cannot be used in expressions
1041975b591SMichal Wajdeczko  * or as a condition.
1051975b591SMichal Wajdeczko  *
1061975b591SMichal Wajdeczko  * See `Xe ASSERTs`_ for general usage guidelines.
1071975b591SMichal Wajdeczko  */
1081975b591SMichal Wajdeczko #define xe_assert(xe, condition) xe_assert_msg((xe), condition, "")
1091975b591SMichal Wajdeczko #define xe_assert_msg(xe, condition, msg, arg...) ({						\
110babba646SLucas De Marchi 	const struct xe_device *__xe = (xe);							\
1111975b591SMichal Wajdeczko 	__xe_assert_msg(__xe, condition,							\
1120aa25625SMichal Wajdeczko 			"platform: %s subplatform: %d\n"					\
1131975b591SMichal Wajdeczko 			"graphics: %s %u.%02u step %s\n"					\
1141975b591SMichal Wajdeczko 			"media: %s %u.%02u step %s\n"						\
1151975b591SMichal Wajdeczko 			msg,									\
1160aa25625SMichal Wajdeczko 			__xe->info.platform_name, __xe->info.subplatform,			\
1171975b591SMichal Wajdeczko 			__xe->info.graphics_name,						\
1181975b591SMichal Wajdeczko 			__xe->info.graphics_verx100 / 100,					\
1191975b591SMichal Wajdeczko 			__xe->info.graphics_verx100 % 100,					\
1201975b591SMichal Wajdeczko 			xe_step_name(__xe->info.step.graphics),					\
1211975b591SMichal Wajdeczko 			__xe->info.media_name,							\
1221975b591SMichal Wajdeczko 			__xe->info.media_verx100 / 100,						\
1231975b591SMichal Wajdeczko 			__xe->info.media_verx100 % 100,						\
1241975b591SMichal Wajdeczko 			xe_step_name(__xe->info.step.media),					\
1251975b591SMichal Wajdeczko 			## arg);								\
1261975b591SMichal Wajdeczko })
1271975b591SMichal Wajdeczko 
1281975b591SMichal Wajdeczko /**
1291975b591SMichal Wajdeczko  * xe_tile_assert - warn if condition is false when debugging.
1301975b591SMichal Wajdeczko  * @tile: the &struct xe_tile pointer to which &condition applies
1311975b591SMichal Wajdeczko  * @condition: condition to check
1321975b591SMichal Wajdeczko  *
1331975b591SMichal Wajdeczko  * xe_tile_assert() uses &drm_WARN to emit a warning and print additional
1341975b591SMichal Wajdeczko  * information that could be read from the &tile pointer if provided &condition
1351975b591SMichal Wajdeczko  * is false.
1361975b591SMichal Wajdeczko  *
1371975b591SMichal Wajdeczko  * Contrary to &drm_WARN, xe_tile_assert() is effective only on debug builds
1381975b591SMichal Wajdeczko  * (&CONFIG_DRM_XE_DEBUG must be enabled) and cannot be used in expressions
1391975b591SMichal Wajdeczko  * or as a condition.
1401975b591SMichal Wajdeczko  *
1411975b591SMichal Wajdeczko  * See `Xe ASSERTs`_ for general usage guidelines.
1421975b591SMichal Wajdeczko  */
1431975b591SMichal Wajdeczko #define xe_tile_assert(tile, condition) xe_tile_assert_msg((tile), condition, "")
1441975b591SMichal Wajdeczko #define xe_tile_assert_msg(tile, condition, msg, arg...) ({					\
145babba646SLucas De Marchi 	const struct xe_tile *__tile = (tile);							\
1461975b591SMichal Wajdeczko 	char __buf[10] __maybe_unused;								\
1471975b591SMichal Wajdeczko 	xe_assert_msg(tile_to_xe(__tile), condition, "tile: %u VRAM %s\n" msg,			\
1481975b591SMichal Wajdeczko 		      __tile->id, ({ string_get_size(__tile->mem.vram.actual_physical_size, 1,	\
1491975b591SMichal Wajdeczko 				     STRING_UNITS_2, __buf, sizeof(__buf)); __buf; }), ## arg);	\
1501975b591SMichal Wajdeczko })
1511975b591SMichal Wajdeczko 
1521975b591SMichal Wajdeczko /**
1531975b591SMichal Wajdeczko  * xe_gt_assert - warn if condition is false when debugging.
1541975b591SMichal Wajdeczko  * @gt: the &struct xe_gt pointer to which &condition applies
1551975b591SMichal Wajdeczko  * @condition: condition to check
1561975b591SMichal Wajdeczko  *
1571975b591SMichal Wajdeczko  * xe_gt_assert() uses &drm_WARN to emit a warning and print additional
1581975b591SMichal Wajdeczko  * information that could be safetely read from the &gt pointer if provided
1591975b591SMichal Wajdeczko  * &condition is false.
1601975b591SMichal Wajdeczko  *
1611975b591SMichal Wajdeczko  * Contrary to &drm_WARN, xe_gt_assert() is effective only on debug builds
1621975b591SMichal Wajdeczko  * (&CONFIG_DRM_XE_DEBUG must be enabled) and cannot be used in expressions
1631975b591SMichal Wajdeczko  * or as a condition.
1641975b591SMichal Wajdeczko  *
1651975b591SMichal Wajdeczko  * See `Xe ASSERTs`_ for general usage guidelines.
1661975b591SMichal Wajdeczko  */
1671975b591SMichal Wajdeczko #define xe_gt_assert(gt, condition) xe_gt_assert_msg((gt), condition, "")
1681975b591SMichal Wajdeczko #define xe_gt_assert_msg(gt, condition, msg, arg...) ({						\
169babba646SLucas De Marchi 	const struct xe_gt *__gt = (gt);							\
1701975b591SMichal Wajdeczko 	xe_tile_assert_msg(gt_to_tile(__gt), condition, "GT: %u type %d\n" msg,			\
1711975b591SMichal Wajdeczko 			   __gt->info.id, __gt->info.type, ## arg);				\
1721975b591SMichal Wajdeczko })
1731975b591SMichal Wajdeczko 
1741975b591SMichal Wajdeczko #endif
175