blob: 5f6926dc9f78ceb7643bee319dd3921a834c0cbc [file] [log] [blame]
Carl van Schaik6d7b2ff2018-07-06 22:00:55 +10001/*
2 * drivers/vservices/compat.h
3 *
4 * Copyright (c) 2012-2018 General Dynamics
5 * Copyright (c) 2014 Open Kernel Labs, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Wrapper functions/definitions for compatibility between differnet kernel
12 * versions.
13 */
14
15#ifndef _VSERVICES_COMPAT_H
16#define _VSERVICES_COMPAT_H
17
18#include <linux/workqueue.h>
19#include <linux/version.h>
20
21/* The INIT_WORK_ONSTACK macro has a slightly different name in older kernels */
22#ifndef INIT_WORK_ONSTACK
23#define INIT_WORK_ONSTACK(_work, _func) INIT_WORK_ON_STACK(_work, _func)
24#endif
25
26/*
27 * We require a workqueue with no concurrency. This is provided by
28 * create_singlethread_workqueue() in kernel prior to 2.6.36.
29 * In later versions, create_singlethread_workqueue() enables WQ_MEM_RECLAIM and
30 * thus WQ_RESCUER, which allows work items to be grabbed by a rescuer thread
31 * and run concurrently if the queue is running too slowly. We must use
32 * alloc_ordered_workqueue() instead, to disable the rescuer.
33 */
34static inline struct workqueue_struct *
35vs_create_workqueue(const char *name)
36{
37#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
38 return create_singlethread_workqueue(name);
39#else
40 return alloc_ordered_workqueue(name, 0);
41#endif
42}
43
44/*
45 * The max3 macro has only been present from 2.6.37
46 * (commit: f27c85c56b32c42bcc54a43189c1e00fdceb23ec)
47 */
48#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
49#define max3(x, y, z) ({ \
50 typeof(x) _max1 = (x); \
51 typeof(y) _max2 = (y); \
52 typeof(z) _max3 = (z); \
53 (void) (&_max1 == &_max2); \
54 (void) (&_max1 == &_max3); \
55 _max1 > _max2 ? (_max1 > _max3 ? _max1 : _max3) : \
56 (_max2 > _max3 ? _max2 : _max3); })
57#endif
58
59#endif /* _VSERVICES_COMPAT_H */