140b326eeSChris Wilson /* 240b326eeSChris Wilson * Copyright © 2016 Intel Corporation 340b326eeSChris Wilson * 440b326eeSChris Wilson * Permission is hereby granted, free of charge, to any person obtaining a 540b326eeSChris Wilson * copy of this software and associated documentation files (the "Software"), 640b326eeSChris Wilson * to deal in the Software without restriction, including without limitation 740b326eeSChris Wilson * the rights to use, copy, modify, merge, publish, distribute, sublicense, 840b326eeSChris Wilson * and/or sell copies of the Software, and to permit persons to whom the 940b326eeSChris Wilson * Software is furnished to do so, subject to the following conditions: 1040b326eeSChris Wilson * 1140b326eeSChris Wilson * The above copyright notice and this permission notice (including the next 1240b326eeSChris Wilson * paragraph) shall be included in all copies or substantial portions of the 1340b326eeSChris Wilson * Software. 1440b326eeSChris Wilson * 1540b326eeSChris Wilson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1640b326eeSChris Wilson * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1740b326eeSChris Wilson * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1840b326eeSChris Wilson * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1940b326eeSChris Wilson * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2040b326eeSChris Wilson * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2140b326eeSChris Wilson * IN THE SOFTWARE. 2240b326eeSChris Wilson * 2340b326eeSChris Wilson */ 2440b326eeSChris Wilson 2540b326eeSChris Wilson #ifndef __I915_UTILS_H 2640b326eeSChris Wilson #define __I915_UTILS_H 2740b326eeSChris Wilson 28f0d66153SMichal Wajdeczko #undef WARN_ON 29f0d66153SMichal Wajdeczko /* Many gcc seem to no see through this and fall over :( */ 30f0d66153SMichal Wajdeczko #if 0 31f0d66153SMichal Wajdeczko #define WARN_ON(x) ({ \ 32f0d66153SMichal Wajdeczko bool __i915_warn_cond = (x); \ 33f0d66153SMichal Wajdeczko if (__builtin_constant_p(__i915_warn_cond)) \ 34f0d66153SMichal Wajdeczko BUILD_BUG_ON(__i915_warn_cond); \ 35f0d66153SMichal Wajdeczko WARN(__i915_warn_cond, "WARN_ON(" #x ")"); }) 36f0d66153SMichal Wajdeczko #else 37f0d66153SMichal Wajdeczko #define WARN_ON(x) WARN((x), "%s", "WARN_ON(" __stringify(x) ")") 38f0d66153SMichal Wajdeczko #endif 39f0d66153SMichal Wajdeczko 40f0d66153SMichal Wajdeczko #undef WARN_ON_ONCE 41f0d66153SMichal Wajdeczko #define WARN_ON_ONCE(x) WARN_ONCE((x), "%s", "WARN_ON_ONCE(" __stringify(x) ")") 42f0d66153SMichal Wajdeczko 4357bdff48SLucas De Marchi #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ 4457bdff48SLucas De Marchi __stringify(x), (long)(x)) 45f0d66153SMichal Wajdeczko 46*815f0ddbSNick Desaulniers #if defined(GCC_VERSION) && GCC_VERSION >= 70000 471692cd60SChris Wilson #define add_overflows(A, B) \ 481692cd60SChris Wilson __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0) 491692cd60SChris Wilson #else 501692cd60SChris Wilson #define add_overflows(A, B) ({ \ 511692cd60SChris Wilson typeof(A) a = (A); \ 521692cd60SChris Wilson typeof(B) b = (B); \ 531692cd60SChris Wilson a + b < a; \ 541692cd60SChris Wilson }) 551692cd60SChris Wilson #endif 561692cd60SChris Wilson 5740b326eeSChris Wilson #define range_overflows(start, size, max) ({ \ 5840b326eeSChris Wilson typeof(start) start__ = (start); \ 5940b326eeSChris Wilson typeof(size) size__ = (size); \ 6040b326eeSChris Wilson typeof(max) max__ = (max); \ 6140b326eeSChris Wilson (void)(&start__ == &size__); \ 6240b326eeSChris Wilson (void)(&start__ == &max__); \ 6340b326eeSChris Wilson start__ > max__ || size__ > max__ - start__; \ 6440b326eeSChris Wilson }) 6540b326eeSChris Wilson 6640b326eeSChris Wilson #define range_overflows_t(type, start, size, max) \ 6740b326eeSChris Wilson range_overflows((type)(start), (type)(size), (type)(max)) 6840b326eeSChris Wilson 6940b326eeSChris Wilson /* Note we don't consider signbits :| */ 7040b326eeSChris Wilson #define overflows_type(x, T) \ 7140b326eeSChris Wilson (sizeof(x) > sizeof(T) && (x) >> (sizeof(T) * BITS_PER_BYTE)) 7240b326eeSChris Wilson 730ce81788SChris Wilson #define ptr_mask_bits(ptr, n) ({ \ 74b7163936SChris Wilson unsigned long __v = (unsigned long)(ptr); \ 750ce81788SChris Wilson (typeof(ptr))(__v & -BIT(n)); \ 76b7163936SChris Wilson }) 77b7163936SChris Wilson 780ce81788SChris Wilson #define ptr_unmask_bits(ptr, n) ((unsigned long)(ptr) & (BIT(n) - 1)) 790ce81788SChris Wilson 800ce81788SChris Wilson #define ptr_unpack_bits(ptr, bits, n) ({ \ 81b7163936SChris Wilson unsigned long __v = (unsigned long)(ptr); \ 820ce81788SChris Wilson *(bits) = __v & (BIT(n) - 1); \ 830ce81788SChris Wilson (typeof(ptr))(__v & -BIT(n)); \ 84b7163936SChris Wilson }) 85b7163936SChris Wilson 862d751415STvrtko Ursulin #define ptr_pack_bits(ptr, bits, n) ({ \ 872d751415STvrtko Ursulin unsigned long __bits = (bits); \ 882d751415STvrtko Ursulin GEM_BUG_ON(__bits & -BIT(n)); \ 892d751415STvrtko Ursulin ((typeof(ptr))((unsigned long)(ptr) | __bits)); \ 902d751415STvrtko Ursulin }) 91b7163936SChris Wilson 920ce81788SChris Wilson #define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT) 930ce81788SChris Wilson #define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT) 940ce81788SChris Wilson #define page_pack_bits(ptr, bits) ptr_pack_bits(ptr, bits, PAGE_SHIFT) 950ce81788SChris Wilson #define page_unpack_bits(ptr, bits) ptr_unpack_bits(ptr, bits, PAGE_SHIFT) 960ce81788SChris Wilson 9716f11f46SMichal Wajdeczko #define ptr_offset(ptr, member) offsetof(typeof(*(ptr)), member) 9816f11f46SMichal Wajdeczko 99b7163936SChris Wilson #define fetch_and_zero(ptr) ({ \ 100b7163936SChris Wilson typeof(*ptr) __T = *(ptr); \ 101b7163936SChris Wilson *(ptr) = (typeof(*ptr))0; \ 102b7163936SChris Wilson __T; \ 103b7163936SChris Wilson }) 104b7163936SChris Wilson 105bb8920f5SMichal Wajdeczko static inline u64 ptr_to_u64(const void *ptr) 106bb8920f5SMichal Wajdeczko { 107bb8920f5SMichal Wajdeczko return (uintptr_t)ptr; 108bb8920f5SMichal Wajdeczko } 109bb8920f5SMichal Wajdeczko 1104ff4b44cSChris Wilson #define u64_to_ptr(T, x) ({ \ 1114ff4b44cSChris Wilson typecheck(u64, x); \ 1124ff4b44cSChris Wilson (T *)(uintptr_t)(x); \ 1134ff4b44cSChris Wilson }) 1144ff4b44cSChris Wilson 11516586fcdSMichal Wajdeczko #define __mask_next_bit(mask) ({ \ 11616586fcdSMichal Wajdeczko int __idx = ffs(mask) - 1; \ 11716586fcdSMichal Wajdeczko mask &= ~BIT(__idx); \ 11816586fcdSMichal Wajdeczko __idx; \ 11916586fcdSMichal Wajdeczko }) 12016586fcdSMichal Wajdeczko 1216c067579SChris Wilson #include <linux/list.h> 1226c067579SChris Wilson 123b887d615SChris Wilson static inline int list_is_first(const struct list_head *list, 124b887d615SChris Wilson const struct list_head *head) 125b887d615SChris Wilson { 126b887d615SChris Wilson return head->next == list; 127b887d615SChris Wilson } 128b887d615SChris Wilson 1296c067579SChris Wilson static inline void __list_del_many(struct list_head *head, 1306c067579SChris Wilson struct list_head *first) 1316c067579SChris Wilson { 1326c067579SChris Wilson first->prev = head; 1336c067579SChris Wilson WRITE_ONCE(head->next, first); 1346c067579SChris Wilson } 1356c067579SChris Wilson 1367c26240eSChris Wilson /* 1377c26240eSChris Wilson * Wait until the work is finally complete, even if it tries to postpone 1387c26240eSChris Wilson * by requeueing itself. Note, that if the worker never cancels itself, 1397c26240eSChris Wilson * we will spin forever. 1407c26240eSChris Wilson */ 1417c26240eSChris Wilson static inline void drain_delayed_work(struct delayed_work *dw) 1427c26240eSChris Wilson { 1437c26240eSChris Wilson do { 1447c26240eSChris Wilson while (flush_delayed_work(dw)) 1457c26240eSChris Wilson ; 1467c26240eSChris Wilson } while (delayed_work_pending(dw)); 1477c26240eSChris Wilson } 1487c26240eSChris Wilson 149b74eeeb6SMichal Wajdeczko static inline const char *yesno(bool v) 150b74eeeb6SMichal Wajdeczko { 151b74eeeb6SMichal Wajdeczko return v ? "yes" : "no"; 152b74eeeb6SMichal Wajdeczko } 153b74eeeb6SMichal Wajdeczko 154b74eeeb6SMichal Wajdeczko static inline const char *onoff(bool v) 155b74eeeb6SMichal Wajdeczko { 156b74eeeb6SMichal Wajdeczko return v ? "on" : "off"; 157b74eeeb6SMichal Wajdeczko } 158b74eeeb6SMichal Wajdeczko 159b74eeeb6SMichal Wajdeczko static inline const char *enableddisabled(bool v) 160b74eeeb6SMichal Wajdeczko { 161b74eeeb6SMichal Wajdeczko return v ? "enabled" : "disabled"; 162b74eeeb6SMichal Wajdeczko } 163b74eeeb6SMichal Wajdeczko 16440b326eeSChris Wilson #endif /* !__I915_UTILS_H */ 165