- Jul 04, 2024
-
-
Lyude Paul authored
This allows us to store hrtimers in the driver's private CRTC data, which we can use in rvkms for emulating vblanks. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Using the rest of the bindings we've just added, add a binding for hrtimer_forward_now(). Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
This is just a binding for hrtimer_cb_get_time() - which we'll be using in a moment for implementing a binding for hrtimer_forward_now(). Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
With Linux's hrtimer API, certain functions require we either acquire proper locking to call specific methods - or that we call said methods from the context of the timer callback. hrtimer_forward() is one of these functions, so we start by adding a new TimerCallbackContext type which provides a way of calling these methods that is inaccessible outside of hrtimer callbacks. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
A binding for hrtimer_cancel(). Additionally, begin using this safe wrapper in our PinnedDrop implementation. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Binding for hrtimer_start_range_ns() for relative mode timers Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
- Jul 03, 2024
-
-
Lyude Paul authored
While working on rvkms, I noticed that there's no code that actually uses the drm_pending_vblank_event that's embedded in vkms_output. So, just drop the member from the struct. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
one timer can be embedded in a Rust struct. The hrtimer Rust API is based on the intrusive style pattern introduced by the Rust workqueue API. Signed-off-by:
Andreas Hindborg <a.hindborg@samsung.com>
-
- Jul 02, 2024
-
-
Lyude Paul authored
It turns out that if you happen to have a kernel config where CONFIG_DRM_PANIC is disabled and spinlock debugging is enabled, along with KMS being enabled - we'll end up trying to acquire an uninitialized spin_lock with drm_panic_lock() when we try to do a commit: rvkms rvkms.0: [drm:drm_atomic_commit] committing 0000000068d2ade1 INFO: trying to register non-static key. The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator. CPU: 4 PID: 1347 Comm: modprobe Not tainted 6.10.0-rc1Lyude-Test+ #272 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20240524-3.fc40 05/24/2024 Call Trace: <TASK> dump_stack_lvl+0x77/0xa0 assign_lock_key+0x114/0x120 register_lock_class+0xa8/0x2c0 __lock_acquire+0x7d/0x2bd0 ? __vmap_pages_range_noflush+0x3a8/0x550 ? drm_atomic_helper_swap_state+0x2ad/0x3a0 lock_acquire+0xec/0x290 ? drm_atomic_helper_swap_state+0x2ad/0x3a0 ? lock_release+0xee/0x310 _raw_spin_lock_irqsave+0x4e/0x70 ? drm_atomic_helper_swap_state+0x2ad/0x3a0 drm_atomic_helper_swap_state+0x2ad/0x3a0 drm_atomic_helper_commit+0xb1/0x270 drm_atomic_commit+0xaf/0xe0 ? __pfx___drm_printfn_info+0x10/0x10 drm_client_modeset_commit_atomic+0x1a1/0x250 drm_client_modeset_commit_locked+0x4b/0x180 drm_client_modeset_commit+0x27/0x50 __drm_fb_helper_restore_fbdev_mode_unlocked+0x76/0x90 drm_fb_helper_set_par+0x38/0x40 fbcon_init+0x3c4/0x690 visual_init+0xc0/0x120 do_bind_con_driver+0x409/0x4c0 do_take_over_console+0x233/0x280 do_fb_registered+0x11f/0x210 fbcon_fb_registered+0x2c/0x60 register_framebuffer+0x248/0x2a0 __drm_fb_helper_initial_config_and_unlock+0x58a/0x720 drm_fbdev_generic_client_hotplug+0x6e/0xb0 drm_client_register+0x76/0xc0 _RNvXs_CsHeezP08sTT_5rvkmsNtB4_5RvkmsNtNtCs1cdwasc6FUb_6kernel8platform6Driver5probe+0xed2/0x1060 [rvkms] ? _RNvMs_NtCs1cdwasc6FUb_6kernel8platformINtB4_7AdapterNtCsHeezP08sTT_5rvkms5RvkmsE14probe_callbackBQ_+0x2b/0x70 [rvkms] ? acpi_dev_pm_attach+0x25/0x110 ? platform_probe+0x6a/0xa0 ? really_probe+0x10b/0x400 ? __driver_probe_device+0x7c/0x140 ? driver_probe_device+0x22/0x1b0 ? __device_attach_driver+0x13a/0x1c0 ? __pfx___device_attach_driver+0x10/0x10 ? bus_for_each_drv+0x114/0x170 ? __device_attach+0xd6/0x1b0 ? bus_probe_device+0x9e/0x120 ? device_add+0x288/0x4b0 ? platform_device_add+0x75/0x230 ? platform_device_register_full+0x141/0x180 ? rust_helper_platform_device_register_simple+0x85/0xb0 ? _RNvMs2_NtCs1cdwasc6FUb_6kernel8platformNtB5_6Device13create_simple+0x1d/0x60 ? _RNvXs0_CsHeezP08sTT_5rvkmsNtB5_5RvkmsNtCs1cdwasc6FUb_6kernel6Module4init+0x11e/0x160 [rvkms] ? 0xffffffffc083f000 ? init_module+0x20/0x1000 [rvkms] ? kernfs_xattr_get+0x3e/0x80 ? do_one_initcall+0x148/0x3f0 ? __lock_acquire+0x5ef/0x2bd0 ? __lock_acquire+0x5ef/0x2bd0 ? __lock_acquire+0x5ef/0x2bd0 ? put_cpu_partial+0x51/0x1d0 ? lock_acquire+0xec/0x290 ? put_cpu_partial+0x51/0x1d0 ? lock_release+0xee/0x310 ? put_cpu_partial+0x51/0x1d0 ? fs_reclaim_acquire+0x69/0xf0 ? lock_acquire+0xec/0x290 ? fs_reclaim_acquire+0x69/0xf0 ? kfree+0x22f/0x340 ? lock_release+0xee/0x310 ? kmalloc_trace_noprof+0x48/0x340 ? do_init_module+0x22/0x240 ? kmalloc_trace_noprof+0x155/0x340 ? do_init_module+0x60/0x240 ? __se_sys_finit_module+0x2e0/0x3f0 ? do_syscall_64+0xa4/0x180 ? syscall_exit_to_user_mode+0x108/0x140 ? do_syscall_64+0xb0/0x180 ? vma_end_read+0xd0/0xe0 ? do_user_addr_fault+0x309/0x640 ? clear_bhb_loop+0x45/0xa0 ? clear_bhb_loop+0x45/0xa0 ? clear_bhb_loop+0x45/0xa0 ? entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK> Fix this by stubbing these macros out when this config option isn't enabled, along with fixing the unused variable warning that introduces. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Sima pointed out that drm_crtc_state violates some of the guarantees that other atomic states have, in that the structure can be mutated even after being swapped in. As a result, we need to update our bindings to not assume that this structure follows rust's data aliasing rules like the rest of the KMS atomic states.
-
Lyude Paul authored
-
Lyude Paul authored
Now that we've added all of the bits that we need for the KMS API, it's time to Bring The Beef and introduce RVKMS! TODO: write something more here I guess? Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Just a simple binding for retrieving the name of the device through dev_name(). Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
TODO: * The idea for this came from Maíra originally, and they should probably be the commit author (we'll fix that before final submission because credit is important :3, right now it's just a bit easier to rewrite the commit)
-
Lyude Paul authored
A binding for retrieving the current rotation of a DRM plane state. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Just a binding for drm_simplify_rotation(). We add this in a new module blend.rs in order to match the layout of the C side of things. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Just add some short-hand aliases to the raw bindings, since that's basically all we need. We put this in a new mode.rs module to match the layout of the C side of KMS. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Bindings for returning the src and dst rectangles for an atomic plane state. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
This is just a binding around drm_mode_config_reset(), which should be called during initialization of a modesetting driver if it doesn't read-back hardware state. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Since RVKMS uses drm_shadow_plane_state instead of the normal drm_plane_state, let's add bindings to allow drivers to use this using the PlaneStateHelper trait that we introduced before. Of course, all of the normal methods available to DRM planes are also available on shadow planes through the use of AsRawPlaneState and friends. Signed-off-by:
Lyude Paul <lyude@redhat.com> TODO: * Make sure that documentation is consistent and finished
-
Lyude Paul authored
Add optional trait methods for DRM's prepare_fb() and cleanup_fb() callbacks now that we have proper Framebuffer bindings. As well, introduce a new PlaneState mutator: PlaneStateMutator. The purpose of this mutator type is for callbacks where we want the implementor to be able to modify the atomic plane state, without providing access to the rest of the atomic state. TODO: * Write documentation Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Returns the Framebuffer currently assigned in an atomic plane state. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
We're about to add some FB related callbacks to planes now, so let's introduce our bindings for Framebuffer objects. Just like Connectors, these use RcModeObject. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
A mandatory trait method used for implementing DRM's atomic plane update callback. This is currently only mandatory because with our current bindings, DRM will crash without this. TODO: See if we can fix that and make it only mandatory in certain situations.
-
Lyude Paul authored
Add a binding for DRM's plane state atomic check helper. TODO: * Finish up documentation (we need to document parameters too! I think?) Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Add a binding for retrieving an opaque reference to the CRTC currently set for an atomic plane state. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Optional trait method for implementing a plane's atomic_check(). TODO: * Documentation * Figure out if we can make this non-mandatory? Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
An optional trait method for implementing a CRTC's atomic state check. TODO: Write documentation Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Next up is introducing bindings that we can use to represent the global DRM atomic state, along with all of the various object states contained within. We do this by introducing a few new concepts: borrowed states, atomic state mutators, and atomic state composers. To understand these, we need to quickly touch upon the general life of an atomic commit. Assuming a driver does its own internal atomic commit, the procedure looks something like this: * Allocate a new atomic state * Duplicate the atomic state of each mode object we want to mutate, and add the duplicated state to the new atomic state * Check (possibly more then once) the atomic state, possibly modifying it along the way * Commit the atomic state to software (we'll call this commit time). At this point no new objects can be added to the state * Finish committing the atomic state to hardware asynchronously With this in mind, we introduce AtomicStateMutator and AtomicStateComposer (along with leaky variants intended for uses in FFI calls). An AtomicStateMutator allows mutating an atomic state but does not allow for adding new objects to the state. Subsequently, an AtomicStateComposer allows for both mutating an atomic state and adding new mode objects. We control when we expose each of these types in order to implement the limitations required by the aforementioned example. Note as well that AtomicStateComposer is intended to eventually be usable directly by drivers. In this scenario, a driver will be able to create an AtomicStateComposer (the equivalent of allocating an atomic state in C) and then commit it by passing it to our DRM bindings by-value, insuring that once the commit process begins it is impossible to keep using the AtomicStateComposer. The next part of this is allowing users to modify the atomic states of all of the objects contained within an atomic state. Since it's an extremely common usecase for objects to mutate the atomic state of multiple objects at once in an unpredictable order, we need a mechanism that will allow us to hand out &mut references to each state while ensuring at runtime that we do not break rust's data aliasing rules (which disallow us from ever having more then one &mut reference to the same piece of data). We do this by introducing the concept of a "borrowed" state. This is a very similar concept to RefCell, where it is ensured during runtime that when a &mut reference is taken out another one cannot be created until the corresponding Ref object has been dropped. Our equivalent Ref types are BorrowedConnectorState, BorrowedCrtcState, and BorrowedPlaneState. Each one of these types can be used in the same manner as a Ref - no additional borrows for an atomic state may be taken until the existing one has been dropped. Subsequently, all of these types implement their respective AsRaw* and FromRaw* counter-parts - and allow dereferencing to each driver-private data structure for fully qualified borrows (like BorrowedCrtcState<'a, CrtcState<T>>. This allows a pretty clean way of mutating multiple states at once without ever breaking rust's mutability rules. We'll use all of these types over the next few commits to begin introducing various atomic modeset callbacks to each mode object type. Signed-off-by:
Lyude Paul <lyude@redhat.com> TODO: * Make sure we have documentation everywhere * Make sure that we also eventually add upcasting capabilities to borrowed types
-
Lyude Paul authored
Same thing as OpaquePlane, but for encoders now. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Same thing as RawCrtc and RawCrtcState, but for DRM planes now
-
Lyude Paul authored
Same thing as RawConnector and RawConnectorState, just for CRTCs now. TODO: * Complete documentation Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Now that we have more then one way to refer to connectors, we also want to ensure that any methods which are common to any kind of connector type can be used on all connector representations. This is where RawConnector and RawConnectorState come in: we implement these traits for any type which implements AsRawConnector or AsRawConnectorState respectively. TODO: * Documentation Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Same thing as OpaqueCrtc and OpaqueCrtcState, but for plane states now. TODO: * Make sure that we have conversion functions to go back and forth from the Opaque versions and non-opaque versions. Currently we only have this for upcasting from OpaquePlane Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
This is the same thing as OpaqueConnector and OpaqueConnectorState, but for CRTCs now. TODO: * Add some of the missing functions we currently mention in documentation, mainly from_opaque() Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Since we allow drivers to have multiple implementations of DriverConnector and DriverConnectorState (in C, the equivalent of this is having multiple structs which embed drm_connector) - there are some situations we will run into where it's not possible for us to know the corresponding DriverConnector or DriverConnectorState for a given connector. The most obvious one is iterating through all connectors on a KMS device. So, take advantage of the various connector traits we added to introduce OpaqueConnector<> and OpaqueConnectorState<> which both can be used as a DRM connector and connector state respectively without needing to know the corresponding traits. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Add a wrapper for `drm_set_preferred_mode()` for our new `ConnectorGuard` type so we can set the preferred mode for RVKMS connectors. Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
Next up is filling out some of the basic connector hotplugging callbacks - which we'll need for setting up the fbdev helpers for KMS devices. Note that connector hotplugging in DRM follows a BFL scheme: pretty much all probing is protected under the mighty drm_device->mode_config.lock, which of course is a bit counter-intuitive to rust's locking schemes where data is always associated with its lock. Since that lock is embedded in an FFI type and not a rust type, we need to introduce our own wrapper type that acts as a lock acquisition for this. This brings us to introducing a few new types: * ModeConfigGuard - the most basic lock guard, as long as this object is alive we are guaranteed to be holding drm_device->mode_config.lock. This object doesn't do much else on its own currently. * UnsafeModeConfigGuard - exactly the same as ModeConfigGuard, but does not lock or unlock drm_device->mode_config.lock on its own and relies on the caller to do it. This is only useful for FFI callbacks, and can be used as a ModeConfigGuard through it's Deref implementation * ConnectorGuard - an object which corresponds to a specific typed DRM connector. This can only be acquired with a ModeConfigGuard, and will be used to allow calling methods that are only safe to call with drm_device->mode_config.lock held. Since it implements Deref<Target=Connector<T>> as well, it can also be used for any other operations that would normally be available on a DRM connector. And finally, we add the DriverConnector::get_modes() trait method which drivers can use to implement the drm_connector_helper_funcs.get_modes callback. Note that while we make this trait method mandatory, we only do so for the time being since VKMS doesn't do very much with DRM connectors - and as such we have no need yet to implement alternative connector probing schemes outside of get_modes(). Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
This adds a simple binding for completing the last step of creating a DRM connector - attaching its encoder. This function should only be called before the connector is registered, and DRM should enforce this itself by returning an error if a driver tries to add an encoder to an already-registered DRM connector. Note that unlike most of the methods we'll be adding to DRM mode objects, this is directly implemented on the Connector<T> type since I don't really think it would make sense for us to allow this operation on an OpaqueConnector (a DRM connector without a known DriverConnector implementation, something we'll be adding in the next few commits). Signed-off-by:
Lyude Paul <lyude@redhat.com>
-
Lyude Paul authored
While we don't have proper bindings for specifying more then literally one fourcc format, this is just enough to get us by for the time being. TODO: * Better commit message * Come up with some way of automating this, there's a heck of a lot of fourcc formats and I think trying to manually add bindings for each one is a bad idea * Documentation
-