Source
140
140
* @obj: the reservation object
141
141
* @fence: the shared fence to add
142
142
*
143
143
* Add a fence to a shared slot, obj->lock must be held, and
144
144
* reservation_object_reserve_shared() has been called.
145
145
*/
146
146
void reservation_object_add_shared_fence(struct reservation_object *obj,
147
147
struct dma_fence *fence)
148
148
{
149
149
struct reservation_object_list *fobj;
150
-
unsigned int i;
150
+
unsigned int i, count;
151
151
152
152
dma_fence_get(fence);
153
153
154
154
fobj = reservation_object_get_list(obj);
155
+
count = fobj->shared_count;
155
156
156
157
preempt_disable();
157
158
write_seqcount_begin(&obj->seq);
158
159
159
-
for (i = 0; i < fobj->shared_count; ++i) {
160
+
for (i = 0; i < count; ++i) {
160
161
struct dma_fence *old_fence;
161
162
162
163
old_fence = rcu_dereference_protected(fobj->shared[i],
163
164
reservation_object_held(obj));
164
165
if (old_fence->context == fence->context ||
165
166
dma_fence_is_signaled(old_fence)) {
166
167
dma_fence_put(old_fence);
167
168
goto replace;
168
169
}
169
170
}
170
171
171
172
BUG_ON(fobj->shared_count >= fobj->shared_max);
172
-
fobj->shared_count++;
173
+
count++;
173
174
174
175
replace:
175
-
/*
176
-
* memory barrier is added by write_seqcount_begin,
177
-
* fobj->shared_count is protected by this lock too
178
-
*/
179
176
RCU_INIT_POINTER(fobj->shared[i], fence);
177
+
/* pointer update must be visible before we extend the shared_count */
178
+
smp_store_mb(fobj->shared_count, count);
179
+
180
180
write_seqcount_end(&obj->seq);
181
181
preempt_enable();
182
182
}
183
183
EXPORT_SYMBOL(reservation_object_add_shared_fence);
184
184
185
185
/**
186
186
* reservation_object_add_excl_fence - Add an exclusive fence.
187
187
* @obj: the reservation object
188
188
* @fence: the shared fence to add
189
189
*