Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 735dc0d1 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-kms-locking' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

The aim of this locking rework is that ioctls which a compositor should be
might call for every frame (set_cursor, page_flip, addfb, rmfb and
getfb/create_handle) should not be able to block on kms background
activities like output detection. And since each EDID read takes about
25ms (in the best case), that always means we'll drop at least one frame.

The solution is to add per-crtc locking for these ioctls, and restrict
background activities to only use the global lock. Change-the-world type
of events (modeset, dpms, ...) need to grab all locks.

Two tricky parts arose in the conversion:
- A lot of current code assumes that a kms fb object can't disappear while
  holding the global lock, since the current code serializes fb
  destruction with it. Hence proper lifetime management using the already
  created refcounting for fbs need to be instantiated for all ioctls and
  interfaces/users.

- The rmfb ioctl removes the to-be-deleted fb from all active users. But
  unconditionally taking the global kms lock to do so introduces an
  unacceptable potential stall point. And obviously changing the userspace
  abi isn't on the table, either. Hence this conversion opportunistically
  checks whether the rmfb ioctl holds the very last reference, which
  guarantees that the fb isn't in active use on any crtc or plane (thanks
  to the conversion to the new lifetime rules using proper refcounting).
  Only if this is not the case will the code go through the slowpath and
  grab all modeset locks. Sane compositors will never hit this path and so
  avoid the stall, but userspace relying on these semantics will also not
  break.

All these cases are exercised by the newly added subtests for the i-g-t
kms_flip, tested on a machine where a full detect cycle takes around 100
ms.  It works, and no frames are dropped any more with these patches
applied.  kms_flip also contains a special case to exercise the
above-describe rmfb slowpath.

* 'drm-kms-locking' of git://people.freedesktop.org/~danvet/drm-intel: (335 commits)
  drm/fb_helper: check whether fbcon is bound
  drm/doc: updates for new framebuffer lifetime rules
  drm: don't hold crtc mutexes for connector ->detect callbacks
  drm: only grab the crtc lock for pageflips
  drm: optimize drm_framebuffer_remove
  drm/vmwgfx: add proper framebuffer refcounting
  drm/i915: dump refcount into framebuffer debugfs file
  drm: refcounting for crtc framebuffers
  drm: refcounting for sprite framebuffers
  drm: fb refcounting for dirtyfb_ioctl
  drm: don't take modeset locks in getfb ioctl
  drm: push modeset_lock_all into ->fb_create driver callbacks
  drm: nest modeset locks within fpriv->fbs_lock
  drm: reference framebuffers which are on the idr
  drm: revamp framebuffer cleanup interfaces
  drm: create drm_framebuffer_lookup
  drm: revamp locking around fb creation/destruction
  drm: only take the crtc lock for ->cursor_move
  drm: only take the crtc lock for ->cursor_set
  drm: add per-crtc locks
  ...
