opnsense-src/sys/ofed/drivers/infiniband/debug/mtrack.h
Hans Petter Selasky b5c1e0cb8d Update the infiniband stack to Mellanox's OFED version 2.1.
Highlights:
 - Multiple verbs API updates
 - Support for RoCE, RDMA over ethernet

All hardware drivers depending on the common infiniband stack has been
updated aswell.

Discussed with:	np @
Sponsored by:	Mellanox Technologies
MFC after:	1 month
2015-02-17 08:40:27 +00:00

844 lines
30 KiB
C

#ifndef __mtrack_h_
#define __mtrack_h_
#include "memtrack.h"
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/kernel.h>
#include <linux/io.h> /* For ioremap_nocache, ioremap, iounmap */
#include <linux/random.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)
# include <linux/io-mapping.h> /* For ioremap_nocache, ioremap, iounmap */
#endif
#include <linux/mm.h> /* For all page handling */
#include <linux/workqueue.h> /* For all work-queue handling */
#include <linux/scatterlist.h> /* For using scatterlists */
#include <linux/skbuff.h> /* For skbufs handling */
#include <asm/uaccess.h> /* For copy from/to user */
#define MEMTRACK_ERROR_INJECTION_MESSAGE(file, line, func) ({ \
printk(KERN_ERR "%s failure injected at %s:%d\n", func, file, line); \
dump_stack(); \
})
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
#define RDMA_KZALLOC_H
#define kzalloc(size, flags) ({ \
void *__memtrack_kz_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kzalloc");\
else \
__memtrack_kz_addr = kmalloc(size, flags); \
if (__memtrack_kz_addr && !is_non_trackable_alloc_func(__func__)) { \
memset(__memtrack_kz_addr, 0, size); \
} \
__memtrack_kz_addr; \
})
#else
#define kzalloc(size, flags) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kzalloc");\
else \
__memtrack_addr = kzalloc(size, flags); \
if (__memtrack_addr && !is_non_trackable_alloc_func(__func__)) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, flags); \
} \
__memtrack_addr; \
})
#endif
#define kzalloc_node(size, flags, node) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kzalloc_node"); \
else \
__memtrack_addr = kzalloc_node(size, flags, node); \
if (__memtrack_addr && (size) && \
!is_non_trackable_alloc_func(__func__)) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, flags); \
} \
__memtrack_addr; \
})
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
#define kcalloc(n, size, flags) kzalloc((n)*(size), flags)
#else
#define kcalloc(n, size, flags) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kcalloc");\
else \
__memtrack_addr = kcalloc(n, size, flags); \
if (__memtrack_addr && (size)) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), (n)*(size), 0UL, 0, __FILE__, __LINE__, flags); \
} \
__memtrack_addr; \
})
#endif
#ifdef ZERO_OR_NULL_PTR
#define kmalloc(sz, flgs) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kmalloc");\
else \
__memtrack_addr = kmalloc(sz, flgs); \
if (!ZERO_OR_NULL_PTR(__memtrack_addr)) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), sz, 0UL, 0, __FILE__, __LINE__, flgs); \
if (memtrack_randomize_mem()) \
get_random_bytes(__memtrack_addr, sz); \
} \
__memtrack_addr; \
})
#else
#define kmalloc(sz, flgs) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kmalloc");\
else \
__memtrack_addr = kmalloc(sz, flgs); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), sz, 0UL, 0, __FILE__, __LINE__, flgs); \
if (memtrack_randomize_mem()) \
get_random_bytes(__memtrack_addr, sz); \
} \
__memtrack_addr; \
})
#endif
#define kmalloc_node(sz, flgs, node) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kmalloc_node"); \
else \
__memtrack_addr = kmalloc_node(sz, flgs, node); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), sz, 0UL, 0, __FILE__, __LINE__, flgs); \
if (memtrack_randomize_mem() && ((flgs) == GFP_KERNEL)) \
get_random_bytes(__memtrack_addr, sz); \
} \
__memtrack_addr; \
})
#ifdef ZERO_OR_NULL_PTR
#define kmemdup(src, sz, flgs) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kmemdup");\
else \
__memtrack_addr = kmemdup(src, sz, flgs); \
if (!ZERO_OR_NULL_PTR(__memtrack_addr)) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), sz, 0UL, 0, __FILE__, __LINE__, flgs); \
} \
__memtrack_addr; \
})
#else
#define kmemdup(src, sz, flgs) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kmemdup");\
else \
__memtrack_addr = kmemdup(src, sz, flgs); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), sz, 0UL, 0, __FILE__, __LINE__, flgs); \
} \
__memtrack_addr; \
})
#endif
#ifdef ZERO_OR_NULL_PTR
#define kfree(addr) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (!ZERO_OR_NULL_PTR(__memtrack_addr) && \
!is_non_trackable_free_func(__func__)) { \
memtrack_free(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
kfree(__memtrack_addr); \
})
#else
#define kfree(addr) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr && !is_non_trackable_free_func(__func__)) { \
memtrack_free(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
kfree(__memtrack_addr); \
})
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) || defined (CONFIG_COMPAT_RCU)
#ifdef kfree_rcu
#undef kfree_rcu
#endif
#ifdef ZERO_OR_NULL_PTR
#define kfree_rcu(addr, rcu_head) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (!ZERO_OR_NULL_PTR(__memtrack_addr) && \
!is_non_trackable_free_func(__func__)) { \
memtrack_free(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
__kfree_rcu(&((addr)->rcu_head), offsetof(typeof(*(addr)), rcu_head)); \
})
#else
#define kfree_rcu(addr, rcu_head) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr && !is_non_trackable_free_func(__func__)) { \
memtrack_free(MEMTRACK_KMALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
__kfree_rcu(&((addr)->rcu_head), offsetof(typeof(*(addr)), rcu_head)); \
})
#endif
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) */
#define vmalloc(size) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "vmalloc");\
else \
__memtrack_addr = vmalloc(size); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_VMALLOC, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
if (memtrack_randomize_mem()) \
get_random_bytes(__memtrack_addr, size); \
} \
__memtrack_addr; \
})
#ifndef vzalloc
#define vzalloc(size) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "vzalloc");\
else \
__memtrack_addr = vzalloc(size); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_VMALLOC, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
__memtrack_addr; \
})
#endif
#ifndef vzalloc_node
#define vzalloc_node(size, node) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "vzalloc_node"); \
else \
__memtrack_addr = vzalloc_node(size, node); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_VMALLOC, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
if (memtrack_randomize_mem()) \
get_random_bytes(__memtrack_addr, size); \
} \
__memtrack_addr; \
})
#endif
#define vmalloc_node(size, node) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "vmalloc_node"); \
else \
__memtrack_addr = vmalloc_node(size, node); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_VMALLOC, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
if (memtrack_randomize_mem()) \
get_random_bytes(__memtrack_addr, size); \
} \
__memtrack_addr; \
})
#define vfree(addr) ({ \
void *__memtrack_addr = (void *)addr; \
if (__memtrack_addr) { \
memtrack_free(MEMTRACK_VMALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
vfree(__memtrack_addr); \
})
#define kmem_cache_alloc(cache, flags) ({ \
void *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "kmem_cache_alloc"); \
else \
__memtrack_addr = kmem_cache_alloc(cache, flags); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_KMEM_OBJ, 0UL, (unsigned long)(__memtrack_addr), 1, 0UL, 0, __FILE__, __LINE__, flags); \
} \
__memtrack_addr; \
})
#define kmem_cache_free(cache, addr) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr) { \
memtrack_free(MEMTRACK_KMEM_OBJ, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
kmem_cache_free(cache, __memtrack_addr); \
})
/* All IO-MAP handling */
#define ioremap(phys_addr, size) ({ \
void __iomem *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "ioremap");\
else \
__memtrack_addr = ioremap(phys_addr, size); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_IOREMAP, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
__memtrack_addr; \
})
#define io_mapping_create_wc(base, size) ({ \
void __iomem *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "io_mapping_create_wc"); \
else \
__memtrack_addr = io_mapping_create_wc(base, size); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_IOREMAP, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
__memtrack_addr; \
})
#define io_mapping_free(addr) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr) { \
memtrack_free(MEMTRACK_IOREMAP, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
io_mapping_free(__memtrack_addr); \
})
#ifdef CONFIG_PPC
#ifdef ioremap_nocache
#undef ioremap_nocache
#endif
#define ioremap_nocache(phys_addr, size) ({ \
void __iomem *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "ioremap_nocache"); \
else \
__memtrack_addr = ioremap(phys_addr, size); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_IOREMAP, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
__memtrack_addr; \
})
#else
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) /* 2.6.16 - 2.6.17 */
#ifdef ioremap_nocache
#undef ioremap_nocache
#endif
#define ioremap_nocache(phys_addr, size) ({ \
void __iomem *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "ioremap_nocache"); \
else \
__memtrack_addr = ioremap(phys_addr, size); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_IOREMAP, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
__memtrack_addr; \
})
#else
#define ioremap_nocache(phys_addr, size) ({ \
void __iomem *__memtrack_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "ioremap_nocache"); \
else \
__memtrack_addr = ioremap_nocache(phys_addr, size); \
if (__memtrack_addr) { \
memtrack_alloc(MEMTRACK_IOREMAP, 0UL, (unsigned long)(__memtrack_addr), size, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
__memtrack_addr; \
})
#endif /* Kernel version is under 2.6.18 */
#endif /* PPC */
#define iounmap(addr) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr) { \
memtrack_free(MEMTRACK_IOREMAP, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
iounmap(__memtrack_addr); \
})
/* All Page handlers */
/* TODO: Catch netif_rx for page dereference */
#define alloc_pages_node(nid, gfp_mask, order) ({ \
struct page *page_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "alloc_pages_node"); \
else \
page_addr = (struct page *)alloc_pages_node(nid, gfp_mask, order); \
if (page_addr && !is_non_trackable_alloc_func(__func__)) { \
memtrack_alloc(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(page_addr), (unsigned long)(order), 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
page_addr; \
})
#ifdef CONFIG_NUMA
#define alloc_pages(gfp_mask, order) ({ \
struct page *page_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "alloc_pages"); \
else \
page_addr = (struct page *)alloc_pages(gfp_mask, order); \
if (page_addr && !is_non_trackable_alloc_func(__func__)) { \
memtrack_alloc(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(page_addr), (unsigned long)(order), 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
page_addr; \
})
#else
#ifdef alloc_pages
#undef alloc_pages
#endif
#define alloc_pages(gfp_mask, order) ({ \
struct page *page_addr; \
\
page_addr = (struct page *)alloc_pages_node(numa_node_id(), gfp_mask, order); \
page_addr; \
})
#endif
#define __get_free_pages(gfp_mask, order) ({ \
struct page *page_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "__get_free_pages"); \
else \
page_addr = (struct page *)__get_free_pages(gfp_mask, order); \
if (page_addr && !is_non_trackable_alloc_func(__func__)) { \
memtrack_alloc(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(page_addr), (unsigned long)(order), 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
page_addr; \
})
#define get_zeroed_page(gfp_mask) ({ \
struct page *page_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "get_zeroed_page"); \
else \
page_addr = (struct page *)get_zeroed_page(gfp_mask); \
if (page_addr && !is_non_trackable_alloc_func(__func__)) { \
memtrack_alloc(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(page_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
(unsigned long)page_addr; \
})
#define __free_pages(addr, order) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr && !is_non_trackable_alloc_func(__func__)) { \
if (!memtrack_check_size(MEMTRACK_PAGE_ALLOC, (unsigned long)(__memtrack_addr), (unsigned long)(order), __FILE__, __LINE__)) \
memtrack_free(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
__free_pages(addr, order); \
})
#define free_pages(addr, order) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr && !is_non_trackable_alloc_func(__func__)) { \
if (!memtrack_check_size(MEMTRACK_PAGE_ALLOC, (unsigned long)(__memtrack_addr), (unsigned long)(order), __FILE__, __LINE__)) \
memtrack_free(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
free_pages(addr, order); \
})
#define get_page(addr) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr && !is_non_trackable_alloc_func(__func__)) { \
if (memtrack_is_new_addr(MEMTRACK_PAGE_ALLOC, (unsigned long)(__memtrack_addr), 0, __FILE__, __LINE__)) { \
memtrack_alloc(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(__memtrack_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
} \
get_page(addr); \
})
#define get_user_pages_fast(start, nr_pages, write, pages) ({ \
int __memtrack_rc = -1; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "get_user_pages_fast"); \
else \
__memtrack_rc = get_user_pages_fast(start, nr_pages, write, pages); \
if (__memtrack_rc > 0 && !is_non_trackable_alloc_func(__func__)) { \
int __memtrack_i; \
\
for (__memtrack_i = 0; __memtrack_i < __memtrack_rc; __memtrack_i++) \
memtrack_alloc(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(pages[__memtrack_i]), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
__memtrack_rc; \
})
#define put_page(addr) ({ \
void *__memtrack_addr = (void *)addr; \
\
if (__memtrack_addr && !is_non_trackable_alloc_func(__func__)) { \
/* Check whether this is not part of umem put page & not */\
/* a new addr and the ref-count is 1 then we'll free this addr */\
/* Don't change the order these conditions */ \
if (!is_umem_put_page(__func__) && \
!memtrack_is_new_addr(MEMTRACK_PAGE_ALLOC, (unsigned long)(__memtrack_addr), 1, __FILE__, __LINE__) && \
(memtrack_get_page_ref_count((unsigned long)(__memtrack_addr)) == 1)) { \
memtrack_free(MEMTRACK_PAGE_ALLOC, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
} \
put_page(addr); \
})
/* Work-Queue handlers */
#ifdef create_workqueue
#undef create_workqueue
#endif
#ifdef create_rt_workqueue
#undef create_rt_workqueue
#endif
#ifdef create_freezeable_workqueue
#undef create_freezeable_workqueue
#endif
#ifdef create_singlethread_workqueue
#undef create_singlethread_workqueue
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) /* 2.6.18 - 2.6.19 */
#define create_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_workqueue"); \
else \
wq_addr = __create_workqueue((name), 0); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#define create_singlethread_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_singlethread_workqueue"); \
else \
wq_addr = __create_workqueue((name), 1); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) /* 2.6.20 - 2.6.27 */
#define create_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_workqueue"); \
else \
wq_addr = __create_workqueue((name), 0, 0); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) /* 2.6.20 - 2.6.21 */
#define create_freezeable_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_freezeable_workqueue"); \
else \
wq_addr = __create_workqueue((name), 0, 1); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#else /* 2.6.22 - 2.6.27 */
#define create_freezeable_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_freezeable_workqueue"); \
else \
wq_addr = __create_workqueue((name), 1, 1); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#endif /* 2.6.20 - 2.6.27 */
#define create_singlethread_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_singlethread_workqueue"); \
else \
wq_addr = __create_workqueue((name), 1, 0); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) /* 2.6.28 - 2.6.35 */
#ifdef alloc_workqueue
#undef alloc_workqueue
#endif
#define alloc_workqueue(name, flags, max_active) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "alloc_workqueue"); \
else \
wq_addr = __create_workqueue((name), (flags), (max_active), 0); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#define create_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_workqueue"); \
else \
wq_addr = __create_workqueue((name), 0, 0, 0); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#define create_rt_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_rt_workqueue"); \
else \
wq_addr = __create_workqueue((name), 0, 0, 1); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#define create_freezeable_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_freezeable_workqueue"); \
else \
wq_addr = __create_workqueue((name), 1, 1, 0); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#define create_singlethread_workqueue(name) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "create_singlethread_workqueue"); \
else \
wq_addr = __create_workqueue((name), 1, 0, 0); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#else /* 2.6.36 */
#ifdef alloc_workqueue
#undef alloc_workqueue
#endif
#ifdef CONFIG_LOCKDEP
#define alloc_workqueue(name, flags, max_active) \
({ \
static struct lock_class_key __key; \
const char *__lock_name; \
struct workqueue_struct *wq_addr = NULL; \
\
if (__builtin_constant_p(name)) \
__lock_name = (name); \
else \
__lock_name = #name; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "alloc_workqueue"); \
else \
wq_addr = __alloc_workqueue_key((name), (flags), (max_active), \
&__key, __lock_name); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#else
#define alloc_workqueue(name, flags, max_active) ({ \
struct workqueue_struct *wq_addr = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "alloc_workqueue"); \
else \
wq_addr = __alloc_workqueue_key((name), (flags), (max_active), NULL, NULL); \
if (wq_addr) { \
memtrack_alloc(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(wq_addr), 0, 0UL, 0, __FILE__, __LINE__, GFP_ATOMIC); \
} \
wq_addr; \
})
#endif
#define create_workqueue(name) \
alloc_workqueue((name), WQ_RESCUER, 1);
#define create_freezeable_workqueue(name) \
alloc_workqueue((name), WQ_FREEZEABLE | WQ_UNBOUND | WQ_RESCUER, 1);
#define create_singlethread_workqueue(name) \
alloc_workqueue((name), WQ_UNBOUND | WQ_RESCUER, 1);
#endif /* Work-Queue Kernel Versions */
#define destroy_workqueue(wq_addr) ({ \
void *__memtrack_addr = (void *)wq_addr; \
\
if (__memtrack_addr) { \
memtrack_free(MEMTRACK_WORK_QUEUE, 0UL, (unsigned long)(__memtrack_addr), 0UL, 0, __FILE__, __LINE__); \
} \
destroy_workqueue(wq_addr); \
})
/* ONLY error injection to functions that we don't monitor */
#define alloc_skb(size, prio) ({ \
struct sk_buff *__memtrack_skb = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "alloc_skb"); \
else \
__memtrack_skb = alloc_skb(size, prio); \
__memtrack_skb; \
})
#define dev_alloc_skb(size) ({ \
struct sk_buff *__memtrack_skb = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "dev_alloc_skb"); \
else \
__memtrack_skb = dev_alloc_skb(size); \
__memtrack_skb; \
})
#define alloc_skb_fclone(size, prio) ({ \
struct sk_buff *__memtrack_skb = NULL; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "alloc_skb_fclone"); \
else \
__memtrack_skb = alloc_skb_fclone(size, prio); \
__memtrack_skb; \
})
#define copy_from_user(to, from, n) ({ \
int ret = n; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "copy_from_user"); \
else \
ret = copy_from_user(to, from, n); \
ret; \
})
#define copy_to_user(to, from, n) ({ \
int ret = n; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "copy_to_user"); \
else \
ret = copy_to_user(to, from, n); \
ret; \
})
#define sysfs_create_file(kobj, attr) ({ \
int ret = -ENOSYS; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "sysfs_create_file"); \
else \
ret = sysfs_create_file(kobj, attr); \
ret; \
})
#define sysfs_create_link(kobj, target, name) ({ \
int ret = -ENOSYS; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "sysfs_create_link"); \
else \
ret = sysfs_create_link(kobj, target, name); \
ret; \
})
#define sysfs_create_group(kobj, grp) ({ \
int ret = -ENOSYS; \
\
if (memtrack_inject_error()) \
MEMTRACK_ERROR_INJECTION_MESSAGE(__FILE__, __LINE__, "sysfs_create_group"); \
else \
ret = sysfs_create_group(kobj, grp); \
ret; \
})
#endif /* __mtrack_h_ */