Carl van Schaik | 6d7b2ff | 2018-07-06 22:00:55 +1000 | [diff] [blame] | 1 | /* |
| 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 | */ |
| 34 | static inline struct workqueue_struct * |
| 35 | vs_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 */ |