Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/vmwgfx: rework to new fence interface, v2

Use the new fence interface on vmwgfx too.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>

---
Changes since v1:
Fix a sleeping function called from invalid context in enable_signaling.

+228 -146
+1
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
··· 703 703 extern void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes); 704 704 extern int vmw_fifo_send_fence(struct vmw_private *dev_priv, 705 705 uint32_t *seqno); 706 + extern void vmw_fifo_ping_host_locked(struct vmw_private *, uint32_t reason); 706 707 extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason); 707 708 extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv); 708 709 extern bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv);
+1 -1
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
··· 2389 2389 BUG_ON(fence == NULL); 2390 2390 2391 2391 fence_rep.handle = fence_handle; 2392 - fence_rep.seqno = fence->seqno; 2392 + fence_rep.seqno = fence->base.seqno; 2393 2393 vmw_update_seqno(dev_priv, &dev_priv->fifo); 2394 2394 fence_rep.passed_seqno = dev_priv->last_read_seqno; 2395 2395 }
+195 -129
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
··· 35 35 struct vmw_private *dev_priv; 36 36 spinlock_t lock; 37 37 struct list_head fence_list; 38 - struct work_struct work; 38 + struct work_struct work, ping_work; 39 39 u32 user_fence_size; 40 40 u32 fence_size; 41 41 u32 event_fence_action_size; ··· 46 46 bool goal_irq_on; /* Protected by @goal_irq_mutex */ 47 47 bool seqno_valid; /* Protected by @lock, and may not be set to true 48 48 without the @goal_irq_mutex held. */ 49 + unsigned ctx; 49 50 }; 50 51 51 52 struct vmw_user_fence { ··· 81 80 uint32_t *tv_usec; 82 81 }; 83 82 83 + static struct vmw_fence_manager * 84 + fman_from_fence(struct vmw_fence_obj *fence) 85 + { 86 + return container_of(fence->base.lock, struct vmw_fence_manager, lock); 87 + } 88 + 84 89 /** 85 90 * Note on fencing subsystem usage of irqs: 86 91 * Typically the vmw_fences_update function is called ··· 109 102 * objects with actions attached to them. 110 103 */ 111 104 112 - static void vmw_fence_obj_destroy_locked(struct kref *kref) 105 + static void vmw_fence_obj_destroy(struct fence *f) 113 106 { 114 107 struct vmw_fence_obj *fence = 115 - container_of(kref, struct vmw_fence_obj, kref); 108 + container_of(f, struct vmw_fence_obj, base); 116 109 117 - struct vmw_fence_manager *fman = fence->fman; 118 - unsigned int num_fences; 110 + struct vmw_fence_manager *fman = fman_from_fence(fence); 111 + unsigned long irq_flags; 119 112 113 + spin_lock_irqsave(&fman->lock, irq_flags); 120 114 list_del_init(&fence->head); 121 - num_fences = --fman->num_fence_objects; 122 - spin_unlock_irq(&fman->lock); 123 - if (fence->destroy) 124 - fence->destroy(fence); 125 - else 126 - kfree(fence); 127 - 128 - spin_lock_irq(&fman->lock); 115 + --fman->num_fence_objects; 116 + spin_unlock_irqrestore(&fman->lock, irq_flags); 117 + fence->destroy(fence); 129 118 } 119 + 120 + static const char *vmw_fence_get_driver_name(struct fence *f) 121 + { 122 + return "vmwgfx"; 123 + } 124 + 125 + static const char *vmw_fence_get_timeline_name(struct fence *f) 126 + { 127 + return "svga"; 128 + } 129 + 130 + static void vmw_fence_ping_func(struct work_struct *work) 131 + { 132 + struct vmw_fence_manager *fman = 133 + container_of(work, struct vmw_fence_manager, ping_work); 134 + 135 + vmw_fifo_ping_host(fman->dev_priv, SVGA_SYNC_GENERIC); 136 + } 137 + 138 + static bool vmw_fence_enable_signaling(struct fence *f) 139 + { 140 + struct vmw_fence_obj *fence = 141 + container_of(f, struct vmw_fence_obj, base); 142 + 143 + struct vmw_fence_manager *fman = fman_from_fence(fence); 144 + struct vmw_private *dev_priv = fman->dev_priv; 145 + 146 + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; 147 + u32 seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE); 148 + if (seqno - fence->base.seqno < VMW_FENCE_WRAP) 149 + return false; 150 + 151 + if (mutex_trylock(&dev_priv->hw_mutex)) { 152 + vmw_fifo_ping_host_locked(dev_priv, SVGA_SYNC_GENERIC); 153 + mutex_unlock(&dev_priv->hw_mutex); 154 + } else 155 + schedule_work(&fman->ping_work); 156 + 157 + return true; 158 + } 159 + 160 + struct vmwgfx_wait_cb { 161 + struct fence_cb base; 162 + struct task_struct *task; 163 + }; 164 + 165 + static void 166 + vmwgfx_wait_cb(struct fence *fence, struct fence_cb *cb) 167 + { 168 + struct vmwgfx_wait_cb *wait = 169 + container_of(cb, struct vmwgfx_wait_cb, base); 170 + 171 + wake_up_process(wait->task); 172 + } 173 + 174 + static void __vmw_fences_update(struct vmw_fence_manager *fman); 175 + 176 + static long vmw_fence_wait(struct fence *f, bool intr, signed long timeout) 177 + { 178 + struct vmw_fence_obj *fence = 179 + container_of(f, struct vmw_fence_obj, base); 180 + 181 + struct vmw_fence_manager *fman = fman_from_fence(fence); 182 + struct vmw_private *dev_priv = fman->dev_priv; 183 + struct vmwgfx_wait_cb cb; 184 + long ret = timeout; 185 + unsigned long irq_flags; 186 + 187 + if (likely(vmw_fence_obj_signaled(fence))) 188 + return timeout; 189 + 190 + vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); 191 + vmw_seqno_waiter_add(dev_priv); 192 + 193 + spin_lock_irqsave(f->lock, irq_flags); 194 + 195 + if (intr && signal_pending(current)) { 196 + ret = -ERESTARTSYS; 197 + goto out; 198 + } 199 + 200 + cb.base.func = vmwgfx_wait_cb; 201 + cb.task = current; 202 + list_add(&cb.base.node, &f->cb_list); 203 + 204 + while (ret > 0) { 205 + __vmw_fences_update(fman); 206 + if (test_bit(FENCE_FLAG_SIGNALED_BIT, &f->flags)) 207 + break; 208 + 209 + if (intr) 210 + __set_current_state(TASK_INTERRUPTIBLE); 211 + else 212 + __set_current_state(TASK_UNINTERRUPTIBLE); 213 + spin_unlock_irqrestore(f->lock, irq_flags); 214 + 215 + ret = schedule_timeout(ret); 216 + 217 + spin_lock_irqsave(f->lock, irq_flags); 218 + if (ret > 0 && intr && signal_pending(current)) 219 + ret = -ERESTARTSYS; 220 + } 221 + 222 + if (!list_empty(&cb.base.node)) 223 + list_del(&cb.base.node); 224 + __set_current_state(TASK_RUNNING); 225 + 226 + out: 227 + spin_unlock_irqrestore(f->lock, irq_flags); 228 + 229 + vmw_seqno_waiter_remove(dev_priv); 230 + 231 + return ret; 232 + } 233 + 234 + static struct fence_ops vmw_fence_ops = { 235 + .get_driver_name = vmw_fence_get_driver_name, 236 + .get_timeline_name = vmw_fence_get_timeline_name, 237 + .enable_signaling = vmw_fence_enable_signaling, 238 + .wait = vmw_fence_wait, 239 + .release = vmw_fence_obj_destroy, 240 + }; 130 241 131 242 132 243 /** ··· 305 180 INIT_LIST_HEAD(&fman->fence_list); 306 181 INIT_LIST_HEAD(&fman->cleanup_list); 307 182 INIT_WORK(&fman->work, &vmw_fence_work_func); 183 + INIT_WORK(&fman->ping_work, &vmw_fence_ping_func); 308 184 fman->fifo_down = true; 309 185 fman->user_fence_size = ttm_round_pot(sizeof(struct vmw_user_fence)); 310 186 fman->fence_size = ttm_round_pot(sizeof(struct vmw_fence_obj)); 311 187 fman->event_fence_action_size = 312 188 ttm_round_pot(sizeof(struct vmw_event_fence_action)); 313 189 mutex_init(&fman->goal_irq_mutex); 190 + fman->ctx = fence_context_alloc(1); 314 191 315 192 return fman; 316 193 } ··· 323 196 bool lists_empty; 324 197 325 198 (void) cancel_work_sync(&fman->work); 199 + (void) cancel_work_sync(&fman->ping_work); 326 200 327 201 spin_lock_irqsave(&fman->lock, irq_flags); 328 202 lists_empty = list_empty(&fman->fence_list) && ··· 339 211 void (*destroy) (struct vmw_fence_obj *fence)) 340 212 { 341 213 unsigned long irq_flags; 342 - unsigned int num_fences; 343 214 int ret = 0; 344 215 345 - fence->seqno = seqno; 216 + fence_init(&fence->base, &vmw_fence_ops, &fman->lock, 217 + fman->ctx, seqno); 346 218 INIT_LIST_HEAD(&fence->seq_passed_actions); 347 - fence->fman = fman; 348 - fence->signaled = 0; 349 - kref_init(&fence->kref); 350 219 fence->destroy = destroy; 351 - init_waitqueue_head(&fence->queue); 352 220 353 221 spin_lock_irqsave(&fman->lock, irq_flags); 354 222 if (unlikely(fman->fifo_down)) { ··· 352 228 goto out_unlock; 353 229 } 354 230 list_add_tail(&fence->head, &fman->fence_list); 355 - num_fences = ++fman->num_fence_objects; 231 + ++fman->num_fence_objects; 356 232 357 233 out_unlock: 358 234 spin_unlock_irqrestore(&fman->lock, irq_flags); 359 235 return ret; 360 236 361 - } 362 - 363 - struct vmw_fence_obj *vmw_fence_obj_reference(struct vmw_fence_obj *fence) 364 - { 365 - if (unlikely(fence == NULL)) 366 - return NULL; 367 - 368 - kref_get(&fence->kref); 369 - return fence; 370 - } 371 - 372 - /** 373 - * vmw_fence_obj_unreference 374 - * 375 - * Note that this function may not be entered with disabled irqs since 376 - * it may re-enable them in the destroy function. 377 - * 378 - */ 379 - void vmw_fence_obj_unreference(struct vmw_fence_obj **fence_p) 380 - { 381 - struct vmw_fence_obj *fence = *fence_p; 382 - struct vmw_fence_manager *fman; 383 - 384 - if (unlikely(fence == NULL)) 385 - return; 386 - 387 - fman = fence->fman; 388 - *fence_p = NULL; 389 - spin_lock_irq(&fman->lock); 390 - BUG_ON(atomic_read(&fence->kref.refcount) == 0); 391 - kref_put(&fence->kref, vmw_fence_obj_destroy_locked); 392 - spin_unlock_irq(&fman->lock); 393 237 } 394 238 395 239 static void vmw_fences_perform_actions(struct vmw_fence_manager *fman, ··· 415 323 list_for_each_entry(fence, &fman->fence_list, head) { 416 324 if (!list_empty(&fence->seq_passed_actions)) { 417 325 fman->seqno_valid = true; 418 - iowrite32(fence->seqno, 326 + iowrite32(fence->base.seqno, 419 327 fifo_mem + SVGA_FIFO_FENCE_GOAL); 420 328 break; 421 329 } ··· 442 350 */ 443 351 static bool vmw_fence_goal_check_locked(struct vmw_fence_obj *fence) 444 352 { 353 + struct vmw_fence_manager *fman = fman_from_fence(fence); 445 354 u32 goal_seqno; 446 355 __le32 __iomem *fifo_mem; 447 356 448 - if (fence->signaled) 357 + if (fence_is_signaled_locked(&fence->base)) 449 358 return false; 450 359 451 - fifo_mem = fence->fman->dev_priv->mmio_virt; 360 + fifo_mem = fman->dev_priv->mmio_virt; 452 361 goal_seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE_GOAL); 453 - if (likely(fence->fman->seqno_valid && 454 - goal_seqno - fence->seqno < VMW_FENCE_WRAP)) 362 + if (likely(fman->seqno_valid && 363 + goal_seqno - fence->base.seqno < VMW_FENCE_WRAP)) 455 364 return false; 456 365 457 - iowrite32(fence->seqno, fifo_mem + SVGA_FIFO_FENCE_GOAL); 458 - fence->fman->seqno_valid = true; 366 + iowrite32(fence->base.seqno, fifo_mem + SVGA_FIFO_FENCE_GOAL); 367 + fman->seqno_valid = true; 459 368 460 369 return true; 461 370 } 462 371 463 - void vmw_fences_update(struct vmw_fence_manager *fman) 372 + static void __vmw_fences_update(struct vmw_fence_manager *fman) 464 373 { 465 - unsigned long flags; 466 374 struct vmw_fence_obj *fence, *next_fence; 467 375 struct list_head action_list; 468 376 bool needs_rerun; ··· 471 379 472 380 seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE); 473 381 rerun: 474 - spin_lock_irqsave(&fman->lock, flags); 475 382 list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { 476 - if (seqno - fence->seqno < VMW_FENCE_WRAP) { 383 + if (seqno - fence->base.seqno < VMW_FENCE_WRAP) { 477 384 list_del_init(&fence->head); 478 - fence->signaled = 1; 385 + fence_signal_locked(&fence->base); 479 386 INIT_LIST_HEAD(&action_list); 480 387 list_splice_init(&fence->seq_passed_actions, 481 388 &action_list); 482 389 vmw_fences_perform_actions(fman, &action_list); 483 - wake_up_all(&fence->queue); 484 390 } else 485 391 break; 486 392 } 487 - 488 - needs_rerun = vmw_fence_goal_new_locked(fman, seqno); 489 - 490 - if (!list_empty(&fman->cleanup_list)) 491 - (void) schedule_work(&fman->work); 492 - spin_unlock_irqrestore(&fman->lock, flags); 493 393 494 394 /* 495 395 * Rerun if the fence goal seqno was updated, and the ··· 489 405 * we missed a fence_goal irq. 490 406 */ 491 407 408 + needs_rerun = vmw_fence_goal_new_locked(fman, seqno); 492 409 if (unlikely(needs_rerun)) { 493 410 new_seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE); 494 411 if (new_seqno != seqno) { ··· 497 412 goto rerun; 498 413 } 499 414 } 415 + 416 + if (!list_empty(&fman->cleanup_list)) 417 + (void) schedule_work(&fman->work); 418 + } 419 + 420 + void vmw_fences_update(struct vmw_fence_manager *fman) 421 + { 422 + unsigned long irq_flags; 423 + 424 + spin_lock_irqsave(&fman->lock, irq_flags); 425 + __vmw_fences_update(fman); 426 + spin_unlock_irqrestore(&fman->lock, irq_flags); 500 427 } 501 428 502 429 bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence) 503 430 { 504 - struct vmw_fence_manager *fman = fence->fman; 505 - unsigned long irq_flags; 506 - uint32_t signaled; 431 + struct vmw_fence_manager *fman = fman_from_fence(fence); 507 432 508 - spin_lock_irqsave(&fman->lock, irq_flags); 509 - signaled = fence->signaled; 510 - spin_unlock_irqrestore(&fman->lock, irq_flags); 511 - 512 - if (signaled) 433 + if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->base.flags)) 513 434 return 1; 514 435 515 436 vmw_fences_update(fman); 516 437 517 - spin_lock_irqsave(&fman->lock, irq_flags); 518 - signaled = fence->signaled; 519 - spin_unlock_irqrestore(&fman->lock, irq_flags); 520 - 521 - return signaled; 438 + return fence_is_signaled(&fence->base); 522 439 } 523 440 524 441 int vmw_fence_obj_wait(struct vmw_fence_obj *fence, bool lazy, 525 442 bool interruptible, unsigned long timeout) 526 443 { 527 - struct vmw_private *dev_priv = fence->fman->dev_priv; 528 - long ret; 444 + long ret = fence_wait_timeout(&fence->base, interruptible, timeout); 529 445 530 - if (likely(vmw_fence_obj_signaled(fence))) 446 + if (likely(ret > 0)) 531 447 return 0; 532 - 533 - vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); 534 - vmw_seqno_waiter_add(dev_priv); 535 - 536 - if (interruptible) 537 - ret = wait_event_interruptible_timeout 538 - (fence->queue, 539 - vmw_fence_obj_signaled(fence), 540 - timeout); 448 + else if (ret == 0) 449 + return -EBUSY; 541 450 else 542 - ret = wait_event_timeout 543 - (fence->queue, 544 - vmw_fence_obj_signaled(fence), 545 - timeout); 546 - 547 - vmw_seqno_waiter_remove(dev_priv); 548 - 549 - if (unlikely(ret == 0)) 550 - ret = -EBUSY; 551 - else if (likely(ret > 0)) 552 - ret = 0; 553 - 554 - return ret; 451 + return ret; 555 452 } 556 453 557 454 void vmw_fence_obj_flush(struct vmw_fence_obj *fence) 558 455 { 559 - struct vmw_private *dev_priv = fence->fman->dev_priv; 456 + struct vmw_private *dev_priv = fman_from_fence(fence)->dev_priv; 560 457 561 458 vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); 562 459 } 563 460 564 461 static void vmw_fence_destroy(struct vmw_fence_obj *fence) 565 462 { 566 - struct vmw_fence_manager *fman = fence->fman; 463 + struct vmw_fence_manager *fman = fman_from_fence(fence); 567 464 568 - kfree(fence); 465 + fence_free(&fence->base); 466 + 569 467 /* 570 468 * Free kernel space accounting. 571 469 */ ··· 595 527 { 596 528 struct vmw_user_fence *ufence = 597 529 container_of(fence, struct vmw_user_fence, fence); 598 - struct vmw_fence_manager *fman = fence->fman; 530 + struct vmw_fence_manager *fman = fman_from_fence(fence); 599 531 600 532 ttm_base_object_kfree(ufence, base); 601 533 /* ··· 688 620 689 621 void vmw_fence_fifo_down(struct vmw_fence_manager *fman) 690 622 { 691 - unsigned long irq_flags; 692 623 struct list_head action_list; 693 624 int ret; 694 625 ··· 696 629 * restart when we've released the fman->lock. 697 630 */ 698 631 699 - spin_lock_irqsave(&fman->lock, irq_flags); 632 + spin_lock_irq(&fman->lock); 700 633 fman->fifo_down = true; 701 634 while (!list_empty(&fman->fence_list)) { 702 635 struct vmw_fence_obj *fence = 703 636 list_entry(fman->fence_list.prev, struct vmw_fence_obj, 704 637 head); 705 - kref_get(&fence->kref); 638 + fence_get(&fence->base); 706 639 spin_unlock_irq(&fman->lock); 707 640 708 641 ret = vmw_fence_obj_wait(fence, false, false, ··· 710 643 711 644 if (unlikely(ret != 0)) { 712 645 list_del_init(&fence->head); 713 - fence->signaled = 1; 646 + fence_signal(&fence->base); 714 647 INIT_LIST_HEAD(&action_list); 715 648 list_splice_init(&fence->seq_passed_actions, 716 649 &action_list); 717 650 vmw_fences_perform_actions(fman, &action_list); 718 - wake_up_all(&fence->queue); 719 651 } 720 652 721 - spin_lock_irq(&fman->lock); 722 - 723 653 BUG_ON(!list_empty(&fence->head)); 724 - kref_put(&fence->kref, vmw_fence_obj_destroy_locked); 654 + fence_put(&fence->base); 655 + spin_lock_irq(&fman->lock); 725 656 } 726 - spin_unlock_irqrestore(&fman->lock, irq_flags); 657 + spin_unlock_irq(&fman->lock); 727 658 } 728 659 729 660 void vmw_fence_fifo_up(struct vmw_fence_manager *fman) ··· 813 748 } 814 749 815 750 fence = &(container_of(base, struct vmw_user_fence, base)->fence); 816 - fman = fence->fman; 751 + fman = fman_from_fence(fence); 817 752 818 753 arg->signaled = vmw_fence_obj_signaled(fence); 819 - spin_lock_irq(&fman->lock); 820 754 821 755 arg->signaled_flags = arg->flags; 756 + spin_lock_irq(&fman->lock); 822 757 arg->passed_seqno = dev_priv->last_read_seqno; 823 758 spin_unlock_irq(&fman->lock); 824 759 ··· 931 866 { 932 867 struct vmw_event_fence_action *eaction = 933 868 container_of(action, struct vmw_event_fence_action, action); 934 - struct vmw_fence_manager *fman = eaction->fence->fman; 869 + struct vmw_fence_manager *fman = fman_from_fence(eaction->fence); 935 870 unsigned long irq_flags; 936 871 937 872 spin_lock_irqsave(&fman->lock, irq_flags); ··· 955 890 static void vmw_fence_obj_add_action(struct vmw_fence_obj *fence, 956 891 struct vmw_fence_action *action) 957 892 { 958 - struct vmw_fence_manager *fman = fence->fman; 893 + struct vmw_fence_manager *fman = fman_from_fence(fence); 959 894 unsigned long irq_flags; 960 895 bool run_update = false; 961 896 ··· 963 898 spin_lock_irqsave(&fman->lock, irq_flags); 964 899 965 900 fman->pending_actions[action->type]++; 966 - if (fence->signaled) { 901 + if (fence_is_signaled_locked(&fence->base)) { 967 902 struct list_head action_list; 968 903 969 904 INIT_LIST_HEAD(&action_list); ··· 1015 950 bool interruptible) 1016 951 { 1017 952 struct vmw_event_fence_action *eaction; 1018 - struct vmw_fence_manager *fman = fence->fman; 953 + struct vmw_fence_manager *fman = fman_from_fence(fence); 1019 954 struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); 1020 955 unsigned long irq_flags; 1021 956 ··· 1055 990 bool interruptible) 1056 991 { 1057 992 struct vmw_event_fence_pending *event; 1058 - struct drm_device *dev = fence->fman->dev_priv->dev; 993 + struct vmw_fence_manager *fman = fman_from_fence(fence); 994 + struct drm_device *dev = fman->dev_priv->dev; 1059 995 unsigned long irq_flags; 1060 996 int ret; 1061 997
+19 -8
drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
··· 27 27 28 28 #ifndef _VMWGFX_FENCE_H_ 29 29 30 + #include <linux/fence.h> 31 + 30 32 #define VMW_FENCE_WAIT_TIMEOUT (5*HZ) 31 33 32 34 struct vmw_private; ··· 52 50 }; 53 51 54 52 struct vmw_fence_obj { 55 - struct kref kref; 56 - u32 seqno; 53 + struct fence base; 57 54 58 - struct vmw_fence_manager *fman; 59 55 struct list_head head; 60 - uint32_t signaled; 61 56 struct list_head seq_passed_actions; 62 57 void (*destroy)(struct vmw_fence_obj *fence); 63 - wait_queue_head_t queue; 64 58 }; 65 59 66 60 extern struct vmw_fence_manager * ··· 64 66 65 67 extern void vmw_fence_manager_takedown(struct vmw_fence_manager *fman); 66 68 67 - extern void vmw_fence_obj_unreference(struct vmw_fence_obj **fence_p); 69 + static inline void 70 + vmw_fence_obj_unreference(struct vmw_fence_obj **fence_p) 71 + { 72 + struct vmw_fence_obj *fence = *fence_p; 68 73 69 - extern struct vmw_fence_obj * 70 - vmw_fence_obj_reference(struct vmw_fence_obj *fence); 74 + *fence_p = NULL; 75 + if (fence) 76 + fence_put(&fence->base); 77 + } 78 + 79 + static inline struct vmw_fence_obj * 80 + vmw_fence_obj_reference(struct vmw_fence_obj *fence) 81 + { 82 + if (fence) 83 + fence_get(&fence->base); 84 + return fence; 85 + } 71 86 72 87 extern void vmw_fences_update(struct vmw_fence_manager *fman); 73 88
+8 -3
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
··· 160 160 return vmw_fifo_send_fence(dev_priv, &dummy); 161 161 } 162 162 163 - void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) 163 + void vmw_fifo_ping_host_locked(struct vmw_private *dev_priv, uint32_t reason) 164 164 { 165 165 __le32 __iomem *fifo_mem = dev_priv->mmio_virt; 166 - 167 - mutex_lock(&dev_priv->hw_mutex); 168 166 169 167 if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) { 170 168 iowrite32(1, fifo_mem + SVGA_FIFO_BUSY); 171 169 vmw_write(dev_priv, SVGA_REG_SYNC, reason); 172 170 } 171 + } 172 + 173 + void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) 174 + { 175 + mutex_lock(&dev_priv->hw_mutex); 176 + 177 + vmw_fifo_ping_host_locked(dev_priv, reason); 173 178 174 179 mutex_unlock(&dev_priv->hw_mutex); 175 180 }
+4 -5
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
··· 1420 1420 struct vmw_fence_obj *fence) 1421 1421 { 1422 1422 struct ttm_bo_device *bdev = bo->bdev; 1423 - struct ttm_bo_driver *driver = bdev->driver; 1424 1423 struct vmw_fence_obj *old_fence_obj; 1425 1424 struct vmw_private *dev_priv = 1426 1425 container_of(bdev, struct vmw_private, bdev); 1427 1426 1428 - if (fence == NULL) 1427 + if (fence == NULL) { 1429 1428 vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL); 1430 - else 1431 - driver->sync_obj_ref(fence); 1429 + } else 1430 + vmw_fence_obj_reference(fence); 1432 1431 1432 + reservation_object_add_excl_fence(bo->resv, &fence->base); 1433 1433 1434 1434 old_fence_obj = bo->sync_obj; 1435 1435 bo->sync_obj = fence; 1436 - 1437 1436 1438 1437 if (old_fence_obj) 1439 1438 vmw_fence_obj_unreference(&old_fence_obj);