.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note |
---|
2 | 2 | /* |
---|
3 | 3 | * |
---|
4 | | - * (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved. |
---|
| 4 | + * (C) COPYRIGHT 2019-2022 ARM Limited. All rights reserved. |
---|
5 | 5 | * |
---|
6 | 6 | * This program is free software and is provided to you under the terms of the |
---|
7 | 7 | * GNU General Public License version 2 as published by the Free Software |
---|
.. | .. |
---|
45 | 45 | #include <linux/slab.h> |
---|
46 | 46 | #include <linux/spinlock.h> |
---|
47 | 47 | #include <linux/version.h> |
---|
| 48 | +#include <linux/version_compat_defs.h> |
---|
48 | 49 | #include <linux/wait.h> |
---|
49 | 50 | |
---|
| 51 | +/* Explicitly include epoll header for old kernels. Not required from 4.16. */ |
---|
| 52 | +#if KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE |
---|
| 53 | +#include <uapi/linux/eventpoll.h> |
---|
| 54 | +#endif |
---|
| 55 | + |
---|
| 56 | +/* Define static_assert(). |
---|
| 57 | + * |
---|
| 58 | + * The macro was introduced in kernel 5.1. But older vendor kernels may define |
---|
| 59 | + * it too. |
---|
| 60 | + */ |
---|
50 | 61 | #if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE |
---|
51 | 62 | #include <linux/build_bug.h> |
---|
52 | | -#else |
---|
| 63 | +#elif !defined(static_assert) |
---|
53 | 64 | // Stringify the expression if no message is given. |
---|
54 | 65 | #define static_assert(e, ...) __static_assert(e, #__VA_ARGS__, #e) |
---|
55 | 66 | #define __static_assert(e, msg, ...) _Static_assert(e, msg) |
---|
56 | | -#endif |
---|
57 | | - |
---|
58 | | -#if KERNEL_VERSION(4, 16, 0) >= LINUX_VERSION_CODE |
---|
59 | | -typedef unsigned int __poll_t; |
---|
60 | | -#endif |
---|
61 | | - |
---|
62 | | -#ifndef ENOTSUP |
---|
63 | | -#define ENOTSUP EOPNOTSUPP |
---|
64 | 67 | #endif |
---|
65 | 68 | |
---|
66 | 69 | /* The module printing prefix */ |
---|
.. | .. |
---|
204 | 207 | */ |
---|
205 | 208 | static inline bool reader_changes_is_valid_size(const size_t size) |
---|
206 | 209 | { |
---|
207 | | - typedef struct reader_changes changes_t; |
---|
208 | | - const size_t elem_size = sizeof(*((changes_t *)0)->data); |
---|
209 | | - const size_t size_size = sizeof(((changes_t *)0)->size); |
---|
| 210 | + const size_t elem_size = sizeof(*((struct reader_changes *)0)->data); |
---|
| 211 | + const size_t size_size = sizeof(((struct reader_changes *)0)->size); |
---|
210 | 212 | const size_t size_max = (1ull << (size_size * 8)) - 1; |
---|
211 | 213 | |
---|
212 | 214 | return is_power_of_2(size) && /* Is a power of two */ |
---|
.. | .. |
---|
223 | 225 | * |
---|
224 | 226 | * Return: |
---|
225 | 227 | * (0, U16_MAX] - the number of data elements allocated |
---|
226 | | - * -EINVAL - a pointer was invalid |
---|
227 | | - * -ENOTSUP - we do not support allocation of the context |
---|
228 | 228 | * -ERANGE - the requested memory size was invalid |
---|
229 | 229 | * -ENOMEM - could not allocate the memory |
---|
230 | | - * -EADDRINUSE - the buffer memory was already allocated |
---|
231 | 230 | */ |
---|
232 | 231 | static int reader_changes_init(struct reader_changes *const changes, |
---|
233 | 232 | const size_t size) |
---|
.. | .. |
---|
622 | 621 | * |
---|
623 | 622 | * Return: |
---|
624 | 623 | * * 0 - no data ready |
---|
625 | | - * * POLLIN - state changes have been buffered |
---|
626 | | - * * -EBADF - the file descriptor did not have an attached reader |
---|
627 | | - * * -EINVAL - the IO control arguments were invalid |
---|
| 624 | + * * EPOLLIN | EPOLLRDNORM - state changes have been buffered |
---|
| 625 | + * * EPOLLHUP | EPOLLERR - IO control arguments were invalid or the file |
---|
| 626 | + * descriptor did not have an attached reader. |
---|
628 | 627 | */ |
---|
629 | 628 | static __poll_t reader_poll(struct file *const file, |
---|
630 | 629 | struct poll_table_struct *const wait) |
---|
631 | 630 | { |
---|
632 | 631 | struct reader *reader; |
---|
633 | 632 | struct reader_changes *changes; |
---|
| 633 | + __poll_t mask = 0; |
---|
634 | 634 | |
---|
635 | 635 | if (unlikely(!file || !wait)) |
---|
636 | | - return -EINVAL; |
---|
| 636 | + return EPOLLHUP | EPOLLERR; |
---|
637 | 637 | |
---|
638 | 638 | reader = file->private_data; |
---|
639 | 639 | if (unlikely(!reader)) |
---|
640 | | - return -EBADF; |
---|
| 640 | + return EPOLLHUP | EPOLLERR; |
---|
641 | 641 | |
---|
642 | 642 | changes = &reader->changes; |
---|
643 | | - |
---|
644 | 643 | if (reader_changes_count(changes) >= changes->threshold) |
---|
645 | | - return POLLIN; |
---|
| 644 | + return EPOLLIN | EPOLLRDNORM; |
---|
646 | 645 | |
---|
647 | 646 | poll_wait(file, &reader->wait_queue, wait); |
---|
648 | 647 | |
---|
649 | | - return (reader_changes_count(changes) > 0) ? POLLIN : 0; |
---|
| 648 | + if (reader_changes_count(changes) > 0) |
---|
| 649 | + mask |= EPOLLIN | EPOLLRDNORM; |
---|
| 650 | + |
---|
| 651 | + return mask; |
---|
650 | 652 | } |
---|
651 | 653 | |
---|
652 | 654 | /* The file operations virtual function table */ |
---|
.. | .. |
---|
662 | 664 | static const size_t kbase_kinstr_jm_readers_max = 16; |
---|
663 | 665 | |
---|
664 | 666 | /** |
---|
665 | | - * kbasep_kinstr_jm_release() - Invoked when the reference count is dropped |
---|
| 667 | + * kbase_kinstr_jm_release() - Invoked when the reference count is dropped |
---|
666 | 668 | * @ref: the context reference count |
---|
667 | 669 | */ |
---|
668 | 670 | static void kbase_kinstr_jm_release(struct kref *const ref) |
---|
.. | .. |
---|
733 | 735 | } |
---|
734 | 736 | |
---|
735 | 737 | /** |
---|
736 | | - * readers_del() - Deletes a reader from the list of readers |
---|
| 738 | + * kbase_kinstr_jm_readers_del() - Deletes a reader from the list of readers |
---|
737 | 739 | * @ctx: the instrumentation context |
---|
738 | 740 | * @reader: the reader to delete |
---|
739 | 741 | */ |
---|
.. | .. |
---|
812 | 814 | kbase_kinstr_jm_ref_put(ctx); |
---|
813 | 815 | } |
---|
814 | 816 | |
---|
815 | | -/** |
---|
816 | | - * timestamp() - Retrieves the current monotonic nanoseconds |
---|
817 | | - * Return: monotonic nanoseconds timestamp. |
---|
818 | | - */ |
---|
819 | | -static u64 timestamp(void) |
---|
820 | | -{ |
---|
821 | | - struct timespec ts; |
---|
822 | | - long ns; |
---|
823 | | - |
---|
824 | | - getrawmonotonic(&ts); |
---|
825 | | - ns = ((long)(ts.tv_sec) * NSEC_PER_SEC) + ts.tv_nsec; |
---|
826 | | - if (unlikely(ns < 0)) |
---|
827 | | - return 0; |
---|
828 | | - return ((u64)(ns)); |
---|
829 | | -} |
---|
830 | | - |
---|
831 | 817 | void kbasep_kinstr_jm_atom_state( |
---|
832 | 818 | struct kbase_jd_atom *const katom, |
---|
833 | 819 | const enum kbase_kinstr_jm_reader_atom_state state) |
---|
.. | .. |
---|
836 | 822 | struct kbase_kinstr_jm *const ctx = kctx->kinstr_jm; |
---|
837 | 823 | const u8 id = kbase_jd_atom_id(kctx, katom); |
---|
838 | 824 | struct kbase_kinstr_jm_atom_state_change change = { |
---|
839 | | - .timestamp = timestamp(), .atom = id, .state = state |
---|
| 825 | + .timestamp = ktime_get_raw_ns(), .atom = id, .state = state |
---|
840 | 826 | }; |
---|
841 | 827 | struct reader *reader; |
---|
842 | 828 | struct hlist_bl_node *node; |
---|