xref: /DragonOS/kernel/src/driver/net/virtio_net.rs (revision 731bc2b32d7b37298883d7a15b6dca659b436ee4)
1 use core::{
2     any::Any,
3     cell::UnsafeCell,
4     fmt::Debug,
5     ops::{Deref, DerefMut},
6 };
7 
8 use alloc::{
9     string::{String, ToString},
10     sync::{Arc, Weak},
11     vec::Vec,
12 };
13 use smoltcp::{iface, phy, wire};
14 use unified_init::macros::unified_init;
15 use virtio_drivers::device::net::VirtIONet;
16 
17 use super::NetDevice;
18 use crate::{
19     arch::rand::rand,
20     driver::{
21         base::{
22             class::Class,
23             device::{
24                 bus::Bus,
25                 driver::{Driver, DriverCommonData},
26                 Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
27             },
28             kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
29             kset::KSet,
30         },
31         virtio::{
32             irq::virtio_irq_manager,
33             sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager},
34             transport::VirtIOTransport,
35             virtio_impl::HalImpl,
36             VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID,
37         },
38     },
39     exception::{irqdesc::IrqReturn, IrqNumber},
40     filesystem::kernfs::KernFSInode,
41     init::initcall::INITCALL_POSTCORE,
42     kerror,
43     libs::{
44         rwlock::{RwLockReadGuard, RwLockWriteGuard},
45         spinlock::{SpinLock, SpinLockGuard},
46     },
47     net::{generate_iface_id, net_core::poll_ifaces_try_lock_onetime, NET_DEVICES},
48     time::Instant,
49 };
50 use system_error::SystemError;
51 
52 static mut VIRTIO_NET_DRIVER: Option<Arc<VirtIONetDriver>> = None;
53 
54 const DEVICE_NAME: &str = "virtio_net";
55 
56 #[inline(always)]
57 fn virtio_net_driver() -> Arc<VirtIONetDriver> {
58     unsafe { VIRTIO_NET_DRIVER.as_ref().unwrap().clone() }
59 }
60 
61 pub struct VirtIoNetImpl {
62     inner: VirtIONet<HalImpl, VirtIOTransport, 2>,
63 }
64 
65 impl VirtIoNetImpl {
66     const fn new(inner: VirtIONet<HalImpl, VirtIOTransport, 2>) -> Self {
67         Self { inner }
68     }
69 }
70 
71 impl Deref for VirtIoNetImpl {
72     type Target = VirtIONet<HalImpl, VirtIOTransport, 2>;
73     fn deref(&self) -> &Self::Target {
74         &self.inner
75     }
76 }
77 
78 impl DerefMut for VirtIoNetImpl {
79     fn deref_mut(&mut self) -> &mut Self::Target {
80         &mut self.inner
81     }
82 }
83 
84 unsafe impl Send for VirtIoNetImpl {}
85 unsafe impl Sync for VirtIoNetImpl {}
86 
87 #[derive(Debug)]
88 struct VirtIONicDeviceInnerWrapper(UnsafeCell<VirtIONicDeviceInner>);
89 unsafe impl Send for VirtIONicDeviceInnerWrapper {}
90 unsafe impl Sync for VirtIONicDeviceInnerWrapper {}
91 
92 impl Deref for VirtIONicDeviceInnerWrapper {
93     type Target = VirtIONicDeviceInner;
94     fn deref(&self) -> &Self::Target {
95         unsafe { &*self.0.get() }
96     }
97 }
98 impl DerefMut for VirtIONicDeviceInnerWrapper {
99     fn deref_mut(&mut self) -> &mut Self::Target {
100         unsafe { &mut *self.0.get() }
101     }
102 }
103 
104 #[allow(clippy::mut_from_ref)]
105 impl VirtIONicDeviceInnerWrapper {
106     fn force_get_mut(&self) -> &mut <VirtIONicDeviceInnerWrapper as Deref>::Target {
107         unsafe { &mut *self.0.get() }
108     }
109 }
110 
111 /// Virtio网络设备驱动(加锁)
112 pub struct VirtIONicDeviceInner {
113     pub inner: Arc<SpinLock<VirtIoNetImpl>>,
114 }
115 
116 impl Clone for VirtIONicDeviceInner {
117     fn clone(&self) -> Self {
118         return VirtIONicDeviceInner {
119             inner: self.inner.clone(),
120         };
121     }
122 }
123 
124 impl Debug for VirtIONicDeviceInner {
125     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
126         f.debug_struct("VirtIONicDriver").finish()
127     }
128 }
129 
130 #[cast_to([sync] VirtIODevice)]
131 #[cast_to([sync] Device)]
132 pub struct VirtioInterface {
133     device_inner: VirtIONicDeviceInnerWrapper,
134     iface_id: usize,
135     iface_name: String,
136     dev_id: Arc<DeviceId>,
137     iface: SpinLock<iface::Interface>,
138     inner: SpinLock<InnerVirtIOInterface>,
139     locked_kobj_state: LockedKObjectState,
140 }
141 
142 #[derive(Debug)]
143 struct InnerVirtIOInterface {
144     name: Option<String>,
145     virtio_index: Option<VirtIODeviceIndex>,
146     device_common: DeviceCommonData,
147     kobj_common: KObjectCommonData,
148 }
149 
150 impl core::fmt::Debug for VirtioInterface {
151     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
152         f.debug_struct("VirtioInterface")
153             .field("iface_id", &self.iface_id)
154             .field("iface_name", &self.iface_name)
155             .field("dev_id", &self.dev_id)
156             .field("inner", &self.inner)
157             .field("locked_kobj_state", &self.locked_kobj_state)
158             .finish()
159     }
160 }
161 
162 impl VirtioInterface {
163     pub fn new(mut device_inner: VirtIONicDeviceInner, dev_id: Arc<DeviceId>) -> Arc<Self> {
164         let iface_id = generate_iface_id();
165         let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet(
166             wire::EthernetAddress(device_inner.inner.lock().mac_address()),
167         ));
168         iface_config.random_seed = rand() as u64;
169 
170         let iface = iface::Interface::new(iface_config, &mut device_inner, Instant::now().into());
171 
172         let result = Arc::new(VirtioInterface {
173             device_inner: VirtIONicDeviceInnerWrapper(UnsafeCell::new(device_inner)),
174             iface_id,
175             locked_kobj_state: LockedKObjectState::default(),
176             iface: SpinLock::new(iface),
177             iface_name: format!("eth{}", iface_id),
178             dev_id,
179             inner: SpinLock::new(InnerVirtIOInterface {
180                 name: None,
181                 virtio_index: None,
182                 device_common: DeviceCommonData::default(),
183                 kobj_common: KObjectCommonData::default(),
184             }),
185         });
186 
187         result.inner().device_common.driver =
188             Some(Arc::downgrade(&virtio_net_driver()) as Weak<dyn Driver>);
189 
190         return result;
191     }
192 
193     fn inner(&self) -> SpinLockGuard<InnerVirtIOInterface> {
194         return self.inner.lock();
195     }
196 
197     /// 获取网卡接口的名称
198     #[allow(dead_code)]
199     pub fn iface_name(&self) -> String {
200         self.iface_name.clone()
201     }
202 }
203 
204 impl VirtIODevice for VirtioInterface {
205     fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
206         poll_ifaces_try_lock_onetime().ok();
207         return Ok(IrqReturn::Handled);
208     }
209 
210     fn dev_id(&self) -> &Arc<DeviceId> {
211         return &self.dev_id;
212     }
213     fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
214         self.inner().virtio_index = Some(index);
215     }
216 
217     fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
218         return self.inner().virtio_index;
219     }
220 
221     fn set_device_name(&self, name: String) {
222         self.inner().name = Some(name);
223     }
224 
225     fn device_name(&self) -> String {
226         self.inner()
227             .name
228             .clone()
229             .unwrap_or_else(|| "virtio_net".to_string())
230     }
231 
232     fn device_type_id(&self) -> u32 {
233         virtio_drivers::transport::DeviceType::Network as u32
234     }
235 
236     fn vendor(&self) -> u32 {
237         VIRTIO_VENDOR_ID.into()
238     }
239 }
240 
241 impl Drop for VirtioInterface {
242     fn drop(&mut self) {
243         // 从全局的网卡接口信息表中删除这个网卡的接口信息
244         NET_DEVICES.write_irqsave().remove(&self.iface_id);
245     }
246 }
247 
248 impl Device for VirtioInterface {
249     fn dev_type(&self) -> DeviceType {
250         DeviceType::Net
251     }
252 
253     fn id_table(&self) -> IdTable {
254         IdTable::new(DEVICE_NAME.to_string(), None)
255     }
256 
257     fn bus(&self) -> Option<Weak<dyn Bus>> {
258         self.inner().device_common.bus.clone()
259     }
260 
261     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
262         self.inner().device_common.bus = bus;
263     }
264 
265     fn class(&self) -> Option<Arc<dyn Class>> {
266         let mut guard = self.inner();
267         let r = guard.device_common.class.clone()?.upgrade();
268         if r.is_none() {
269             guard.device_common.class = None;
270         }
271 
272         return r;
273     }
274 
275     fn set_class(&self, class: Option<Weak<dyn Class>>) {
276         self.inner().device_common.class = class;
277     }
278 
279     fn driver(&self) -> Option<Arc<dyn Driver>> {
280         let r = self.inner().device_common.driver.clone()?.upgrade();
281         if r.is_none() {
282             self.inner().device_common.driver = None;
283         }
284 
285         return r;
286     }
287 
288     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
289         self.inner().device_common.driver = driver;
290     }
291 
292     fn is_dead(&self) -> bool {
293         false
294     }
295 
296     fn can_match(&self) -> bool {
297         self.inner().device_common.can_match
298     }
299 
300     fn set_can_match(&self, can_match: bool) {
301         self.inner().device_common.can_match = can_match;
302     }
303 
304     fn state_synced(&self) -> bool {
305         true
306     }
307 }
308 
309 impl VirtIONicDeviceInner {
310     pub fn new(driver_net: VirtIONet<HalImpl, VirtIOTransport, 2>) -> Self {
311         let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet(
312             wire::EthernetAddress(driver_net.mac_address()),
313         ));
314 
315         iface_config.random_seed = rand() as u64;
316 
317         let inner = Arc::new(SpinLock::new(VirtIoNetImpl::new(driver_net)));
318         let result = VirtIONicDeviceInner { inner };
319         return result;
320     }
321 }
322 
323 pub struct VirtioNetToken {
324     driver: VirtIONicDeviceInner,
325     rx_buffer: Option<virtio_drivers::device::net::RxBuffer>,
326 }
327 
328 impl VirtioNetToken {
329     pub fn new(
330         driver: VirtIONicDeviceInner,
331         rx_buffer: Option<virtio_drivers::device::net::RxBuffer>,
332     ) -> Self {
333         return Self { driver, rx_buffer };
334     }
335 }
336 
337 impl phy::Device for VirtIONicDeviceInner {
338     type RxToken<'a> = VirtioNetToken where Self: 'a;
339     type TxToken<'a> = VirtioNetToken where Self: 'a;
340 
341     fn receive(
342         &mut self,
343         _timestamp: smoltcp::time::Instant,
344     ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
345         match self.inner.lock().receive() {
346             Ok(buf) => Some((
347                 VirtioNetToken::new(self.clone(), Some(buf)),
348                 VirtioNetToken::new(self.clone(), None),
349             )),
350             Err(virtio_drivers::Error::NotReady) => None,
351             Err(err) => panic!("VirtIO receive failed: {}", err),
352         }
353     }
354 
355     fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
356         // kdebug!("VirtioNet: transmit");
357         if self.inner.lock_irqsave().can_send() {
358             // kdebug!("VirtioNet: can send");
359             return Some(VirtioNetToken::new(self.clone(), None));
360         } else {
361             // kdebug!("VirtioNet: can not send");
362             return None;
363         }
364     }
365 
366     fn capabilities(&self) -> phy::DeviceCapabilities {
367         let mut caps = phy::DeviceCapabilities::default();
368         // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。
369         caps.max_transmission_unit = 2000;
370         /*
371            Maximum burst size, in terms of MTU.
372            The network device is unable to send or receive bursts large than the value returned by this function.
373            If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated.
374         */
375         caps.max_burst_size = Some(1);
376         return caps;
377     }
378 }
379 
380 impl phy::TxToken for VirtioNetToken {
381     fn consume<R, F>(self, len: usize, f: F) -> R
382     where
383         F: FnOnce(&mut [u8]) -> R,
384     {
385         // // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。
386         let mut driver_net = self.driver.inner.lock();
387         let mut tx_buf = driver_net.new_tx_buffer(len);
388         let result = f(tx_buf.packet_mut());
389         driver_net.send(tx_buf).expect("virtio_net send failed");
390         return result;
391     }
392 }
393 
394 impl phy::RxToken for VirtioNetToken {
395     fn consume<R, F>(self, f: F) -> R
396     where
397         F: FnOnce(&mut [u8]) -> R,
398     {
399         // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。
400         let mut rx_buf = self.rx_buffer.unwrap();
401         let result = f(rx_buf.packet_mut());
402         self.driver
403             .inner
404             .lock()
405             .recycle_rx_buffer(rx_buf)
406             .expect("virtio_net recv failed");
407         result
408     }
409 }
410 
411 /// @brief virtio-net 驱动的初始化与测试
412 pub fn virtio_net(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
413     let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
414         match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
415             Ok(net) => net,
416             Err(_) => {
417                 kerror!("VirtIONet init failed");
418                 return;
419             }
420         };
421     let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address());
422     let dev_inner = VirtIONicDeviceInner::new(driver_net);
423     let iface = VirtioInterface::new(dev_inner, dev_id);
424     kdebug!("To add virtio net: {}, mac: {}", iface.device_name(), mac);
425     virtio_device_manager()
426         .device_add(iface.clone() as Arc<dyn VirtIODevice>)
427         .expect("Add virtio net failed");
428 }
429 
430 impl NetDevice for VirtioInterface {
431     fn mac(&self) -> wire::EthernetAddress {
432         let mac: [u8; 6] = self.device_inner.inner.lock().mac_address();
433         return wire::EthernetAddress::from_bytes(&mac);
434     }
435 
436     #[inline]
437     fn nic_id(&self) -> usize {
438         return self.iface_id;
439     }
440 
441     #[inline]
442     fn name(&self) -> String {
443         return self.iface_name.clone();
444     }
445 
446     fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> {
447         if ip_addrs.len() != 1 {
448             return Err(SystemError::EINVAL);
449         }
450 
451         self.iface.lock().update_ip_addrs(|addrs| {
452             let dest = addrs.iter_mut().next();
453 
454             if let Some(dest) = dest {
455                 *dest = ip_addrs[0];
456             } else {
457                 addrs
458                     .push(ip_addrs[0])
459                     .expect("Push wire::IpCidr failed: full");
460             }
461         });
462         return Ok(());
463     }
464 
465     fn poll(&self, sockets: &mut iface::SocketSet) -> Result<(), SystemError> {
466         let timestamp: smoltcp::time::Instant = Instant::now().into();
467         let mut guard = self.iface.lock();
468         let poll_res = guard.poll(timestamp, self.device_inner.force_get_mut(), sockets);
469         // todo: notify!!!
470         // kdebug!("Virtio Interface poll:{poll_res}");
471         if poll_res {
472             return Ok(());
473         }
474         return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
475     }
476 
477     #[inline(always)]
478     fn inner_iface(&self) -> &SpinLock<iface::Interface> {
479         return &self.iface;
480     }
481     // fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
482     //     return self;
483     // }
484 }
485 
486 impl KObject for VirtioInterface {
487     fn as_any_ref(&self) -> &dyn core::any::Any {
488         self
489     }
490 
491     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
492         self.inner().kobj_common.kern_inode = inode;
493     }
494 
495     fn inode(&self) -> Option<Arc<KernFSInode>> {
496         self.inner().kobj_common.kern_inode.clone()
497     }
498 
499     fn parent(&self) -> Option<Weak<dyn KObject>> {
500         self.inner().kobj_common.parent.clone()
501     }
502 
503     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
504         self.inner().kobj_common.parent = parent;
505     }
506 
507     fn kset(&self) -> Option<Arc<KSet>> {
508         self.inner().kobj_common.kset.clone()
509     }
510 
511     fn set_kset(&self, kset: Option<Arc<KSet>>) {
512         self.inner().kobj_common.kset = kset;
513     }
514 
515     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
516         self.inner().kobj_common.kobj_type
517     }
518 
519     fn name(&self) -> String {
520         self.device_name()
521     }
522 
523     fn set_name(&self, _name: String) {
524         // do nothing
525     }
526 
527     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
528         self.locked_kobj_state.read()
529     }
530 
531     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
532         self.locked_kobj_state.write()
533     }
534 
535     fn set_kobj_state(&self, state: KObjectState) {
536         *self.locked_kobj_state.write() = state;
537     }
538 
539     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
540         self.inner().kobj_common.kobj_type = ktype;
541     }
542 }
543 
544 #[unified_init(INITCALL_POSTCORE)]
545 fn virtio_net_driver_init() -> Result<(), SystemError> {
546     let driver = VirtIONetDriver::new();
547     virtio_driver_manager()
548         .register(driver.clone() as Arc<dyn VirtIODriver>)
549         .expect("Add virtio net driver failed");
550     unsafe {
551         VIRTIO_NET_DRIVER = Some(driver);
552     }
553 
554     return Ok(());
555 }
556 
557 #[derive(Debug)]
558 #[cast_to([sync] VirtIODriver)]
559 #[cast_to([sync] Driver)]
560 struct VirtIONetDriver {
561     inner: SpinLock<InnerVirtIODriver>,
562     kobj_state: LockedKObjectState,
563 }
564 
565 impl VirtIONetDriver {
566     pub fn new() -> Arc<Self> {
567         let inner = InnerVirtIODriver {
568             driver_common: DriverCommonData::default(),
569             kobj_common: KObjectCommonData::default(),
570         };
571         Arc::new(VirtIONetDriver {
572             inner: SpinLock::new(inner),
573             kobj_state: LockedKObjectState::default(),
574         })
575     }
576 
577     fn inner(&self) -> SpinLockGuard<InnerVirtIODriver> {
578         return self.inner.lock();
579     }
580 }
581 
582 #[derive(Debug)]
583 struct InnerVirtIODriver {
584     driver_common: DriverCommonData,
585     kobj_common: KObjectCommonData,
586 }
587 
588 impl VirtIODriver for VirtIONetDriver {
589     fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
590         let iface = device
591             .clone()
592             .arc_any()
593             .downcast::<VirtioInterface>()
594             .map_err(|_| {
595                 kerror!(
596                 "VirtIONetDriver::probe() failed: device is not a VirtioInterface. Device: '{:?}'",
597                 device.name()
598             );
599                 SystemError::EINVAL
600             })?;
601 
602         // 将网卡的接口信息注册到全局的网卡接口信息表中
603         NET_DEVICES
604             .write_irqsave()
605             .insert(iface.nic_id(), iface.clone());
606 
607         virtio_irq_manager()
608             .register_device(iface.clone())
609             .expect("Register virtio net failed");
610 
611         return Ok(());
612     }
613 }
614 
615 impl Driver for VirtIONetDriver {
616     fn id_table(&self) -> Option<IdTable> {
617         Some(IdTable::new(DEVICE_NAME.to_string(), None))
618     }
619 
620     fn add_device(&self, device: Arc<dyn Device>) {
621         let iface = device
622             .arc_any()
623             .downcast::<VirtioInterface>()
624             .expect("VirtIONetDriver::add_device() failed: device is not a VirtioInterface");
625 
626         self.inner()
627             .driver_common
628             .devices
629             .push(iface as Arc<dyn Device>);
630     }
631 
632     fn delete_device(&self, device: &Arc<dyn Device>) {
633         let _iface = device
634             .clone()
635             .arc_any()
636             .downcast::<VirtioInterface>()
637             .expect("VirtIONetDriver::delete_device() failed: device is not a VirtioInterface");
638 
639         let mut guard = self.inner();
640         let index = guard
641             .driver_common
642             .devices
643             .iter()
644             .position(|dev| Arc::ptr_eq(device, dev))
645             .expect("VirtIONetDriver::delete_device() failed: device not found");
646 
647         guard.driver_common.devices.remove(index);
648     }
649 
650     fn devices(&self) -> Vec<Arc<dyn Device>> {
651         self.inner().driver_common.devices.clone()
652     }
653 
654     fn bus(&self) -> Option<Weak<dyn Bus>> {
655         Some(Arc::downgrade(&virtio_bus()) as Weak<dyn Bus>)
656     }
657 
658     fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
659         // do nothing
660     }
661 }
662 
663 impl KObject for VirtIONetDriver {
664     fn as_any_ref(&self) -> &dyn Any {
665         self
666     }
667 
668     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
669         self.inner().kobj_common.kern_inode = inode;
670     }
671 
672     fn inode(&self) -> Option<Arc<KernFSInode>> {
673         self.inner().kobj_common.kern_inode.clone()
674     }
675 
676     fn parent(&self) -> Option<Weak<dyn KObject>> {
677         self.inner().kobj_common.parent.clone()
678     }
679 
680     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
681         self.inner().kobj_common.parent = parent;
682     }
683 
684     fn kset(&self) -> Option<Arc<KSet>> {
685         self.inner().kobj_common.kset.clone()
686     }
687 
688     fn set_kset(&self, kset: Option<Arc<KSet>>) {
689         self.inner().kobj_common.kset = kset;
690     }
691 
692     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
693         self.inner().kobj_common.kobj_type
694     }
695 
696     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
697         self.inner().kobj_common.kobj_type = ktype;
698     }
699 
700     fn name(&self) -> String {
701         DEVICE_NAME.to_string()
702     }
703 
704     fn set_name(&self, _name: String) {
705         // do nothing
706     }
707 
708     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
709         self.kobj_state.read()
710     }
711 
712     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
713         self.kobj_state.write()
714     }
715 
716     fn set_kobj_state(&self, state: KObjectState) {
717         *self.kobj_state.write() = state;
718     }
719 }
720