Line data Source code
1 : /*
2 : * Header file for reservations for dma-buf and ttm
3 : *
4 : * Copyright(C) 2011 Linaro Limited. All rights reserved.
5 : * Copyright (C) 2012-2013 Canonical Ltd
6 : * Copyright (C) 2012 Texas Instruments
7 : *
8 : * Authors:
9 : * Rob Clark <robdclark@gmail.com>
10 : * Maarten Lankhorst <maarten.lankhorst@canonical.com>
11 : * Thomas Hellstrom <thellstrom-at-vmware-dot-com>
12 : *
13 : * Based on bo.c which bears the following copyright notice,
14 : * but is dual licensed:
15 : *
16 : * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
17 : * All Rights Reserved.
18 : *
19 : * Permission is hereby granted, free of charge, to any person obtaining a
20 : * copy of this software and associated documentation files (the
21 : * "Software"), to deal in the Software without restriction, including
22 : * without limitation the rights to use, copy, modify, merge, publish,
23 : * distribute, sub license, and/or sell copies of the Software, and to
24 : * permit persons to whom the Software is furnished to do so, subject to
25 : * the following conditions:
26 : *
27 : * The above copyright notice and this permission notice (including the
28 : * next paragraph) shall be included in all copies or substantial portions
29 : * of the Software.
30 : *
31 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 : * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
34 : * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
35 : * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
36 : * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
37 : * USE OR OTHER DEALINGS IN THE SOFTWARE.
38 : */
39 : #ifndef _LINUX_RESERVATION_H
40 : #define _LINUX_RESERVATION_H
41 :
42 : #include <dev/pci/drm/drm_linux.h>
43 : #include <dev/pci/drm/linux_ww_mutex.h>
44 : #include <dev/pci/drm/linux_rcupdate.h>
45 :
46 : extern struct ww_class reservation_ww_class;
47 : extern struct lock_class_key reservation_seqcount_class;
48 : extern const char reservation_seqcount_string[];
49 :
50 : struct reservation_object_list {
51 : struct rcu_head rcu;
52 : u32 shared_count, shared_max;
53 : struct fence __rcu *shared[];
54 : };
55 :
56 : struct reservation_object {
57 : struct ww_mutex lock;
58 : seqcount_t seq;
59 :
60 : struct fence __rcu *fence_excl;
61 : struct reservation_object_list __rcu *fence;
62 : struct reservation_object_list *staged;
63 : };
64 :
65 : #define reservation_object_held(obj) lockdep_is_held(&(obj)->lock.base)
66 : #define reservation_object_assert_held(obj) \
67 : lockdep_assert_held(&(obj)->lock.base)
68 :
69 : static inline void
70 0 : reservation_object_init(struct reservation_object *obj)
71 : {
72 0 : ww_mutex_init(&obj->lock, &reservation_ww_class);
73 :
74 0 : __seqcount_init(&obj->seq, reservation_seqcount_string, &reservation_seqcount_class);
75 0 : RCU_INIT_POINTER(obj->fence, NULL);
76 0 : RCU_INIT_POINTER(obj->fence_excl, NULL);
77 0 : obj->staged = NULL;
78 0 : }
79 :
80 : static inline void
81 0 : reservation_object_fini(struct reservation_object *obj)
82 : {
83 : int i;
84 : struct reservation_object_list *fobj;
85 : struct fence *excl;
86 :
87 : /*
88 : * This object should be dead and all references must have
89 : * been released to it, so no need to be protected with rcu.
90 : */
91 0 : excl = rcu_dereference_protected(obj->fence_excl, 1);
92 0 : if (excl)
93 0 : fence_put(excl);
94 :
95 0 : fobj = rcu_dereference_protected(obj->fence, 1);
96 0 : if (fobj) {
97 0 : for (i = 0; i < fobj->shared_count; ++i)
98 0 : fence_put(rcu_dereference_protected(fobj->shared[i], 1));
99 :
100 0 : kfree(fobj);
101 0 : }
102 0 : kfree(obj->staged);
103 :
104 0 : ww_mutex_destroy(&obj->lock);
105 0 : }
106 :
107 : static inline struct reservation_object_list *
108 0 : reservation_object_get_list(struct reservation_object *obj)
109 : {
110 0 : return rcu_dereference_protected(obj->fence,
111 : reservation_object_held(obj));
112 : }
113 :
114 : static inline struct fence *
115 0 : reservation_object_get_excl(struct reservation_object *obj)
116 : {
117 0 : return rcu_dereference_protected(obj->fence_excl,
118 : reservation_object_held(obj));
119 : }
120 :
121 : int reservation_object_reserve_shared(struct reservation_object *obj);
122 : void reservation_object_add_shared_fence(struct reservation_object *obj,
123 : struct fence *fence);
124 :
125 : void reservation_object_add_excl_fence(struct reservation_object *obj,
126 : struct fence *fence);
127 :
128 : int reservation_object_get_fences_rcu(struct reservation_object *obj,
129 : struct fence **pfence_excl,
130 : unsigned *pshared_count,
131 : struct fence ***pshared);
132 :
133 : long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
134 : bool wait_all, bool intr,
135 : unsigned long timeout);
136 :
137 : bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
138 : bool test_all);
139 :
140 : #endif /* _LINUX_RESERVATION_H */
|