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

drm/i915: Remove locking from i915_gem_object_prepare_read/write

Execbuffer submission will perform its own WW locking, and we
cannot rely on the implicit lock there.

This also makes it clear that the GVT code will get a lockdep splat when
multiple batchbuffer shadows need to be performed in the same instance,
fix that up.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200819140904.1708856-7-maarten.lankhorst@linux.intel.com
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

authored by

Maarten Lankhorst and committed by
Joonas Lahtinen
1af343cd 80f0b679

+59 -27
+6 -14
drivers/gpu/drm/i915/gem/i915_gem_domain.c
··· 576 576 if (!i915_gem_object_has_struct_page(obj)) 577 577 return -ENODEV; 578 578 579 - ret = i915_gem_object_lock_interruptible(obj, NULL); 580 - if (ret) 581 - return ret; 579 + assert_object_held(obj); 582 580 583 581 ret = i915_gem_object_wait(obj, 584 582 I915_WAIT_INTERRUPTIBLE, 585 583 MAX_SCHEDULE_TIMEOUT); 586 584 if (ret) 587 - goto err_unlock; 585 + return ret; 588 586 589 587 ret = i915_gem_object_pin_pages(obj); 590 588 if (ret) 591 - goto err_unlock; 589 + return ret; 592 590 593 591 if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ || 594 592 !static_cpu_has(X86_FEATURE_CLFLUSH)) { ··· 614 616 615 617 err_unpin: 616 618 i915_gem_object_unpin_pages(obj); 617 - err_unlock: 618 - i915_gem_object_unlock(obj); 619 619 return ret; 620 620 } 621 621 ··· 626 630 if (!i915_gem_object_has_struct_page(obj)) 627 631 return -ENODEV; 628 632 629 - ret = i915_gem_object_lock_interruptible(obj, NULL); 630 - if (ret) 631 - return ret; 633 + assert_object_held(obj); 632 634 633 635 ret = i915_gem_object_wait(obj, 634 636 I915_WAIT_INTERRUPTIBLE | 635 637 I915_WAIT_ALL, 636 638 MAX_SCHEDULE_TIMEOUT); 637 639 if (ret) 638 - goto err_unlock; 640 + return ret; 639 641 640 642 ret = i915_gem_object_pin_pages(obj); 641 643 if (ret) 642 - goto err_unlock; 644 + return ret; 643 645 644 646 if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE || 645 647 !static_cpu_has(X86_FEATURE_CLFLUSH)) { ··· 674 680 675 681 err_unpin: 676 682 i915_gem_object_unpin_pages(obj); 677 - err_unlock: 678 - i915_gem_object_unlock(obj); 679 683 return ret; 680 684 }
+11 -2
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
··· 991 991 992 992 vaddr = unmask_page(cache->vaddr); 993 993 if (cache->vaddr & KMAP) { 994 + struct drm_i915_gem_object *obj = 995 + (struct drm_i915_gem_object *)cache->node.mm; 994 996 if (cache->vaddr & CLFLUSH_AFTER) 995 997 mb(); 996 998 997 999 kunmap_atomic(vaddr); 998 - i915_gem_object_finish_access((struct drm_i915_gem_object *)cache->node.mm); 1000 + i915_gem_object_finish_access(obj); 1001 + i915_gem_object_unlock(obj); 999 1002 } else { 1000 1003 struct i915_ggtt *ggtt = cache_to_ggtt(cache); 1001 1004 ··· 1034 1031 unsigned int flushes; 1035 1032 int err; 1036 1033 1037 - err = i915_gem_object_prepare_write(obj, &flushes); 1034 + err = i915_gem_object_lock_interruptible(obj, NULL); 1038 1035 if (err) 1039 1036 return ERR_PTR(err); 1037 + 1038 + err = i915_gem_object_prepare_write(obj, &flushes); 1039 + if (err) { 1040 + i915_gem_object_unlock(obj); 1041 + return ERR_PTR(err); 1042 + } 1040 1043 1041 1044 BUILD_BUG_ON(KMAP & CLFLUSH_FLAGS); 1042 1045 BUILD_BUG_ON((KMAP | CLFLUSH_FLAGS) & PAGE_MASK);
-1
drivers/gpu/drm/i915/gem/i915_gem_object.h
··· 432 432 i915_gem_object_finish_access(struct drm_i915_gem_object *obj) 433 433 { 434 434 i915_gem_object_unpin_pages(obj); 435 - i915_gem_object_unlock(obj); 436 435 } 437 436 438 437 static inline struct intel_engine_cs *
+4 -1
drivers/gpu/drm/i915/gem/selftests/huge_pages.c
··· 964 964 unsigned long n; 965 965 int err; 966 966 967 + i915_gem_object_lock(obj, NULL); 967 968 err = i915_gem_object_prepare_read(obj, &needs_flush); 968 969 if (err) 969 - return err; 970 + goto err_unlock; 970 971 971 972 for (n = 0; n < obj->base.size >> PAGE_SHIFT; ++n) { 972 973 u32 *ptr = kmap_atomic(i915_gem_object_get_page(obj, n)); ··· 987 986 } 988 987 989 988 i915_gem_object_finish_access(obj); 989 + err_unlock: 990 + i915_gem_object_unlock(obj); 990 991 991 992 return err; 992 993 }
+10 -4
drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
··· 27 27 u32 *cpu; 28 28 int err; 29 29 30 + i915_gem_object_lock(ctx->obj, NULL); 30 31 err = i915_gem_object_prepare_write(ctx->obj, &needs_clflush); 31 32 if (err) 32 - return err; 33 + goto out; 33 34 34 35 page = i915_gem_object_get_page(ctx->obj, offset >> PAGE_SHIFT); 35 36 map = kmap_atomic(page); ··· 47 46 kunmap_atomic(map); 48 47 i915_gem_object_finish_access(ctx->obj); 49 48 50 - return 0; 49 + out: 50 + i915_gem_object_unlock(ctx->obj); 51 + return err; 51 52 } 52 53 53 54 static int cpu_get(struct context *ctx, unsigned long offset, u32 *v) ··· 60 57 u32 *cpu; 61 58 int err; 62 59 60 + i915_gem_object_lock(ctx->obj, NULL); 63 61 err = i915_gem_object_prepare_read(ctx->obj, &needs_clflush); 64 62 if (err) 65 - return err; 63 + goto out; 66 64 67 65 page = i915_gem_object_get_page(ctx->obj, offset >> PAGE_SHIFT); 68 66 map = kmap_atomic(page); ··· 77 73 kunmap_atomic(map); 78 74 i915_gem_object_finish_access(ctx->obj); 79 75 80 - return 0; 76 + out: 77 + i915_gem_object_unlock(ctx->obj); 78 + return err; 81 79 } 82 80 83 81 static int gtt_set(struct context *ctx, unsigned long offset, u32 v)
+9 -3
drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
··· 461 461 unsigned int n, m, need_flush; 462 462 int err; 463 463 464 + i915_gem_object_lock(obj, NULL); 464 465 err = i915_gem_object_prepare_write(obj, &need_flush); 465 466 if (err) 466 - return err; 467 + goto out; 467 468 468 469 for (n = 0; n < real_page_count(obj); n++) { 469 470 u32 *map; ··· 480 479 i915_gem_object_finish_access(obj); 481 480 obj->read_domains = I915_GEM_DOMAIN_GTT | I915_GEM_DOMAIN_CPU; 482 481 obj->write_domain = 0; 483 - return 0; 482 + out: 483 + i915_gem_object_unlock(obj); 484 + return err; 484 485 } 485 486 486 487 static noinline int cpu_check(struct drm_i915_gem_object *obj, ··· 491 488 unsigned int n, m, needs_flush; 492 489 int err; 493 490 491 + i915_gem_object_lock(obj, NULL); 494 492 err = i915_gem_object_prepare_read(obj, &needs_flush); 495 493 if (err) 496 - return err; 494 + goto out_unlock; 497 495 498 496 for (n = 0; n < real_page_count(obj); n++) { 499 497 u32 *map; ··· 531 527 } 532 528 533 529 i915_gem_object_finish_access(obj); 530 + out_unlock: 531 + i915_gem_object_unlock(obj); 534 532 return err; 535 533 } 536 534
+1
drivers/gpu/drm/i915/gvt/cmd_parser.c
··· 1923 1923 if (ret) 1924 1924 goto err_unmap; 1925 1925 1926 + i915_gem_object_unlock(bb->obj); 1926 1927 INIT_LIST_HEAD(&bb->list); 1927 1928 list_add(&bb->list, &s->workload->shadow_bb); 1928 1929
+18 -2
drivers/gpu/drm/i915/i915_gem.c
··· 335 335 u64 remain; 336 336 int ret; 337 337 338 - ret = i915_gem_object_prepare_read(obj, &needs_clflush); 338 + ret = i915_gem_object_lock_interruptible(obj, NULL); 339 339 if (ret) 340 340 return ret; 341 341 342 + ret = i915_gem_object_prepare_read(obj, &needs_clflush); 343 + if (ret) { 344 + i915_gem_object_unlock(obj); 345 + return ret; 346 + } 347 + 342 348 fence = i915_gem_object_lock_fence(obj); 343 349 i915_gem_object_finish_access(obj); 350 + i915_gem_object_unlock(obj); 351 + 344 352 if (!fence) 345 353 return -ENOMEM; 346 354 ··· 742 734 u64 remain; 743 735 int ret; 744 736 745 - ret = i915_gem_object_prepare_write(obj, &needs_clflush); 737 + ret = i915_gem_object_lock_interruptible(obj, NULL); 746 738 if (ret) 747 739 return ret; 748 740 741 + ret = i915_gem_object_prepare_write(obj, &needs_clflush); 742 + if (ret) { 743 + i915_gem_object_unlock(obj); 744 + return ret; 745 + } 746 + 749 747 fence = i915_gem_object_lock_fence(obj); 750 748 i915_gem_object_finish_access(obj); 749 + i915_gem_object_unlock(obj); 750 + 751 751 if (!fence) 752 752 return -ENOMEM; 753 753