parents bac4b7c3 20c60c35
Loading
Loading
Loading
Loading
+49 −14
Original line number Diff line number Diff line
@@ -978,10 +978,25 @@ int max_width, max_height;</synopsis>
        If the parameters are deemed valid, drivers then create, initialize and
        return an instance of struct <structname>drm_framebuffer</structname>.
        If desired the instance can be embedded in a larger driver-specific
        structure. The new instance is initialized with a call to
        <function>drm_framebuffer_init</function> which takes a pointer to DRM
        frame buffer operations (struct
        <structname>drm_framebuffer_funcs</structname>). Frame buffer operations are
	structure. Drivers must fill its <structfield>width</structfield>,
	<structfield>height</structfield>, <structfield>pitches</structfield>,
        <structfield>offsets</structfield>, <structfield>depth</structfield>,
        <structfield>bits_per_pixel</structfield> and
        <structfield>pixel_format</structfield> fields from the values passed
        through the <parameter>drm_mode_fb_cmd2</parameter> argument. They
        should call the <function>drm_helper_mode_fill_fb_struct</function>
        helper function to do so.
      </para>

      <para>
	The initailization of the new framebuffer instance is finalized with a
	call to <function>drm_framebuffer_init</function> which takes a pointer
	to DRM frame buffer operations (struct
	<structname>drm_framebuffer_funcs</structname>). Note that this function
	publishes the framebuffer and so from this point on it can be accessed
	concurrently from other threads. Hence it must be the last step in the
	driver's framebuffer initialization sequence. Frame buffer operations
	are
        <itemizedlist>
          <listitem>
            <synopsis>int (*create_handle)(struct drm_framebuffer *fb,
@@ -1022,16 +1037,16 @@ int max_width, max_height;</synopsis>
        </itemizedlist>
      </para>
      <para>
        After initializing the <structname>drm_framebuffer</structname>
        instance drivers must fill its <structfield>width</structfield>,
        <structfield>height</structfield>, <structfield>pitches</structfield>,
        <structfield>offsets</structfield>, <structfield>depth</structfield>,
        <structfield>bits_per_pixel</structfield> and
        <structfield>pixel_format</structfield> fields from the values passed
        through the <parameter>drm_mode_fb_cmd2</parameter> argument. They
        should call the <function>drm_helper_mode_fill_fb_struct</function>
        helper function to do so.
      </para>
	The lifetime of a drm framebuffer is controlled with a reference count,
	drivers can grab additional references with
	<function>drm_framebuffer_reference</function> </para> and drop them
	again with <function>drm_framebuffer_unreference</function>. For
	driver-private framebuffers for which the last reference is never
	dropped (e.g. for the fbdev framebuffer when the struct
	<structname>drm_framebuffer</structname> is embedded into the fbdev
	helper struct) drivers can manually clean up a framebuffer at module
	unload time with
	<function>drm_framebuffer_unregister_private</function>.
    </sect2>
    <sect2>
      <title>Output Polling</title>
@@ -1043,6 +1058,22 @@ int max_width, max_height;</synopsis>
        operation.
      </para>
    </sect2>
    <sect2>
      <title>Locking</title>
      <para>
        Beside some lookup structures with their own locking (which is hidden
	behind the interface functions) most of the modeset state is protected
	by the <code>dev-&lt;mode_config.lock</code> mutex and additionally
	per-crtc locks to allow cursor updates, pageflips and similar operations
	to occur concurrently with background tasks like output detection.
	Operations which cross domains like a full modeset always grab all
	locks. Drivers there need to protect resources shared between crtcs with
	additional locking. They also need to be careful to always grab the
	relevant crtc locks if a modset functions touches crtc state, e.g. for
	load detection (which does only grab the <code>mode_config.lock</code>
	to allow concurrent screen updates on live crtcs).
      </para>
    </sect2>
  </sect1>

  <!-- Internals: kms initialization and cleanup -->
@@ -1609,6 +1640,10 @@ void intel_crt_init(struct drm_device *dev)
        make its properties available to applications.
      </para>
    </sect2>
    <sect2>
      <title>KMS API Functions</title>
!Edrivers/gpu/drm/drm_crtc.c
    </sect2>
  </sect1>

  <!-- Internals: kms helper functions -->
+23 −17
Original line number Diff line number Diff line
@@ -228,7 +228,7 @@ S: Maintained
F:	drivers/platform/x86/acerhdf.c

ACER WMI LAPTOP EXTRAS
M:	Joey Lee <jlee@novell.com>
M:	"Lee, Chun-Yi" <jlee@suse.com>
L:	platform-driver-x86@vger.kernel.org
S:	Maintained
F:	drivers/platform/x86/acer-wmi.c
@@ -648,7 +648,7 @@ F: arch/arm/

ARM SUB-ARCHITECTURES
L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S:	MAINTAINED
S:	Maintained
F:	arch/arm/mach-*/
F:	arch/arm/plat-*/
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
@@ -1351,6 +1351,14 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k
S:	Supported
F:	drivers/net/wireless/ath/ath9k/

WILOCITY WIL6210 WIRELESS DRIVER
M:	Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
L:	linux-wireless@vger.kernel.org
L:	wil6210@qca.qualcomm.com
S:	Supported
W:	http://wireless.kernel.org/en/users/Drivers/wil6210
F:	drivers/net/wireless/ath/wil6210/

CARL9170 LINUX COMMUNITY WIRELESS DRIVER
M:	Christian Lamparter <chunkeey@googlemail.com>
L:	linux-wireless@vger.kernel.org
@@ -1964,9 +1972,9 @@ S: Maintained
F:	drivers/usb/host/ohci-ep93xx.c

CIRRUS LOGIC CS4270 SOUND DRIVER
M:	Timur Tabi <timur@freescale.com>
M:	Timur Tabi <timur@tabi.org>
L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
S:	Supported
S:	Odd Fixes
F:	sound/soc/codecs/cs4270*

CLEANCACHE API
@@ -3183,9 +3191,9 @@ F: include/uapi/video/
F:	include/uapi/linux/fb.h

FREESCALE DIU FRAMEBUFFER DRIVER
M:	Timur Tabi <timur@freescale.com>
M:	Timur Tabi <timur@tabi.org>
L:	linux-fbdev@vger.kernel.org
S:	Supported
S:	Maintained
F:	drivers/video/fsl-diu-fb.*

FREESCALE DMA DRIVER
@@ -3220,9 +3228,8 @@ F: drivers/net/ethernet/freescale/fs_enet/
F:	include/linux/fs_enet_pd.h

FREESCALE QUICC ENGINE LIBRARY
M:	Timur Tabi <timur@freescale.com>
L:	linuxppc-dev@lists.ozlabs.org
S:	Supported
S:	Orphan
F:	arch/powerpc/sysdev/qe_lib/
F:	arch/powerpc/include/asm/*qe.h

@@ -3241,16 +3248,16 @@ S: Maintained
F:	drivers/net/ethernet/freescale/ucc_geth*

FREESCALE QUICC ENGINE UCC UART DRIVER
M:	Timur Tabi <timur@freescale.com>
M:	Timur Tabi <timur@tabi.org>
L:	linuxppc-dev@lists.ozlabs.org
S:	Supported
S:	Maintained
F:	drivers/tty/serial/ucc_uart.c

FREESCALE SOC SOUND DRIVERS
M:	Timur Tabi <timur@freescale.com>
M:	Timur Tabi <timur@tabi.org>
L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
L:	linuxppc-dev@lists.ozlabs.org
S:	Supported
S:	Maintained
F:	sound/soc/fsl/fsl*
F:	sound/soc/fsl/mpc8610_hpcd.c

@@ -5077,7 +5084,7 @@ S: Maintained
F:	drivers/media/radio/radio-mr800.c

MSI LAPTOP SUPPORT
M:	"Lee, Chun-Yi" <jlee@novell.com>
M:	"Lee, Chun-Yi" <jlee@suse.com>
L:	platform-driver-x86@vger.kernel.org
S:	Maintained
F:	drivers/platform/x86/msi-laptop.c
@@ -5507,8 +5514,7 @@ M: Benoît Cousson <b-cousson@ti.com>
M:	Paul Walmsley <paul@pwsan.com>
L:	linux-omap@vger.kernel.org
S:	Maintained
F:	arch/arm/mach-omap2/omap_hwmod.c
F:	arch/arm/plat-omap/include/plat/omap_hwmod.h
F:	arch/arm/mach-omap2/omap_hwmod.*

OMAP HWMOD DATA FOR OMAP4-BASED DEVICES
M:	Benoît Cousson <b-cousson@ti.com>
@@ -7334,7 +7340,7 @@ S: Odd Fixes
F:	drivers/staging/speakup/

STAGING - TI DSP BRIDGE DRIVERS
M:	Omar Ramirez Luna <omar.ramirez@ti.com>
M:	Omar Ramirez Luna <omar.ramirez@copitl.com>
S:	Odd Fixes
F:	drivers/staging/tidspbridge/

@@ -8526,7 +8532,7 @@ F: Documentation/x86/
F:	arch/x86/

X86 PLATFORM DRIVERS
M:	Matthew Garrett <mjg@redhat.com>
M:	Matthew Garrett <matthew.garrett@nebula.com>
L:	platform-driver-x86@vger.kernel.org
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
S:	Maintained
+1 −1
Original line number Diff line number Diff line
VERSION = 3
PATCHLEVEL = 8
SUBLEVEL = 0
EXTRAVERSION = -rc3
EXTRAVERSION = -rc4
NAME = Terrified Chipmunk

# *DOCUMENTATION*
+1 −0
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb

targets += dtbs
targets += $(dtb-y)
endif

# *.dtb used to be generated in the directory above. Clean out the
+18 −0
Original line number Diff line number Diff line
@@ -306,6 +306,22 @@
					};
				};

				ssc0 {
					pinctrl_ssc0_tx: ssc0_tx-0 {
						atmel,pins =
							<1 16 0x1 0x0	/* PB16 periph A */
							 1 17 0x1 0x0	/* PB17 periph A */
							 1 18 0x1 0x0>;	/* PB18 periph A */
					};

					pinctrl_ssc0_rx: ssc0_rx-0 {
						atmel,pins =
							<1 19 0x1 0x0	/* PB19 periph A */
							 1 20 0x1 0x0	/* PB20 periph A */
							 1 21 0x1 0x0>;	/* PB21 periph A */
					};
				};

				pioA: gpio@fffff400 {
					compatible = "atmel,at91rm9200-gpio";
					reg = <0xfffff400 0x200>;
@@ -450,6 +466,8 @@
				compatible = "atmel,at91rm9200-ssc";
				reg = <0xfffbc000 0x4000>;
				interrupts = <14 4 5>;
				pinctrl-names = "default";
				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
				status = "disabled";
			};

Loading