1 1.17 riastrad /* $NetBSD: nouveau_fence.c,v 1.17 2021/12/19 10:49:13 riastradh Exp $ */ 2 1.2 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright (C) 2007 Ben Skeggs. 5 1.1 riastrad * All Rights Reserved. 6 1.1 riastrad * 7 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining 8 1.1 riastrad * a copy of this software and associated documentation files (the 9 1.1 riastrad * "Software"), to deal in the Software without restriction, including 10 1.1 riastrad * without limitation the rights to use, copy, modify, merge, publish, 11 1.1 riastrad * distribute, sublicense, and/or sell copies of the Software, and to 12 1.1 riastrad * permit persons to whom the Software is furnished to do so, subject to 13 1.1 riastrad * the following conditions: 14 1.1 riastrad * 15 1.1 riastrad * The above copyright notice and this permission notice (including the 16 1.1 riastrad * next paragraph) shall be included in all copies or substantial 17 1.1 riastrad * portions of the Software. 18 1.1 riastrad * 19 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 1.1 riastrad * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 1.1 riastrad * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 1.1 riastrad * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 23 1.1 riastrad * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24 1.1 riastrad * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25 1.1 riastrad * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 1.1 riastrad * 27 1.1 riastrad */ 28 1.1 riastrad 29 1.2 riastrad #include <sys/cdefs.h> 30 1.17 riastrad __KERNEL_RCSID(0, "$NetBSD: nouveau_fence.c,v 1.17 2021/12/19 10:49:13 riastradh Exp $"); 31 1.1 riastrad 32 1.17 riastrad #include <linux/atomic.h> 33 1.1 riastrad #include <linux/ktime.h> 34 1.1 riastrad #include <linux/hrtimer.h> 35 1.16 riastrad #include <linux/sched/signal.h> 36 1.17 riastrad #include <linux/workqueue.h> 37 1.16 riastrad #include <trace/events/dma_fence.h> 38 1.10 riastrad 39 1.16 riastrad #include <nvif/cl826e.h> 40 1.10 riastrad #include <nvif/notify.h> 41 1.10 riastrad #include <nvif/event.h> 42 1.1 riastrad 43 1.16 riastrad #include "nouveau_drv.h" 44 1.1 riastrad #include "nouveau_dma.h" 45 1.1 riastrad #include "nouveau_fence.h" 46 1.1 riastrad 47 1.16 riastrad static const struct dma_fence_ops nouveau_fence_ops_uevent; 48 1.16 riastrad static const struct dma_fence_ops nouveau_fence_ops_legacy; 49 1.10 riastrad 50 1.10 riastrad static inline struct nouveau_fence * 51 1.16 riastrad from_fence(struct dma_fence *fence) 52 1.10 riastrad { 53 1.10 riastrad return container_of(fence, struct nouveau_fence, base); 54 1.10 riastrad } 55 1.1 riastrad 56 1.10 riastrad static inline struct nouveau_fence_chan * 57 1.10 riastrad nouveau_fctx(struct nouveau_fence *fence) 58 1.10 riastrad { 59 1.10 riastrad return container_of(fence->base.lock, struct nouveau_fence_chan, lock); 60 1.10 riastrad } 61 1.1 riastrad 62 1.10 riastrad static int 63 1.10 riastrad nouveau_fence_signal(struct nouveau_fence *fence) 64 1.6 riastrad { 65 1.10 riastrad int drop = 0; 66 1.10 riastrad 67 1.16 riastrad dma_fence_signal_locked(&fence->base); 68 1.10 riastrad list_del(&fence->head); 69 1.10 riastrad rcu_assign_pointer(fence->channel, NULL); 70 1.10 riastrad 71 1.16 riastrad if (test_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags)) { 72 1.10 riastrad struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 73 1.6 riastrad 74 1.10 riastrad if (!--fctx->notify_ref) 75 1.10 riastrad drop = 1; 76 1.6 riastrad } 77 1.6 riastrad 78 1.16 riastrad dma_fence_put(&fence->base); 79 1.10 riastrad return drop; 80 1.6 riastrad } 81 1.6 riastrad 82 1.10 riastrad static struct nouveau_fence * 83 1.16 riastrad nouveau_local_fence(struct dma_fence *fence, struct nouveau_drm *drm) 84 1.16 riastrad { 85 1.10 riastrad if (fence->ops != &nouveau_fence_ops_legacy && 86 1.10 riastrad fence->ops != &nouveau_fence_ops_uevent) 87 1.10 riastrad return NULL; 88 1.7 riastrad 89 1.16 riastrad if (fence->context < drm->chan.context_base || 90 1.16 riastrad fence->context >= drm->chan.context_base + drm->chan.nr) 91 1.10 riastrad return NULL; 92 1.7 riastrad 93 1.10 riastrad return from_fence(fence); 94 1.7 riastrad } 95 1.7 riastrad 96 1.10 riastrad void 97 1.16 riastrad nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error) 98 1.7 riastrad { 99 1.10 riastrad struct nouveau_fence *fence; 100 1.10 riastrad 101 1.10 riastrad spin_lock_irq(&fctx->lock); 102 1.10 riastrad while (!list_empty(&fctx->pending)) { 103 1.10 riastrad fence = list_entry(fctx->pending.next, typeof(*fence), head); 104 1.7 riastrad 105 1.16 riastrad if (error) 106 1.16 riastrad dma_fence_set_error(&fence->base, error); 107 1.16 riastrad 108 1.10 riastrad if (nouveau_fence_signal(fence)) 109 1.10 riastrad nvif_notify_put(&fctx->notify); 110 1.7 riastrad } 111 1.10 riastrad spin_unlock_irq(&fctx->lock); 112 1.16 riastrad } 113 1.10 riastrad 114 1.16 riastrad void 115 1.16 riastrad nouveau_fence_context_del(struct nouveau_fence_chan *fctx) 116 1.16 riastrad { 117 1.16 riastrad nouveau_fence_context_kill(fctx, 0); 118 1.10 riastrad nvif_notify_fini(&fctx->notify); 119 1.10 riastrad fctx->dead = 1; 120 1.10 riastrad 121 1.10 riastrad /* 122 1.10 riastrad * Ensure that all accesses to fence->channel complete before freeing 123 1.10 riastrad * the channel. 124 1.10 riastrad */ 125 1.10 riastrad synchronize_rcu(); 126 1.7 riastrad } 127 1.7 riastrad 128 1.6 riastrad static void 129 1.10 riastrad nouveau_fence_context_put(struct kref *fence_ref) 130 1.6 riastrad { 131 1.13 mrg struct nouveau_fence_chan *fctx = 132 1.13 mrg container_of(fence_ref, struct nouveau_fence_chan, fence_ref); 133 1.13 mrg 134 1.13 mrg spin_lock_destroy(&fctx->lock); 135 1.13 mrg kfree(fctx); 136 1.10 riastrad } 137 1.6 riastrad 138 1.10 riastrad void 139 1.10 riastrad nouveau_fence_context_free(struct nouveau_fence_chan *fctx) 140 1.10 riastrad { 141 1.10 riastrad kref_put(&fctx->fence_ref, nouveau_fence_context_put); 142 1.6 riastrad } 143 1.6 riastrad 144 1.10 riastrad static int 145 1.10 riastrad nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) 146 1.1 riastrad { 147 1.10 riastrad struct nouveau_fence *fence; 148 1.10 riastrad int drop = 0; 149 1.10 riastrad u32 seq = fctx->read(chan); 150 1.1 riastrad 151 1.10 riastrad while (!list_empty(&fctx->pending)) { 152 1.10 riastrad fence = list_entry(fctx->pending.next, typeof(*fence), head); 153 1.5 riastrad 154 1.10 riastrad if ((int)(seq - fence->base.seqno) < 0) 155 1.10 riastrad break; 156 1.10 riastrad 157 1.10 riastrad drop |= nouveau_fence_signal(fence); 158 1.1 riastrad } 159 1.1 riastrad 160 1.10 riastrad return drop; 161 1.1 riastrad } 162 1.1 riastrad 163 1.10 riastrad static int 164 1.10 riastrad nouveau_fence_wait_uevent_handler(struct nvif_notify *notify) 165 1.6 riastrad { 166 1.10 riastrad struct nouveau_fence_chan *fctx = 167 1.10 riastrad container_of(notify, typeof(*fctx), notify); 168 1.10 riastrad unsigned long flags; 169 1.10 riastrad int ret = NVIF_NOTIFY_KEEP; 170 1.10 riastrad 171 1.10 riastrad spin_lock_irqsave(&fctx->lock, flags); 172 1.10 riastrad if (!list_empty(&fctx->pending)) { 173 1.10 riastrad struct nouveau_fence *fence; 174 1.10 riastrad struct nouveau_channel *chan; 175 1.10 riastrad 176 1.10 riastrad fence = list_entry(fctx->pending.next, typeof(*fence), head); 177 1.10 riastrad chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); 178 1.11 riastrad if (nouveau_fence_update(chan, fctx)) 179 1.10 riastrad ret = NVIF_NOTIFY_DROP; 180 1.10 riastrad } 181 1.10 riastrad spin_unlock_irqrestore(&fctx->lock, flags); 182 1.6 riastrad 183 1.10 riastrad return ret; 184 1.1 riastrad } 185 1.1 riastrad 186 1.1 riastrad void 187 1.10 riastrad nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) 188 1.1 riastrad { 189 1.10 riastrad struct nouveau_fence_priv *priv = (void*)chan->drm->fence; 190 1.10 riastrad struct nouveau_cli *cli = (void *)chan->user.client; 191 1.10 riastrad int ret; 192 1.5 riastrad 193 1.1 riastrad INIT_LIST_HEAD(&fctx->flip); 194 1.1 riastrad INIT_LIST_HEAD(&fctx->pending); 195 1.1 riastrad spin_lock_init(&fctx->lock); 196 1.16 riastrad fctx->context = chan->drm->chan.context_base + chan->chid; 197 1.10 riastrad 198 1.10 riastrad if (chan == chan->drm->cechan) 199 1.10 riastrad strcpy(fctx->name, "copy engine channel"); 200 1.10 riastrad else if (chan == chan->drm->channel) 201 1.10 riastrad strcpy(fctx->name, "generic kernel channel"); 202 1.10 riastrad else 203 1.10 riastrad strcpy(fctx->name, nvxx_client(&cli->base)->name); 204 1.10 riastrad 205 1.10 riastrad kref_init(&fctx->fence_ref); 206 1.10 riastrad if (!priv->uevent) 207 1.10 riastrad return; 208 1.10 riastrad 209 1.10 riastrad ret = nvif_notify_init(&chan->user, nouveau_fence_wait_uevent_handler, 210 1.16 riastrad false, NV826E_V0_NTFY_NON_STALL_INTERRUPT, 211 1.10 riastrad &(struct nvif_notify_uevent_req) { }, 212 1.10 riastrad sizeof(struct nvif_notify_uevent_req), 213 1.10 riastrad sizeof(struct nvif_notify_uevent_rep), 214 1.10 riastrad &fctx->notify); 215 1.10 riastrad 216 1.10 riastrad WARN_ON(ret); 217 1.10 riastrad } 218 1.10 riastrad 219 1.1 riastrad int 220 1.1 riastrad nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) 221 1.1 riastrad { 222 1.1 riastrad struct nouveau_fence_chan *fctx = chan->fence; 223 1.10 riastrad struct nouveau_fence_priv *priv = (void*)chan->drm->fence; 224 1.1 riastrad int ret; 225 1.1 riastrad 226 1.1 riastrad fence->channel = chan; 227 1.1 riastrad fence->timeout = jiffies + (15 * HZ); 228 1.1 riastrad 229 1.10 riastrad if (priv->uevent) 230 1.16 riastrad dma_fence_init(&fence->base, &nouveau_fence_ops_uevent, 231 1.16 riastrad &fctx->lock, fctx->context, ++fctx->sequence); 232 1.10 riastrad else 233 1.16 riastrad dma_fence_init(&fence->base, &nouveau_fence_ops_legacy, 234 1.16 riastrad &fctx->lock, fctx->context, ++fctx->sequence); 235 1.10 riastrad kref_get(&fctx->fence_ref); 236 1.10 riastrad 237 1.16 riastrad trace_dma_fence_emit(&fence->base); 238 1.1 riastrad ret = fctx->emit(fence); 239 1.1 riastrad if (!ret) { 240 1.16 riastrad dma_fence_get(&fence->base); 241 1.10 riastrad spin_lock_irq(&fctx->lock); 242 1.10 riastrad 243 1.10 riastrad if (nouveau_fence_update(chan, fctx)) 244 1.10 riastrad nvif_notify_put(&fctx->notify); 245 1.10 riastrad 246 1.1 riastrad list_add_tail(&fence->head, &fctx->pending); 247 1.10 riastrad spin_unlock_irq(&fctx->lock); 248 1.1 riastrad } 249 1.1 riastrad 250 1.1 riastrad return ret; 251 1.1 riastrad } 252 1.1 riastrad 253 1.1 riastrad bool 254 1.1 riastrad nouveau_fence_done(struct nouveau_fence *fence) 255 1.1 riastrad { 256 1.10 riastrad if (fence->base.ops == &nouveau_fence_ops_legacy || 257 1.10 riastrad fence->base.ops == &nouveau_fence_ops_uevent) { 258 1.10 riastrad struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 259 1.10 riastrad struct nouveau_channel *chan; 260 1.10 riastrad unsigned long flags; 261 1.10 riastrad 262 1.16 riastrad if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) 263 1.10 riastrad return true; 264 1.10 riastrad 265 1.10 riastrad spin_lock_irqsave(&fctx->lock, flags); 266 1.10 riastrad chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); 267 1.10 riastrad if (chan && nouveau_fence_update(chan, fctx)) 268 1.10 riastrad nvif_notify_put(&fctx->notify); 269 1.10 riastrad spin_unlock_irqrestore(&fctx->lock, flags); 270 1.10 riastrad } 271 1.16 riastrad return dma_fence_is_signaled(&fence->base); 272 1.10 riastrad } 273 1.10 riastrad 274 1.10 riastrad static long 275 1.16 riastrad nouveau_fence_wait_legacy(struct dma_fence *f, bool intr, long wait) 276 1.10 riastrad { 277 1.10 riastrad struct nouveau_fence *fence = from_fence(f); 278 1.10 riastrad #ifndef __NetBSD__ 279 1.10 riastrad unsigned long sleep_time = NSEC_PER_MSEC / 1000; 280 1.10 riastrad #endif 281 1.10 riastrad unsigned long t = jiffies, timeout = t + wait; 282 1.5 riastrad 283 1.10 riastrad #ifdef __NetBSD__ 284 1.10 riastrad while (!nouveau_fence_done(fence)) { 285 1.10 riastrad int ret; 286 1.10 riastrad /* XXX what lock? */ 287 1.10 riastrad /* XXX errno NetBSD->Linux */ 288 1.10 riastrad ret = -kpause("nvfencel", intr, 1, NULL); 289 1.14 mrg if (ret) { 290 1.14 mrg if (ret == -ERESTART) 291 1.14 mrg ret = -ERESTARTSYS; 292 1.10 riastrad return ret; 293 1.14 mrg } 294 1.10 riastrad t = jiffies; 295 1.10 riastrad if (t >= timeout) 296 1.10 riastrad return 0; 297 1.10 riastrad } 298 1.10 riastrad #else 299 1.10 riastrad while (!nouveau_fence_done(fence)) { 300 1.10 riastrad ktime_t kt; 301 1.6 riastrad 302 1.10 riastrad t = jiffies; 303 1.7 riastrad 304 1.10 riastrad if (wait != MAX_SCHEDULE_TIMEOUT && time_after_eq(t, timeout)) { 305 1.10 riastrad __set_current_state(TASK_RUNNING); 306 1.10 riastrad return 0; 307 1.10 riastrad } 308 1.5 riastrad 309 1.10 riastrad __set_current_state(intr ? TASK_INTERRUPTIBLE : 310 1.10 riastrad TASK_UNINTERRUPTIBLE); 311 1.6 riastrad 312 1.16 riastrad kt = sleep_time; 313 1.10 riastrad schedule_hrtimeout(&kt, HRTIMER_MODE_REL); 314 1.10 riastrad sleep_time *= 2; 315 1.10 riastrad if (sleep_time > NSEC_PER_MSEC) 316 1.10 riastrad sleep_time = NSEC_PER_MSEC; 317 1.7 riastrad 318 1.10 riastrad if (intr && signal_pending(current)) 319 1.10 riastrad return -ERESTARTSYS; 320 1.10 riastrad } 321 1.1 riastrad 322 1.10 riastrad __set_current_state(TASK_RUNNING); 323 1.10 riastrad #endif 324 1.5 riastrad 325 1.10 riastrad return timeout - t; 326 1.1 riastrad } 327 1.1 riastrad 328 1.1 riastrad static int 329 1.10 riastrad nouveau_fence_wait_busy(struct nouveau_fence *fence, bool intr) 330 1.1 riastrad { 331 1.1 riastrad int ret = 0; 332 1.1 riastrad 333 1.10 riastrad while (!nouveau_fence_done(fence)) { 334 1.10 riastrad if (time_after_eq(jiffies, fence->timeout)) { 335 1.10 riastrad ret = -EBUSY; 336 1.10 riastrad break; 337 1.10 riastrad } 338 1.6 riastrad 339 1.10 riastrad #ifdef __NetBSD__ 340 1.10 riastrad /* XXX unlock anything? */ 341 1.10 riastrad /* XXX poll for interrupts? */ 342 1.10 riastrad DELAY(1000); 343 1.10 riastrad #else 344 1.10 riastrad __set_current_state(intr ? 345 1.10 riastrad TASK_INTERRUPTIBLE : 346 1.10 riastrad TASK_UNINTERRUPTIBLE); 347 1.1 riastrad 348 1.10 riastrad if (intr && signal_pending(current)) { 349 1.10 riastrad ret = -ERESTARTSYS; 350 1.10 riastrad break; 351 1.1 riastrad } 352 1.10 riastrad #endif 353 1.1 riastrad } 354 1.1 riastrad 355 1.10 riastrad #ifndef __NetBSD__ 356 1.10 riastrad __set_current_state(TASK_RUNNING); 357 1.10 riastrad #endif 358 1.10 riastrad return ret; 359 1.10 riastrad } 360 1.10 riastrad 361 1.10 riastrad int 362 1.10 riastrad nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr) 363 1.10 riastrad { 364 1.10 riastrad long ret; 365 1.7 riastrad 366 1.10 riastrad if (!lazy) 367 1.10 riastrad return nouveau_fence_wait_busy(fence, intr); 368 1.7 riastrad 369 1.16 riastrad ret = dma_fence_wait_timeout(&fence->base, intr, 15 * HZ); 370 1.10 riastrad if (ret < 0) 371 1.1 riastrad return ret; 372 1.10 riastrad else if (!ret) 373 1.10 riastrad return -EBUSY; 374 1.10 riastrad else 375 1.10 riastrad return 0; 376 1.1 riastrad } 377 1.1 riastrad 378 1.1 riastrad int 379 1.10 riastrad nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool exclusive, bool intr) 380 1.1 riastrad { 381 1.10 riastrad struct nouveau_fence_chan *fctx = chan->fence; 382 1.16 riastrad struct dma_fence *fence; 383 1.16 riastrad struct dma_resv *resv = nvbo->bo.base.resv; 384 1.16 riastrad struct dma_resv_list *fobj; 385 1.10 riastrad struct nouveau_fence *f; 386 1.10 riastrad int ret = 0, i; 387 1.10 riastrad 388 1.10 riastrad if (!exclusive) { 389 1.16 riastrad ret = dma_resv_reserve_shared(resv, 1); 390 1.10 riastrad 391 1.10 riastrad if (ret) 392 1.10 riastrad return ret; 393 1.10 riastrad } 394 1.10 riastrad 395 1.16 riastrad fobj = dma_resv_get_list(resv); 396 1.16 riastrad fence = dma_resv_get_excl(resv); 397 1.10 riastrad 398 1.10 riastrad if (fence && (!exclusive || !fobj || !fobj->shared_count)) { 399 1.10 riastrad struct nouveau_channel *prev = NULL; 400 1.10 riastrad bool must_wait = true; 401 1.10 riastrad 402 1.10 riastrad f = nouveau_local_fence(fence, chan->drm); 403 1.10 riastrad if (f) { 404 1.10 riastrad rcu_read_lock(); 405 1.10 riastrad prev = rcu_dereference(f->channel); 406 1.10 riastrad if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) 407 1.10 riastrad must_wait = false; 408 1.10 riastrad rcu_read_unlock(); 409 1.10 riastrad } 410 1.1 riastrad 411 1.10 riastrad if (must_wait) 412 1.16 riastrad ret = dma_fence_wait(fence, intr); 413 1.6 riastrad 414 1.10 riastrad return ret; 415 1.1 riastrad } 416 1.1 riastrad 417 1.10 riastrad if (!exclusive || !fobj) 418 1.10 riastrad return ret; 419 1.1 riastrad 420 1.10 riastrad for (i = 0; i < fobj->shared_count && !ret; ++i) { 421 1.10 riastrad struct nouveau_channel *prev = NULL; 422 1.10 riastrad bool must_wait = true; 423 1.10 riastrad 424 1.10 riastrad fence = rcu_dereference_protected(fobj->shared[i], 425 1.16 riastrad dma_resv_held(resv)); 426 1.10 riastrad 427 1.10 riastrad f = nouveau_local_fence(fence, chan->drm); 428 1.10 riastrad if (f) { 429 1.10 riastrad rcu_read_lock(); 430 1.10 riastrad prev = rcu_dereference(f->channel); 431 1.10 riastrad if (prev && (prev == chan || fctx->sync(f, prev, chan) == 0)) 432 1.10 riastrad must_wait = false; 433 1.10 riastrad rcu_read_unlock(); 434 1.1 riastrad } 435 1.1 riastrad 436 1.10 riastrad if (must_wait) 437 1.16 riastrad ret = dma_fence_wait(fence, intr); 438 1.1 riastrad } 439 1.1 riastrad 440 1.1 riastrad return ret; 441 1.1 riastrad } 442 1.1 riastrad 443 1.1 riastrad void 444 1.1 riastrad nouveau_fence_unref(struct nouveau_fence **pfence) 445 1.1 riastrad { 446 1.1 riastrad if (*pfence) 447 1.16 riastrad dma_fence_put(&(*pfence)->base); 448 1.1 riastrad *pfence = NULL; 449 1.1 riastrad } 450 1.1 riastrad 451 1.1 riastrad int 452 1.1 riastrad nouveau_fence_new(struct nouveau_channel *chan, bool sysmem, 453 1.1 riastrad struct nouveau_fence **pfence) 454 1.1 riastrad { 455 1.1 riastrad struct nouveau_fence *fence; 456 1.1 riastrad int ret = 0; 457 1.1 riastrad 458 1.1 riastrad if (unlikely(!chan->fence)) 459 1.1 riastrad return -ENODEV; 460 1.1 riastrad 461 1.1 riastrad fence = kzalloc(sizeof(*fence), GFP_KERNEL); 462 1.1 riastrad if (!fence) 463 1.1 riastrad return -ENOMEM; 464 1.1 riastrad 465 1.1 riastrad ret = nouveau_fence_emit(fence, chan); 466 1.1 riastrad if (ret) 467 1.1 riastrad nouveau_fence_unref(&fence); 468 1.1 riastrad 469 1.1 riastrad *pfence = fence; 470 1.1 riastrad return ret; 471 1.1 riastrad } 472 1.10 riastrad 473 1.16 riastrad static const char *nouveau_fence_get_get_driver_name(struct dma_fence *fence) 474 1.10 riastrad { 475 1.10 riastrad return "nouveau"; 476 1.10 riastrad } 477 1.10 riastrad 478 1.16 riastrad static const char *nouveau_fence_get_timeline_name(struct dma_fence *f) 479 1.10 riastrad { 480 1.10 riastrad struct nouveau_fence *fence = from_fence(f); 481 1.10 riastrad struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 482 1.10 riastrad 483 1.10 riastrad return !fctx->dead ? fctx->name : "dead channel"; 484 1.10 riastrad } 485 1.10 riastrad 486 1.10 riastrad /* 487 1.10 riastrad * In an ideal world, read would not assume the channel context is still alive. 488 1.10 riastrad * This function may be called from another device, running into free memory as a 489 1.10 riastrad * result. The drm node should still be there, so we can derive the index from 490 1.10 riastrad * the fence context. 491 1.10 riastrad */ 492 1.16 riastrad static bool nouveau_fence_is_signaled(struct dma_fence *f) 493 1.10 riastrad { 494 1.10 riastrad struct nouveau_fence *fence = from_fence(f); 495 1.10 riastrad struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 496 1.10 riastrad struct nouveau_channel *chan; 497 1.10 riastrad bool ret = false; 498 1.10 riastrad 499 1.10 riastrad rcu_read_lock(); 500 1.10 riastrad chan = rcu_dereference(fence->channel); 501 1.10 riastrad if (chan) 502 1.10 riastrad ret = (int)(fctx->read(chan) - fence->base.seqno) >= 0; 503 1.10 riastrad rcu_read_unlock(); 504 1.10 riastrad 505 1.10 riastrad return ret; 506 1.10 riastrad } 507 1.10 riastrad 508 1.16 riastrad static bool nouveau_fence_no_signaling(struct dma_fence *f) 509 1.10 riastrad { 510 1.10 riastrad struct nouveau_fence *fence = from_fence(f); 511 1.10 riastrad 512 1.10 riastrad /* 513 1.10 riastrad * caller should have a reference on the fence, 514 1.10 riastrad * else fence could get freed here 515 1.10 riastrad */ 516 1.16 riastrad WARN_ON(kref_read(&fence->base.refcount) <= 1); 517 1.10 riastrad 518 1.10 riastrad /* 519 1.16 riastrad * This needs uevents to work correctly, but dma_fence_add_callback relies on 520 1.10 riastrad * being able to enable signaling. It will still get signaled eventually, 521 1.10 riastrad * just not right away. 522 1.10 riastrad */ 523 1.10 riastrad if (nouveau_fence_is_signaled(f)) { 524 1.10 riastrad list_del(&fence->head); 525 1.10 riastrad 526 1.16 riastrad dma_fence_put(&fence->base); 527 1.10 riastrad return false; 528 1.10 riastrad } 529 1.10 riastrad 530 1.10 riastrad return true; 531 1.10 riastrad } 532 1.10 riastrad 533 1.16 riastrad static void nouveau_fence_release(struct dma_fence *f) 534 1.10 riastrad { 535 1.10 riastrad struct nouveau_fence *fence = from_fence(f); 536 1.10 riastrad struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 537 1.10 riastrad 538 1.10 riastrad kref_put(&fctx->fence_ref, nouveau_fence_context_put); 539 1.16 riastrad dma_fence_free(&fence->base); 540 1.10 riastrad } 541 1.10 riastrad 542 1.16 riastrad static const struct dma_fence_ops nouveau_fence_ops_legacy = { 543 1.10 riastrad .get_driver_name = nouveau_fence_get_get_driver_name, 544 1.10 riastrad .get_timeline_name = nouveau_fence_get_timeline_name, 545 1.10 riastrad .enable_signaling = nouveau_fence_no_signaling, 546 1.10 riastrad .signaled = nouveau_fence_is_signaled, 547 1.10 riastrad .wait = nouveau_fence_wait_legacy, 548 1.10 riastrad .release = nouveau_fence_release 549 1.10 riastrad }; 550 1.10 riastrad 551 1.16 riastrad static bool nouveau_fence_enable_signaling(struct dma_fence *f) 552 1.10 riastrad { 553 1.10 riastrad struct nouveau_fence *fence = from_fence(f); 554 1.10 riastrad struct nouveau_fence_chan *fctx = nouveau_fctx(fence); 555 1.10 riastrad bool ret; 556 1.10 riastrad 557 1.10 riastrad if (!fctx->notify_ref++) 558 1.10 riastrad nvif_notify_get(&fctx->notify); 559 1.10 riastrad 560 1.10 riastrad ret = nouveau_fence_no_signaling(f); 561 1.10 riastrad if (ret) 562 1.16 riastrad set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags); 563 1.10 riastrad else if (!--fctx->notify_ref) 564 1.10 riastrad nvif_notify_put(&fctx->notify); 565 1.10 riastrad 566 1.10 riastrad return ret; 567 1.10 riastrad } 568 1.10 riastrad 569 1.16 riastrad static const struct dma_fence_ops nouveau_fence_ops_uevent = { 570 1.10 riastrad .get_driver_name = nouveau_fence_get_get_driver_name, 571 1.10 riastrad .get_timeline_name = nouveau_fence_get_timeline_name, 572 1.10 riastrad .enable_signaling = nouveau_fence_enable_signaling, 573 1.10 riastrad .signaled = nouveau_fence_is_signaled, 574 1.16 riastrad .release = nouveau_fence_release 575 1.10 riastrad }; 576