native: Release output device files that are unused
In order to make it possible to e.g. unload an unused DRM device, we need to make sure that we don't keep the file descriptor open if we don't need it; otherwise we block anyone from unloading the corresponding module. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
This commit is contained in:
@ -655,6 +655,7 @@ retry_page_flips (gpointer user_data)
|
||||
g_critical ("Failed to page flip: %s", error->message);
|
||||
|
||||
meta_kms_page_flip_data_discard_in_impl (page_flip_data, error);
|
||||
meta_kms_impl_device_unhold_fd (impl_device);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -977,6 +978,7 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device,
|
||||
fb_id = 0;
|
||||
drm_mode = cached_mode_set->drm_mode;
|
||||
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
|
||||
meta_kms_impl_device_hold_fd (impl_device);
|
||||
schedule_retry_page_flip (impl_device_simple,
|
||||
crtc,
|
||||
fb_id,
|
||||
@ -1016,6 +1018,8 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device,
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_kms_impl_device_hold_fd (impl_device);
|
||||
|
||||
impl_device_simple->posted_page_flip_datas =
|
||||
g_list_prepend (impl_device_simple->posted_page_flip_datas,
|
||||
page_flip_data);
|
||||
@ -1367,6 +1371,8 @@ page_flip_handler (int fd,
|
||||
page_flip_data,
|
||||
meta_kms_crtc_get_id (crtc));
|
||||
|
||||
meta_kms_impl_device_unhold_fd (impl_device);
|
||||
|
||||
meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
|
||||
impl_device_simple->posted_page_flip_datas =
|
||||
g_list_remove (impl_device_simple->posted_page_flip_datas,
|
||||
@ -1465,6 +1471,14 @@ meta_kms_impl_device_simple_handle_page_flip_callback (MetaKmsImplDevice *impl
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dispose_page_flip_data (MetaKmsPageFlipData *page_flip_data,
|
||||
MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
|
||||
meta_kms_impl_device_unhold_fd (impl_device);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
@ -1489,7 +1503,7 @@ meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_
|
||||
meta_kms_impl_device_get_path (
|
||||
meta_kms_page_flip_data_get_impl_device (page_flip_data)));
|
||||
|
||||
meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
|
||||
dispose_page_flip_data (page_flip_data, impl_device);
|
||||
retry_page_flip_data_free (retry_page_flip_data);
|
||||
}
|
||||
g_clear_pointer (&impl_device_simple->pending_page_flip_retries, g_list_free);
|
||||
@ -1505,8 +1519,8 @@ meta_kms_impl_device_simple_prepare_shutdown (MetaKmsImplDevice *impl_device)
|
||||
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
|
||||
|
||||
g_list_foreach (impl_device_simple->posted_page_flip_datas,
|
||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
||||
NULL);
|
||||
(GFunc) dispose_page_flip_data,
|
||||
impl_device);
|
||||
g_clear_list (&impl_device_simple->posted_page_flip_datas, NULL);
|
||||
}
|
||||
|
||||
@ -1515,18 +1529,16 @@ meta_kms_impl_device_simple_finalize (GObject *object)
|
||||
{
|
||||
MetaKmsImplDeviceSimple *impl_device_simple =
|
||||
META_KMS_IMPL_DEVICE_SIMPLE (object);
|
||||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
|
||||
|
||||
g_list_free_full (impl_device_simple->pending_page_flip_retries,
|
||||
(GDestroyNotify) retry_page_flip_data_free);
|
||||
dispatch_page_flip_datas (&impl_device_simple->posted_page_flip_datas,
|
||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
||||
NULL);
|
||||
dispatch_page_flip_datas (&impl_device_simple->postponed_page_flip_datas,
|
||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
||||
NULL);
|
||||
(GFunc) dispose_page_flip_data,
|
||||
impl_device);
|
||||
dispatch_page_flip_datas (&impl_device_simple->postponed_mode_set_fallback_datas,
|
||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
||||
NULL);
|
||||
(GFunc) dispose_page_flip_data,
|
||||
impl_device);
|
||||
|
||||
g_assert (!impl_device_simple->posted_page_flip_datas);
|
||||
|
||||
@ -1548,7 +1560,6 @@ meta_kms_impl_device_simple_open_device_file (MetaKmsImplDevice *impl_device,
|
||||
MetaDevicePool *device_pool =
|
||||
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
||||
g_autoptr (MetaDeviceFile) device_file = NULL;
|
||||
int fd;
|
||||
|
||||
device_file = meta_device_pool_open (device_pool, path,
|
||||
META_DEVICE_FILE_FLAG_TAKE_CONTROL,
|
||||
@ -1556,13 +1567,26 @@ meta_kms_impl_device_simple_open_device_file (MetaKmsImplDevice *impl_device,
|
||||
if (!device_file)
|
||||
return NULL;
|
||||
|
||||
fd = meta_device_file_get_fd (device_file);
|
||||
|
||||
if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
|
||||
if (!meta_device_file_has_tag (device_file,
|
||||
META_DEVICE_FILE_TAG_KMS,
|
||||
META_KMS_DEVICE_FILE_TAG_SIMPLE))
|
||||
{
|
||||
g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
|
||||
"DRM_CLIENT_CAP_UNIVERSAL_PLANES not supported");
|
||||
return NULL;
|
||||
int fd = meta_device_file_get_fd (device_file);
|
||||
|
||||
g_warn_if_fail (!meta_device_file_has_tag (device_file,
|
||||
META_DEVICE_FILE_TAG_KMS,
|
||||
META_KMS_DEVICE_FILE_TAG_ATOMIC));
|
||||
|
||||
if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
|
||||
{
|
||||
g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
|
||||
"DRM_CLIENT_CAP_UNIVERSAL_PLANES not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
meta_device_file_tag (device_file,
|
||||
META_DEVICE_FILE_TAG_KMS,
|
||||
META_KMS_DEVICE_FILE_TAG_SIMPLE);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&device_file);
|
||||
|
Reference in New Issue
Block a user