aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/vga
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2013-08-15 18:37:59 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-09-03 13:17:59 -0400
commit5c0f6ee766d7c689e71a7df5e5fa87941affd75a (patch)
tree42674b39f8b5c4c587e6d7474e6b8f601e896cdb /drivers/gpu/vga
parentf22d776f3e280e605819fc09fc35db0d802d36ce (diff)
vgaarb: Fix VGA decodes changes
When VGA decodes change we need to do a bit more evaluation of exactly what has changed. We don't necessarily give up all the old owns resources and we need to account for resources with locks. The new algorithm is: If something is added, update decodes. If legacy resources were added and none were there before, we have a new participant. If something is removed, update decodes. If we previously owned it, we no longer own it. If it was previously locked, invalidate all locks and release it. If legacy resources were removed and none are left, remove the participant from VGA arbitration. Previously we updated decodes, released ownership of everything that was previously decoded, ignored all locks, and went off looking for another device to transfer VGA to. In a test case where Intel IGD removes only legacy VGA memory decoding, this left the arbiter switching to discrete graphics without actually disabling legacy VGA IO from the IGD. As a bonus, we bumped up the count of VGA arbitration participants for no good reason. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Cc: Dave Airlie <airlied@redhat.com> Acked-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> [danvet: Kill now unused variables, reported by the 0-day kernel builtbot.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/vga')
-rw-r--r--drivers/gpu/vga/vgaarb.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index ea564711bb80..af0259708358 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -644,10 +644,12 @@ bail:
644static inline void vga_update_device_decodes(struct vga_device *vgadev, 644static inline void vga_update_device_decodes(struct vga_device *vgadev,
645 int new_decodes) 645 int new_decodes)
646{ 646{
647 int old_decodes; 647 int old_decodes, decodes_removed, decodes_unlocked;
648 struct vga_device *new_vgadev, *conflict;
649 648
650 old_decodes = vgadev->decodes; 649 old_decodes = vgadev->decodes;
650 decodes_removed = ~new_decodes & old_decodes;
651 decodes_unlocked = vgadev->locks & decodes_removed;
652 vgadev->owns &= ~decodes_removed;
651 vgadev->decodes = new_decodes; 653 vgadev->decodes = new_decodes;
652 654
653 pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n", 655 pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n",
@@ -656,31 +658,22 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev,
656 vga_iostate_to_str(vgadev->decodes), 658 vga_iostate_to_str(vgadev->decodes),
657 vga_iostate_to_str(vgadev->owns)); 659 vga_iostate_to_str(vgadev->owns));
658 660
659 661 /* if we removed locked decodes, lock count goes to zero, and release */
660 /* if we own the decodes we should move them along to 662 if (decodes_unlocked) {
661 another card */ 663 if (decodes_unlocked & VGA_RSRC_LEGACY_IO)
662 if ((vgadev->owns & old_decodes) && (vga_count > 1)) { 664 vgadev->io_lock_cnt = 0;
663 /* set us to own nothing */ 665 if (decodes_unlocked & VGA_RSRC_LEGACY_MEM)
664 vgadev->owns &= ~old_decodes; 666 vgadev->mem_lock_cnt = 0;
665 list_for_each_entry(new_vgadev, &vga_list, list) { 667 __vga_put(vgadev, decodes_unlocked);
666 if ((new_vgadev != vgadev) &&
667 (new_vgadev->decodes & VGA_RSRC_LEGACY_MASK)) {
668 pr_info("vgaarb: transferring owner from PCI:%s to PCI:%s\n", pci_name(vgadev->pdev), pci_name(new_vgadev->pdev));
669 conflict = __vga_tryget(new_vgadev, VGA_RSRC_LEGACY_MASK);
670 if (!conflict)
671 __vga_put(new_vgadev, VGA_RSRC_LEGACY_MASK);
672 break;
673 }
674 }
675 } 668 }
676 669
677 /* change decodes counter */ 670 /* change decodes counter */
678 if (old_decodes != new_decodes) { 671 if (old_decodes & VGA_RSRC_LEGACY_MASK &&
679 if (new_decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) 672 !(new_decodes & VGA_RSRC_LEGACY_MASK))
680 vga_decode_count++; 673 vga_decode_count--;
681 else 674 if (!(old_decodes & VGA_RSRC_LEGACY_MASK) &&
682 vga_decode_count--; 675 new_decodes & VGA_RSRC_LEGACY_MASK)
683 } 676 vga_decode_count++;
684 pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); 677 pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count);
685} 678}
686 679