Commit Graph

11 Commits

Author SHA1 Message Date
Daniel Stone
bf248ca1f5 drm/i915: Fix locking around GuC firmware load
The GuC firmware load requires struct_mutex to create a GEM object,
but this collides badly with request_firmware. Move struct_mutex
locking down into the loader itself, so we don't hold it across the
entire load process, including request_firmware.

[   20.451400] ======================================================
[   20.451420] [ INFO: possible circular locking dependency detected ]
[   20.451441] 4.3.0-rc5+ #1 Tainted: G        W
[   20.451457] -------------------------------------------------------
[   20.451477] plymouthd/371 is trying to acquire lock:
[   20.451494]  (&dev->struct_mutex){+.+.+.}, at: [<ffffffffa0093c62>]
drm_gem_mmap+0x112/0x290 [drm]
[   20.451538]
               but task is already holding lock:
[   20.451557]  (&mm->mmap_sem){++++++}, at: [<ffffffff811fd9ac>]
vm_mmap_pgoff+0x8c/0xf0
[   20.451591]
               which lock already depends on the new lock.

[   20.451617]
               the existing dependency chain (in reverse order) is:
[   20.451640]
               -> #3 (&mm->mmap_sem){++++++}:
[   20.451661]        [<ffffffff8110644e>] lock_acquire+0xce/0x1c0
[   20.451683]        [<ffffffff8120ec9a>] __might_fault+0x7a/0xa0
[   20.451705]        [<ffffffff8127e34e>] filldir+0x9e/0x130
[   20.451726]        [<ffffffff81295b86>] dcache_readdir+0x186/0x230
[   20.451748]        [<ffffffff8127e117>] iterate_dir+0x97/0x130
[   20.451769]        [<ffffffff8127e66a>] SyS_getdents+0x9a/0x130
[   20.451790]        [<ffffffff8184f2f2>] entry_SYSCALL_64_fastpath+0x12/0x76
[   20.451829]
               -> #2 (&sb->s_type->i_mutex_key#2){+.+.+.}:
[   20.451852]        [<ffffffff8110644e>] lock_acquire+0xce/0x1c0
[   20.451872]        [<ffffffff8184b516>] mutex_lock_nested+0x86/0x400
[   20.451893]        [<ffffffff81277790>] walk_component+0x1d0/0x2a0
[   20.451914]        [<ffffffff812779f0>] link_path_walk+0x190/0x5a0
[   20.451935]        [<ffffffff8127803b>] path_openat+0xab/0x1260
[   20.451955]        [<ffffffff8127a651>] do_filp_open+0x91/0x100
[   20.451975]        [<ffffffff81267e67>] file_open_name+0xf7/0x150
[   20.451995]        [<ffffffff81267ef3>] filp_open+0x33/0x60
[   20.452014]        [<ffffffff8157e1e7>] _request_firmware+0x277/0x880
[   20.452038]        [<ffffffff8157e9e4>] request_firmware_work_func+0x34/0x80
[   20.452060]        [<ffffffff810c7020>] process_one_work+0x230/0x680
[   20.452082]        [<ffffffff810c74be>] worker_thread+0x4e/0x450
[   20.452102]        [<ffffffff810ce511>] kthread+0x101/0x120
[   20.452121]        [<ffffffff8184f66f>] ret_from_fork+0x3f/0x70
[   20.452140]
               -> #1 (umhelper_sem){++++.+}:
[   20.452159]        [<ffffffff8110644e>] lock_acquire+0xce/0x1c0
[   20.452178]        [<ffffffff8184c5c1>] down_read+0x51/0xa0
[   20.452197]        [<ffffffff810c203b>]
usermodehelper_read_trylock+0x5b/0x130
[   20.452221]        [<ffffffff8157e147>] _request_firmware+0x1d7/0x880
[   20.452242]        [<ffffffff8157e821>] request_firmware+0x31/0x50
[   20.452262]        [<ffffffffa01b54a4>]
intel_guc_ucode_init+0xf4/0x400 [i915]
[   20.452305]        [<ffffffffa0213913>] i915_driver_load+0xd63/0x16e0 [i915]
[   20.452343]        [<ffffffffa00987d9>] drm_dev_register+0xa9/0xc0 [drm]
[   20.452369]        [<ffffffffa009ae3d>] drm_get_pci_dev+0x8d/0x1e0 [drm]
[   20.452396]        [<ffffffffa01521e4>] i915_pci_probe+0x34/0x50 [i915]
[   20.452421]        [<ffffffff81464675>] local_pci_probe+0x45/0xa0
[   20.452443]        [<ffffffff81465a6d>] pci_device_probe+0xfd/0x140
[   20.452464]        [<ffffffff8156a2e4>] driver_probe_device+0x224/0x480
[   20.452486]        [<ffffffff8156a5c8>] __driver_attach+0x88/0x90
[   20.452505]        [<ffffffff81567cf3>] bus_for_each_dev+0x73/0xc0
[   20.452526]        [<ffffffff81569a7e>] driver_attach+0x1e/0x20
[   20.452546]        [<ffffffff815695ae>] bus_add_driver+0x1ee/0x280
[   20.452566]        [<ffffffff8156b100>] driver_register+0x60/0xe0
[   20.453197]        [<ffffffff81464050>] __pci_register_driver+0x60/0x70
[   20.453845]        [<ffffffffa009b070>] drm_pci_init+0xe0/0x110 [drm]
[   20.454497]        [<ffffffffa027f092>] 0xffffffffa027f092
[   20.455156]        [<ffffffff81002123>] do_one_initcall+0xb3/0x200
[   20.455796]        [<ffffffff811d8c01>] do_init_module+0x5f/0x1e7
[   20.456434]        [<ffffffff8114c4e6>] load_module+0x2126/0x27d0
[   20.457071]        [<ffffffff8114cdf9>] SyS_finit_module+0xb9/0xf0
[   20.457738]        [<ffffffff8184f2f2>] entry_SYSCALL_64_fastpath+0x12/0x76
[   20.458370]
               -> #0 (&dev->struct_mutex){+.+.+.}:
[   20.459773]        [<ffffffff8110584f>] __lock_acquire+0x191f/0x1ba0
[   20.460451]        [<ffffffff8110644e>] lock_acquire+0xce/0x1c0
[   20.461074]        [<ffffffffa0093c88>] drm_gem_mmap+0x138/0x290 [drm]
[   20.461693]        [<ffffffff8121a5ec>] mmap_region+0x3ec/0x670
[   20.462298]        [<ffffffff8121abb2>] do_mmap+0x342/0x420
[   20.462901]        [<ffffffff811fd9d2>] vm_mmap_pgoff+0xb2/0xf0
[   20.463532]        [<ffffffff81218f62>] SyS_mmap_pgoff+0x1f2/0x290
[   20.464118]        [<ffffffff8102187b>] SyS_mmap+0x1b/0x30
[   20.464702]        [<ffffffff8184f2f2>] entry_SYSCALL_64_fastpath+0x12/0x76
[   20.465289]
               other info that might help us debug this:

[   20.467179] Chain exists of:
                 &dev->struct_mutex --> &sb->s_type->i_mutex_key#2 -->
&mm->mmap_sem

[   20.468928]  Possible unsafe locking scenario:

[   20.470161]        CPU0                    CPU1
[   20.470745]        ----                    ----
[   20.471325]   lock(&mm->mmap_sem);
[   20.471902]                                lock(&sb->s_type->i_mutex_key#2);
[   20.472538]                                lock(&mm->mmap_sem);
[   20.473118]   lock(&dev->struct_mutex);
[   20.473704]
                *** DEADLOCK ***

Signed-off-by: Daniel Stone <daniels@collabora.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2015-11-04 13:23:15 +10:00
Alex Dai
a1c4199414 drm/i915/guc: Add host2guc notification for suspend and resume
Add host2guc interface to notify GuC power state changes when
enter or resume from power saving state.

v3: Move intel_guc_suspend to i915_drm_suspend for consistency.

v2: Add GuC suspend/resume to runtime suspend/resume too

v1: Change to a more flexible way when fill host to GuC scratch
data in order to remove hard coding.

Signed-off-by: Alex Dai <yu.dai@intel.com>
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-10-06 10:32:22 +02:00
Sagar Arun Kamble
9d91a1bfae drm/i915/guc: Don't forward flip interrupts to GuC
Due to flip interrupts GuC stays awake always and GT does not enter
RC6. Do not route those interrupts to GuC for now. Driver won't touch
DE_GUCRMR register and leave it as what default value.

Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Reviewed-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-10-01 18:12:17 +02:00
Ville Syrjälä
ab9cc558a3 drm/i915: Parametrize UOS_RSA_SCRATCH
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-30 10:20:13 +02:00
Alex Dai
0d44d3fa2b drm/i915/guc: Fix a bug in GuC status check
Bit 16 of GuC status indicates resuming from RC6. The LAPIC_DONE
status is a reliable readiness flag only when resuming from RC6.
This fix a racing issue that allocation of doorbell fails whilst
GuC init is not finished.

Signed-off-by: Alex Dai <yu.dai@intel.com>
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-30 10:20:00 +02:00
Nick Hoath
b970b48685 drm/i915/gen9: Add WaDisableMinuteIaClockGating
Signed-off-by: Nick Hoath <nicholas.hoath@intel.com>
Signed-off-by: Arun Siluvery <arun.siluvery@linux.intel.com>
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-14 11:12:28 +02:00
Alex Dai
aa557ab015 drm/i915/guc: Support GuC version 4.3
The firmware layout changes that now it only has css header +
uCode + RSA signature. Plus, other trivial changes to support
GuC V4.3.

Signed-off-by: Alex Dai <yu.dai@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-09-02 09:54:56 +02:00
Dave Gordon
4df001d398 drm/i915: Interrupt routing for GuC submission
Turn on interrupt steering to route necessary interrupts to GuC.

v6:
    Rebased

Issue: VIZ-4884
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-08-14 18:16:43 +02:00
Dave Gordon
44a28b1d36 drm/i915: Implementation of GuC submission client
A GuC client has its own doorbell and workqueue. It maintains the
doorbell cache line, process description object and work queue item.

A default guc_client is created for the i915 driver to use for
normal-priority in-order submission.

Note that the created client is not yet ready for use; doorbell
allocation will fail as we haven't yet linked the GuC's context
descriptor to the default contexts for each ring (see later patch).

v2:
    Defer adding structure members until needed [Chris Wilson]
    Rationalise type declarations [Chris Wilson]

v5:
    Add GuC per-engine submission & seqno statistics.
    Move wq locking to encompass both get_space() and add_item().
    Take forcewake lock in host2guc_action() [Tom O'Rourke]

v6:
    Fix GuC doorbell cacheline selection code (the
        cacheline-within-page calculation was wrong).
    Rename GuC priorities to make them closer to the names used in
        the GuC firmware source, matching what the autogenerated
        versions will (probably) be.
    Add per-ring statistics to client.

Issue: VIZ-4884
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-08-14 18:16:42 +02:00
Alex Dai
bac427f8ab drm/i915: Prepare for GuC-based command submission
This adds the first of the data structures used to communicate with the
GuC (the pool of guc_context structures).

We create a GuC-specific wrapper round the GEM object allocator as all
GEM objects shared with the GuC must be pinned into GGTT space at an
address that is NOT in the range [0..WOPCM_TOP), as that range of GGTT
addresses is not accessible to the GuC (from the GuC's point of view,
it's permanently reserved for other objects such as the BootROM & SRAM).

Later, we will need to allocate additional GuC-sharable objects for the
submission client(s) and the GuC's debug log.

v2:
    Remove redundant initialisation [Chris Wilson]
    Defer adding struct members until needed [Chris Wilson]
    Local functions should pass dev_priv rather than dev [Chris Wilson]

v5:
    Invalidate GuC TLB after allocating and pinning a new object

v6:
    Rebased

Issue: VIZ-4884
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-08-14 18:16:41 +02:00
Alex Dai
33a732f407 drm/i915: GuC-specific firmware loader
This fetches the required firmware image from the filesystem,
then loads it into the GuC's memory via a dedicated DMA engine.

This patch is derived from GuC loading work originally done by
Vinit Azad and Ben Widawsky.

v2:
    Various improvements per review comments by Chris Wilson

v3:
    Removed 'wait' parameter to intel_guc_ucode_load() as firmware
        prefetch is no longer supported in the common firmware loader,
	per Daniel Vetter's request.
    Firmware checker callback fn now returns errno rather than bool.

v4:
    Squash uC-independent code into GuC-specifc loader [Daniel Vetter]
    Don't keep the driver working (by falling back to execlist mode)
        if GuC firmware loading fails [Daniel Vetter]

v5:
    Clarify WOPCM-related #defines [Tom O'Rourke]
    Delete obsolete code no longer required with current h/w & f/w
        [Tom O'Rourke]
    Move the call to intel_guc_ucode_init() later, so that it can
        allocate GEM objects, and have it fetch the firmware; then
	intel_guc_ucode_load() doesn't need to fetch it later.
        [Daniel Vetter].

v6:
    Update comment describing intel_guc_ucode_load() [Tom O'Rourke]

Issue: VIZ-4884
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Tom O'Rourke <Tom.O'Rourke@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
2015-08-14 18:16:39 +02:00