37
37
#include <drm/drm_crtc.h>
38
38
#include <drm/drm_edid.h>
39
39
#include <drm/drm_fourcc.h>
40
+ #include <drm/drm_modeset_lock.h>
40
41
41
42
#include "drm_crtc_internal.h"
42
43
50
51
*/
51
52
void drm_modeset_lock_all (struct drm_device * dev )
52
53
{
53
- struct drm_crtc * crtc ;
54
+ struct drm_mode_config * config = & dev -> mode_config ;
55
+ struct drm_modeset_acquire_ctx * ctx ;
56
+ int ret ;
54
57
55
- mutex_lock (& dev -> mode_config .mutex );
58
+ ctx = kzalloc (sizeof (* ctx ), GFP_KERNEL );
59
+ if (WARN_ON (!ctx ))
60
+ return ;
56
61
57
- mutex_lock (& dev -> mode_config . connection_mutex );
62
+ mutex_lock (& config -> mutex );
58
63
59
- list_for_each_entry (crtc , & dev -> mode_config .crtc_list , head )
60
- mutex_lock_nest_lock (& crtc -> mutex , & dev -> mode_config .mutex );
64
+ drm_modeset_acquire_init (ctx , 0 );
65
+
66
+ retry :
67
+ ret = drm_modeset_lock (& config -> connection_mutex , ctx );
68
+ if (ret )
69
+ goto fail ;
70
+ ret = drm_modeset_lock_all_crtcs (dev , ctx );
71
+ if (ret )
72
+ goto fail ;
73
+
74
+ WARN_ON (config -> acquire_ctx );
75
+
76
+ /* now we hold the locks, so now that it is safe, stash the
77
+ * ctx for drm_modeset_unlock_all():
78
+ */
79
+ config -> acquire_ctx = ctx ;
80
+
81
+ drm_warn_on_modeset_not_all_locked (dev );
82
+
83
+ return ;
84
+
85
+ fail :
86
+ if (ret == - EDEADLK ) {
87
+ drm_modeset_backoff (ctx );
88
+ goto retry ;
89
+ }
61
90
}
62
91
EXPORT_SYMBOL (drm_modeset_lock_all );
63
92
@@ -69,12 +98,17 @@ EXPORT_SYMBOL(drm_modeset_lock_all);
69
98
*/
70
99
void drm_modeset_unlock_all (struct drm_device * dev )
71
100
{
72
- struct drm_crtc * crtc ;
101
+ struct drm_mode_config * config = & dev -> mode_config ;
102
+ struct drm_modeset_acquire_ctx * ctx = config -> acquire_ctx ;
73
103
74
- list_for_each_entry (crtc , & dev -> mode_config .crtc_list , head )
75
- mutex_unlock (& crtc -> mutex );
104
+ if (WARN_ON (!ctx ))
105
+ return ;
106
+
107
+ config -> acquire_ctx = NULL ;
108
+ drm_modeset_drop_locks (ctx );
109
+ drm_modeset_acquire_fini (ctx );
76
110
77
- mutex_unlock ( & dev -> mode_config . connection_mutex );
111
+ kfree ( ctx );
78
112
79
113
mutex_unlock (& dev -> mode_config .mutex );
80
114
}
@@ -95,9 +129,9 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev)
95
129
return ;
96
130
97
131
list_for_each_entry (crtc , & dev -> mode_config .crtc_list , head )
98
- WARN_ON (!mutex_is_locked (& crtc -> mutex ));
132
+ WARN_ON (!drm_modeset_is_locked (& crtc -> mutex ));
99
133
100
- WARN_ON (!mutex_is_locked (& dev -> mode_config .connection_mutex ));
134
+ WARN_ON (!drm_modeset_is_locked (& dev -> mode_config .connection_mutex ));
101
135
WARN_ON (!mutex_is_locked (& dev -> mode_config .mutex ));
102
136
}
103
137
EXPORT_SYMBOL (drm_warn_on_modeset_not_all_locked );
@@ -671,6 +705,8 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
671
705
}
672
706
EXPORT_SYMBOL (drm_framebuffer_remove );
673
707
708
+ DEFINE_WW_CLASS (crtc_ww_class );
709
+
674
710
/**
675
711
* drm_crtc_init_with_planes - Initialise a new CRTC object with
676
712
* specified primary and cursor planes.
@@ -690,24 +726,26 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
690
726
void * cursor ,
691
727
const struct drm_crtc_funcs * funcs )
692
728
{
729
+ struct drm_mode_config * config = & dev -> mode_config ;
693
730
int ret ;
694
731
695
732
crtc -> dev = dev ;
696
733
crtc -> funcs = funcs ;
697
734
crtc -> invert_dimensions = false;
698
735
699
736
drm_modeset_lock_all (dev );
700
- mutex_init (& crtc -> mutex );
701
- mutex_lock_nest_lock (& crtc -> mutex , & dev -> mode_config .mutex );
737
+ drm_modeset_lock_init (& crtc -> mutex );
738
+ /* dropped by _unlock_all(): */
739
+ drm_modeset_lock (& crtc -> mutex , config -> acquire_ctx );
702
740
703
741
ret = drm_mode_object_get (dev , & crtc -> base , DRM_MODE_OBJECT_CRTC );
704
742
if (ret )
705
743
goto out ;
706
744
707
745
crtc -> base .properties = & crtc -> properties ;
708
746
709
- list_add_tail (& crtc -> head , & dev -> mode_config . crtc_list );
710
- dev -> mode_config . num_crtc ++ ;
747
+ list_add_tail (& crtc -> head , & config -> crtc_list );
748
+ config -> num_crtc ++ ;
711
749
712
750
crtc -> primary = primary ;
713
751
if (primary )
@@ -735,6 +773,8 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
735
773
kfree (crtc -> gamma_store );
736
774
crtc -> gamma_store = NULL ;
737
775
776
+ drm_modeset_lock_fini (& crtc -> mutex );
777
+
738
778
drm_mode_object_put (dev , & crtc -> base );
739
779
list_del (& crtc -> head );
740
780
dev -> mode_config .num_crtc -- ;
@@ -1798,7 +1838,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
1798
1838
DRM_DEBUG_KMS ("[CONNECTOR:%d:?]\n" , out_resp -> connector_id );
1799
1839
1800
1840
mutex_lock (& dev -> mode_config .mutex );
1801
- mutex_lock (& dev -> mode_config .connection_mutex );
1841
+ drm_modeset_lock (& dev -> mode_config .connection_mutex , NULL );
1802
1842
1803
1843
connector = drm_connector_find (dev , out_resp -> connector_id );
1804
1844
if (!connector ) {
@@ -1897,7 +1937,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
1897
1937
out_resp -> count_encoders = encoders_count ;
1898
1938
1899
1939
out :
1900
- mutex_unlock (& dev -> mode_config .connection_mutex );
1940
+ drm_modeset_unlock (& dev -> mode_config .connection_mutex );
1901
1941
mutex_unlock (& dev -> mode_config .mutex );
1902
1942
1903
1943
return ret ;
@@ -2481,7 +2521,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
2481
2521
return - ENOENT ;
2482
2522
}
2483
2523
2484
- mutex_lock (& crtc -> mutex );
2524
+ drm_modeset_lock (& crtc -> mutex , NULL );
2485
2525
if (req -> flags & DRM_MODE_CURSOR_BO ) {
2486
2526
if (!crtc -> funcs -> cursor_set && !crtc -> funcs -> cursor_set2 ) {
2487
2527
ret = - ENXIO ;
@@ -2505,7 +2545,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
2505
2545
}
2506
2546
}
2507
2547
out :
2508
- mutex_unlock (& crtc -> mutex );
2548
+ drm_modeset_unlock (& crtc -> mutex );
2509
2549
2510
2550
return ret ;
2511
2551
@@ -4198,7 +4238,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
4198
4238
if (!crtc )
4199
4239
return - ENOENT ;
4200
4240
4201
- mutex_lock (& crtc -> mutex );
4241
+ drm_modeset_lock (& crtc -> mutex , NULL );
4202
4242
if (crtc -> primary -> fb == NULL ) {
4203
4243
/* The framebuffer is currently unbound, presumably
4204
4244
* due to a hotplug event, that userspace has not
@@ -4282,7 +4322,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
4282
4322
drm_framebuffer_unreference (fb );
4283
4323
if (old_fb )
4284
4324
drm_framebuffer_unreference (old_fb );
4285
- mutex_unlock (& crtc -> mutex );
4325
+ drm_modeset_unlock (& crtc -> mutex );
4286
4326
4287
4327
return ret ;
4288
4328
}
@@ -4647,7 +4687,7 @@ EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
4647
4687
void drm_mode_config_init (struct drm_device * dev )
4648
4688
{
4649
4689
mutex_init (& dev -> mode_config .mutex );
4650
- mutex_init (& dev -> mode_config .connection_mutex );
4690
+ drm_modeset_lock_init (& dev -> mode_config .connection_mutex );
4651
4691
mutex_init (& dev -> mode_config .idr_mutex );
4652
4692
mutex_init (& dev -> mode_config .fb_lock );
4653
4693
INIT_LIST_HEAD (& dev -> mode_config .fb_list );
@@ -4747,5 +4787,6 @@ void drm_mode_config_cleanup(struct drm_device *dev)
4747
4787
}
4748
4788
4749
4789
idr_destroy (& dev -> mode_config .crtc_idr );
4790
+ drm_modeset_lock_fini (& dev -> mode_config .connection_mutex );
4750
4791
}
4751
4792
EXPORT_SYMBOL (drm_mode_config_cleanup );
0 commit comments