public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, Daniel Vetter <daniel.vetter@ffwll.ch>,
	Chris Wilson <chris@chris-wilson.co.uk>,
	Eugeni Dodonov <eugeni.dodonov@intel.com>,
	Keith Packard <keithp@keithp.com>
Subject: [patch 46/86] drm/i915: protect force_wake_(get|put) with the gt_lock
Date: Fri, 10 Feb 2012 14:30:05 -0800	[thread overview]
Message-ID: <20120210222949.102085830@clark.kroah.org> (raw)
In-Reply-To: <20120210223514.GA24190@kroah.com>

3.2-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Daniel Vetter <daniel.vetter@ffwll.ch>

commit 9f1f46a45a681d357d1ceedecec3671a5ae957f4 upstream.

The problem this patch solves is that the forcewake accounting
necessary for register reads is protected by dev->struct_mutex. But the
hangcheck and error_capture code need to access registers without
grabbing this mutex because we hold it while waiting for the gpu.
So a new lock is required. Because currently the error_state capture
is called from the error irq handler and the hangcheck code runs from
a timer, it needs to be an irqsafe spinlock (note that the registers
used by the irq handler (neglecting the error handling part) only uses
registers that don't need the forcewake dance).

We could tune this down to a normal spinlock when we rework the
error_state capture and hangcheck code to run from a workqueue.  But
we don't have any read in a fastpath that needs forcewake, so I've
decided to not care much about overhead.

This prevents tests/gem_hangcheck_forcewake from i-g-t from killing my
snb on recent kernels - something must have slightly changed the
timings. On previous kernels it only trigger a WARN about the broken
locking.

v2: Drop the previous patch for the register writes.

v3: Improve the commit message per Chris Wilson's suggestions.

Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/gpu/drm/i915/i915_debugfs.c |    8 ++++++--
 drivers/gpu/drm/i915/i915_dma.c     |    1 +
 drivers/gpu/drm/i915/i915_drv.c     |   18 ++++++++++++------
 drivers/gpu/drm/i915/i915_drv.h     |   10 +++++++---
 4 files changed, 26 insertions(+), 11 deletions(-)

--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1314,9 +1314,13 @@ static int i915_gen6_forcewake_count_inf
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
 	struct drm_device *dev = node->minor->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned forcewake_count;
 
-	seq_printf(m, "forcewake count = %d\n",
-		   atomic_read(&dev_priv->forcewake_count));
+	spin_lock_irq(&dev_priv->gt_lock);
+	forcewake_count = dev_priv->forcewake_count;
+	spin_unlock_irq(&dev_priv->gt_lock);
+
+	seq_printf(m, "forcewake count = %u\n", forcewake_count);
 
 	return 0;
 }
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2042,6 +2042,7 @@ int i915_driver_load(struct drm_device *
 	if (!IS_I945G(dev) && !IS_I945GM(dev))
 		pci_enable_msi(dev->pdev);
 
+	spin_lock_init(&dev_priv->gt_lock);
 	spin_lock_init(&dev_priv->irq_lock);
 	spin_lock_init(&dev_priv->error_lock);
 	spin_lock_init(&dev_priv->rps_lock);
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -368,11 +368,12 @@ void __gen6_gt_force_wake_mt_get(struct
  */
 void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
 {
-	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+	unsigned long irqflags;
 
-	/* Forcewake is atomic in case we get in here without the lock */
-	if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
+	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+	if (dev_priv->forcewake_count++ == 0)
 		dev_priv->display.force_wake_get(dev_priv);
+	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
 }
 
 void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
@@ -392,10 +393,12 @@ void __gen6_gt_force_wake_mt_put(struct
  */
 void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
 {
-	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+	unsigned long irqflags;
 
-	if (atomic_dec_and_test(&dev_priv->forcewake_count))
+	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+	if (--dev_priv->forcewake_count == 0)
 		dev_priv->display.force_wake_put(dev_priv);
+	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
 }
 
 void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
@@ -626,6 +629,7 @@ int i915_reset(struct drm_device *dev, u
 	 * need to
 	 */
 	bool need_display = true;
+	unsigned long irqflags;
 	int ret;
 
 	if (!i915_try_reset)
@@ -644,8 +648,10 @@ int i915_reset(struct drm_device *dev, u
 	case 6:
 		ret = gen6_do_reset(dev, flags);
 		/* If reset with a user forcewake, try to restore */
-		if (atomic_read(&dev_priv->forcewake_count))
+		spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+		if (dev_priv->forcewake_count)
 			dev_priv->display.force_wake_get(dev_priv);
+		spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
 		break;
 	case 5:
 		ret = ironlake_do_reset(dev, flags);
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -286,7 +286,13 @@ typedef struct drm_i915_private {
 	int relative_constants_mode;
 
 	void __iomem *regs;
-	u32 gt_fifo_count;
+	/** gt_fifo_count and the subsequent register write are synchronized
+	 * with dev->struct_mutex. */
+	unsigned gt_fifo_count;
+	/** forcewake_count is protected by gt_lock */
+	unsigned forcewake_count;
+	/** gt_lock is also taken in irq contexts. */
+	struct spinlock gt_lock;
 
 	struct intel_gmbus {
 		struct i2c_adapter adapter;
@@ -738,8 +744,6 @@ typedef struct drm_i915_private {
 
 	struct drm_property *broadcast_rgb_property;
 	struct drm_property *force_audio_property;
-
-	atomic_t forcewake_count;
 } drm_i915_private_t;
 
 enum i915_cache_level {



  parent reply	other threads:[~2012-02-10 23:15 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-10 22:35 [patch 00/86] 3.2.6-stable review Greg KH
2012-02-10 22:29 ` [patch 01/86] readahead: fix pipeline break caused by block plug Greg KH
2012-02-10 22:29 ` [patch 02/86] ALSA: hda - Fix the logic to detect VIA analog low-current mode Greg KH
2012-02-10 22:29 ` [patch 03/86] ALSA: HDA: Remove quirk for Asus N53Jq Greg KH
2012-02-10 22:29 ` [patch 04/86] ALSA: hda - Apply 0x0f-VREF fix to all ASUS laptops with ALC861/660 Greg KH
2012-02-10 22:29 ` [patch 05/86] ALSA: hda - Fix calling cs_automic twice for Cirrus codecs Greg KH
2012-02-10 22:29 ` [patch 06/86] ALSA: hda - Allow analog low-current mode when dynamic power-control is on Greg KH
2012-02-10 22:29 ` [patch 07/86] ALSA: HDA: Fix duplicated output to more than one codec Greg KH
2012-02-10 22:29 ` [patch 08/86] ALSA: hda - Disable dynamic-power control for VIA as default Greg KH
2012-02-10 22:29 ` [patch 09/86] ASoC: wm_hubs: Enable line out VMID buffer for single ended line outputs Greg KH
2012-02-10 22:29 ` [patch 10/86] ASoC: wm_hubs: fix wrong bits for LINEOUT2 N/P mixer Greg KH
2012-02-10 22:29 ` [patch 11/86] ARM: 7306/1: vfp: flush thread hwstate before restoring context from sigframe Greg KH
2012-02-10 22:29 ` [patch 12/86] ARM: 7307/1: vfp: fix ptrace regset modification race Greg KH
2012-02-10 22:29 ` [patch 13/86] ARM: 7308/1: vfp: flush thread hwstate before copying ptrace registers Greg KH
2012-02-10 22:29 ` [patch 14/86] ARM: OMAP2+: GPMC: fix device size setup Greg KH
2012-02-10 22:29 ` [patch 15/86] drivers/tty/vt/vt_ioctl.c: fix KDFONTOP 32bit compatibility layer Greg KH
2012-02-10 22:29 ` [patch 16/86] proc: mem_release() should check mm != NULL Greg KH
2012-02-10 22:29 ` [patch 17/86] proc: unify mem_read() and mem_write() Greg KH
2012-02-10 22:29 ` [patch 18/86] proc: make sure mem_open() doesnt pin the targets memory Greg KH
2012-02-10 22:29 ` [patch 19/86] firewire: ohci: add reset packet quirk for SB Audigy Greg KH
2012-02-10 22:29 ` [patch 20/86] firewire: ohci: disable MSI on Ricoh controllers Greg KH
2012-02-10 22:29 ` [patch 21/86] IB/mlx4: pass SMP vendor-specific attribute MADs to firmware Greg KH
2012-02-10 22:29 ` [patch 22/86] RDMA/core: Fix kernel panic by always initializing qp->usecnt Greg KH
2012-02-10 22:29 ` [patch 23/86] kprobes: fix a memory leak in function pre_handler_kretprobe() Greg KH
2012-02-10 22:29 ` [patch 24/86] mtd: gpmi-nand bugfix: reset the BCH module when it is not MX23 Greg KH
2012-02-10 22:29 ` [patch 25/86] Revert "mtd: atmel_nand: optimize read/write buffer functions" Greg KH
2012-02-10 22:29 ` [patch 26/86] at_hdmac: bugfix for enabling channel irq Greg KH
2012-02-10 22:29 ` [patch 27/86] mm/filemap_xip.c: fix race condition in xip_file_fault() Greg KH
2012-02-10 22:29 ` [patch 28/86] mm: compaction: check pfn_valid when entering a new MAX_ORDER_NR_PAGES block during isolation for migration Greg KH
2012-02-10 22:29 ` [patch 29/86] PM / Hibernate: Fix s2disk regression related to freezing workqueues Greg KH
2012-02-10 22:29 ` [patch 30/86] PM / QoS: CPU C-state breakage with PM Qos change Greg KH
2012-02-10 22:29 ` [patch 31/86] drm/radeon: Set DESKTOP_HEIGHT register to the framebuffer (not mode) height Greg KH
2012-02-10 22:29 ` [patch 32/86] drm/nouveau/gem: fix fence_sync race / oops Greg KH
2012-02-10 22:29 ` [patch 33/86] drm/radeon/kms: disable output polling when suspended Greg KH
2012-02-10 22:29 ` [patch 34/86] drm/radeon/kms: fix TRAVIS panel setup Greg KH
2012-02-10 22:29 ` [patch 35/86] sched/rt: Fix task stack corruption under __ARCH_WANT_INTERRUPTS_ON_CTXSW Greg KH
2012-02-10 22:29 ` [patch 36/86] PM / Hibernate: Thaw processes in SNAPSHOT_CREATE_IMAGE ioctl test path Greg KH
2012-02-10 22:29 ` [patch 37/86] PM / Hibernate: Thaw kernel threads in SNAPSHOT_CREATE_IMAGE ioctl path Greg KH
2012-02-10 22:29 ` [patch 38/86] 8139cp: fix missing napi_gro_flush Greg KH
2012-02-10 22:29 ` [patch 39/86] udf: Mark LVID buffer as uptodate before marking it dirty Greg KH
2012-02-10 22:29 ` [patch 40/86] drm/i915: HDMI hot remove notification to audio driver Greg KH
2012-02-10 22:30 ` [patch 41/86] drm/i915: DisplayPort " Greg KH
2012-02-10 22:30 ` [patch 42/86] drm/i915: check ACTHD of all rings Greg KH
2012-02-10 22:30 ` [patch 43/86] drm/i915: Fix TV Out refresh rate Greg KH
2012-02-10 22:30 ` [patch 44/86] drm/i915: handle 3rd pipe Greg KH
2012-02-10 22:30 ` [patch 45/86] drm/i915: convert force_wake_get to func pointer in the gpu reset code Greg KH
2012-02-10 22:30 ` Greg KH [this message]
2012-02-10 22:30 ` [patch 47/86] eCryptfs: Infinite loop due to overflow in ecryptfs_write() Greg KH
2012-02-10 22:30 ` [patch 48/86] hwmon: (w83627ehf) Fix number of fans for NCT6776F Greg KH
2012-02-10 22:30 ` [patch 49/86] cifs: Fix oops in session setup code for null user mounts Greg KH
2012-02-10 22:30 ` [patch 50/86] atmel_lcdfb: fix usage of CONTRAST_CTR in suspend/resume Greg KH
2012-02-10 22:30 ` [patch 51/86] lockdep, bug: Exclude TAINT_FIRMWARE_WORKAROUND from disabling lockdep Greg KH
2012-02-10 22:30 ` [patch 52/86] lockdep, bug: Exclude TAINT_OOT_MODULE from disabling lock debugging Greg KH
2012-02-10 22:30 ` [patch 53/86] iscsi-target: Fix reject release handling in iscsit_free_cmd() Greg KH
2012-02-10 22:30 ` [patch 54/86] iscsi-target: Fix double list_add with iscsit_alloc_buffs reject Greg KH
2012-02-10 22:30 ` [patch 55/86] iscsi-target: Fix discovery with INADDR_ANY and IN6ADDR_ANY_INIT Greg KH
2012-02-10 22:30 ` [patch 56/86] ASoC: wm_hubs: Fix routing of input PGAs to line output mixer Greg KH
2012-02-10 22:30 ` [patch 57/86] ASoC: wm_hubs: Correct line input to line output 2 paths Greg KH
2012-02-10 22:30 ` [patch 58/86] ASoC: wm8962: Fix word length configuration Greg KH
2012-02-10 22:30 ` [patch 59/86] ASoC: wm8994: Enabling VMID should take a runtime PM reference Greg KH
2012-02-10 22:30 ` [patch 60/86] ASoC: wm8994: Fix typo in VMID ramp setting Greg KH
2012-02-10 22:30 ` [patch 61/86] pcmcia: fix socket refcount decrementing on each resume Greg KH
2012-02-10 22:30 ` [patch 62/86] ALSA: oxygen, virtuoso: fix exchanged L/R volumes of aux and CD inputs Greg KH
2012-02-10 22:30 ` [patch 63/86] iommu/amd: Work around broken IVRS tables Greg KH
2012-02-10 22:30 ` [patch 64/86] iommu/msm: Fix error handling in msm_iommu_unmap() Greg KH
2012-02-10 22:30 ` [patch 65/86] mm: compaction: check for overlapping nodes during isolation for migration Greg KH
2012-02-10 22:30 ` [patch 66/86] mm: fix UP THP spin_is_locked BUGs Greg KH
2012-02-10 22:30 ` [patch 67/86] target: Use correct preempted registration sense code Greg KH
2012-02-10 22:30 ` [patch 68/86] target: Allow PERSISTENT RESERVE IN for non-reservation holder Greg KH
2012-02-10 22:30 ` [patch 69/86] target: Correct sense key for INVALID FIELD IN {PARAMETER LIST,CDB} Greg KH
2012-02-10 22:30 ` [patch 70/86] target: Add workaround for zero-length control CDB handling Greg KH
2012-02-10 22:30 ` [patch 71/86] target: Return correct ASC for unimplemented VPD pages Greg KH
2012-02-10 22:30 ` [patch 72/86] target: Fail INQUIRY commands with EVPD==0 but PAGE CODE!=0 Greg KH
2012-02-10 22:30 ` [patch 73/86] Staging: asus_oled: fix image processing Greg KH
2012-02-10 22:30 ` [patch 74/86] Staging: asus_oled: fix NULL-ptr crash on unloading Greg KH
2012-02-10 22:30 ` [patch 75/86] staging: r8712u: Add new Sitecom UsB ID Greg KH
2012-02-10 22:30 ` [patch 76/86] staging: r8712u: Use asynchronous firmware loading Greg KH
2012-02-10 22:30 ` [patch 77/86] usb: ch9.h: usb_endpoint_maxp() uses __le16_to_cpu() Greg KH
2012-02-10 22:30 ` [patch 78/86] usb: gadget: zero: fix bug in loopback autoresume handling Greg KH
2012-02-10 22:30 ` [patch 79/86] usb: Skip PCI USB quirk handling for Netlogic XLP Greg KH
2012-02-10 22:30 ` [patch 80/86] USB: usbserial: add new PID number (0xa951) to the ftdi driver Greg KH
2012-02-10 22:30 ` [patch 81/86] USB: add new zte 3g-dongles pid to option.c Greg KH
2012-02-10 22:30 ` [patch 82/86] zcache: Set SWIZ_BITS to 8 to reduce tmem bucket lock contention Greg KH
2012-02-10 22:30 ` [patch 83/86] zcache: fix deadlock condition Greg KH
2012-02-10 22:30 ` [patch 84/86] mmc: cb710 core: Add missing spin_lock_init for irq_lock of struct cb710_chip Greg KH
2012-02-10 22:30 ` [patch 85/86] [CPUFREQ] powernow-k8: Avoid Pstate MSR accesses on systems supporting CPB Greg KH
2012-02-10 22:30 ` [patch 86/86] [CPUFREQ] powernow-k8: Fix indexing issue Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120210222949.102085830@clark.kroah.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=chris@chris-wilson.co.uk \
    --cc=daniel.vetter@ffwll.ch \
    --cc=eugeni.dodonov@intel.com \
    --cc=keithp@keithp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox