diff options
Diffstat (limited to 'include/linux/reservation.h')
| -rw-r--r-- | include/linux/reservation.h | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 813dae960ebd..5a0b64cf68b4 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * Copyright (C) 2012 Texas Instruments | 6 | * Copyright (C) 2012 Texas Instruments |
| 7 | * | 7 | * |
| 8 | * Authors: | 8 | * Authors: |
| 9 | * Rob Clark <rob.clark@linaro.org> | 9 | * Rob Clark <robdclark@gmail.com> |
| 10 | * Maarten Lankhorst <maarten.lankhorst@canonical.com> | 10 | * Maarten Lankhorst <maarten.lankhorst@canonical.com> |
| 11 | * Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 11 | * Thomas Hellstrom <thellstrom-at-vmware-dot-com> |
| 12 | * | 12 | * |
| @@ -40,23 +40,103 @@ | |||
| 40 | #define _LINUX_RESERVATION_H | 40 | #define _LINUX_RESERVATION_H |
| 41 | 41 | ||
| 42 | #include <linux/ww_mutex.h> | 42 | #include <linux/ww_mutex.h> |
| 43 | #include <linux/fence.h> | ||
| 44 | #include <linux/slab.h> | ||
| 45 | #include <linux/seqlock.h> | ||
| 46 | #include <linux/rcupdate.h> | ||
| 43 | 47 | ||
| 44 | extern struct ww_class reservation_ww_class; | 48 | extern struct ww_class reservation_ww_class; |
| 49 | extern struct lock_class_key reservation_seqcount_class; | ||
| 50 | extern const char reservation_seqcount_string[]; | ||
| 51 | |||
| 52 | struct reservation_object_list { | ||
| 53 | struct rcu_head rcu; | ||
| 54 | u32 shared_count, shared_max; | ||
| 55 | struct fence __rcu *shared[]; | ||
| 56 | }; | ||
| 45 | 57 | ||
| 46 | struct reservation_object { | 58 | struct reservation_object { |
| 47 | struct ww_mutex lock; | 59 | struct ww_mutex lock; |
| 60 | seqcount_t seq; | ||
| 61 | |||
| 62 | struct fence __rcu *fence_excl; | ||
| 63 | struct reservation_object_list __rcu *fence; | ||
| 64 | struct reservation_object_list *staged; | ||
| 48 | }; | 65 | }; |
| 49 | 66 | ||
| 67 | #define reservation_object_held(obj) lockdep_is_held(&(obj)->lock.base) | ||
| 68 | #define reservation_object_assert_held(obj) \ | ||
| 69 | lockdep_assert_held(&(obj)->lock.base) | ||
| 70 | |||
| 50 | static inline void | 71 | static inline void |
| 51 | reservation_object_init(struct reservation_object *obj) | 72 | reservation_object_init(struct reservation_object *obj) |
| 52 | { | 73 | { |
| 53 | ww_mutex_init(&obj->lock, &reservation_ww_class); | 74 | ww_mutex_init(&obj->lock, &reservation_ww_class); |
| 75 | |||
| 76 | __seqcount_init(&obj->seq, reservation_seqcount_string, &reservation_seqcount_class); | ||
| 77 | RCU_INIT_POINTER(obj->fence, NULL); | ||
| 78 | RCU_INIT_POINTER(obj->fence_excl, NULL); | ||
| 79 | obj->staged = NULL; | ||
| 54 | } | 80 | } |
| 55 | 81 | ||
| 56 | static inline void | 82 | static inline void |
| 57 | reservation_object_fini(struct reservation_object *obj) | 83 | reservation_object_fini(struct reservation_object *obj) |
| 58 | { | 84 | { |
| 85 | int i; | ||
| 86 | struct reservation_object_list *fobj; | ||
| 87 | struct fence *excl; | ||
| 88 | |||
| 89 | /* | ||
| 90 | * This object should be dead and all references must have | ||
| 91 | * been released to it, so no need to be protected with rcu. | ||
| 92 | */ | ||
| 93 | excl = rcu_dereference_protected(obj->fence_excl, 1); | ||
| 94 | if (excl) | ||
| 95 | fence_put(excl); | ||
| 96 | |||
| 97 | fobj = rcu_dereference_protected(obj->fence, 1); | ||
| 98 | if (fobj) { | ||
| 99 | for (i = 0; i < fobj->shared_count; ++i) | ||
| 100 | fence_put(rcu_dereference_protected(fobj->shared[i], 1)); | ||
| 101 | |||
| 102 | kfree(fobj); | ||
| 103 | } | ||
| 104 | kfree(obj->staged); | ||
| 105 | |||
| 59 | ww_mutex_destroy(&obj->lock); | 106 | ww_mutex_destroy(&obj->lock); |
| 60 | } | 107 | } |
| 61 | 108 | ||
| 109 | static inline struct reservation_object_list * | ||
| 110 | reservation_object_get_list(struct reservation_object *obj) | ||
| 111 | { | ||
| 112 | return rcu_dereference_protected(obj->fence, | ||
| 113 | reservation_object_held(obj)); | ||
| 114 | } | ||
| 115 | |||
| 116 | static inline struct fence * | ||
| 117 | reservation_object_get_excl(struct reservation_object *obj) | ||
| 118 | { | ||
| 119 | return rcu_dereference_protected(obj->fence_excl, | ||
| 120 | reservation_object_held(obj)); | ||
| 121 | } | ||
| 122 | |||
| 123 | int reservation_object_reserve_shared(struct reservation_object *obj); | ||
| 124 | void reservation_object_add_shared_fence(struct reservation_object *obj, | ||
| 125 | struct fence *fence); | ||
| 126 | |||
| 127 | void reservation_object_add_excl_fence(struct reservation_object *obj, | ||
| 128 | struct fence *fence); | ||
| 129 | |||
| 130 | int reservation_object_get_fences_rcu(struct reservation_object *obj, | ||
| 131 | struct fence **pfence_excl, | ||
| 132 | unsigned *pshared_count, | ||
| 133 | struct fence ***pshared); | ||
| 134 | |||
| 135 | long reservation_object_wait_timeout_rcu(struct reservation_object *obj, | ||
| 136 | bool wait_all, bool intr, | ||
| 137 | unsigned long timeout); | ||
| 138 | |||
| 139 | bool reservation_object_test_signaled_rcu(struct reservation_object *obj, | ||
| 140 | bool test_all); | ||
| 141 | |||
| 62 | #endif /* _LINUX_RESERVATION_H */ | 142 | #endif /* _LINUX_RESERVATION_H */ |
