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 irq(&self) -> Option<IrqNumber> { 211 None 212 } 213 214 fn dev_id(&self) -> &Arc<DeviceId> { 215 return &self.dev_id; 216 } 217 fn set_virtio_device_index(&self, index: VirtIODeviceIndex) { 218 self.inner().virtio_index = Some(index); 219 } 220 221 fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> { 222 return self.inner().virtio_index; 223 } 224 225 fn set_device_name(&self, name: String) { 226 self.inner().name = Some(name); 227 } 228 229 fn device_name(&self) -> String { 230 self.inner() 231 .name 232 .clone() 233 .unwrap_or_else(|| "virtio_net".to_string()) 234 } 235 236 fn device_type_id(&self) -> u32 { 237 virtio_drivers::transport::DeviceType::Network as u32 238 } 239 240 fn vendor(&self) -> u32 { 241 VIRTIO_VENDOR_ID.into() 242 } 243 } 244 245 impl Drop for VirtioInterface { 246 fn drop(&mut self) { 247 // 从全局的网卡接口信息表中删除这个网卡的接口信息 248 NET_DEVICES.write_irqsave().remove(&self.iface_id); 249 } 250 } 251 252 impl Device for VirtioInterface { 253 fn dev_type(&self) -> DeviceType { 254 DeviceType::Net 255 } 256 257 fn id_table(&self) -> IdTable { 258 IdTable::new(DEVICE_NAME.to_string(), None) 259 } 260 261 fn bus(&self) -> Option<Weak<dyn Bus>> { 262 self.inner().device_common.bus.clone() 263 } 264 265 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 266 self.inner().device_common.bus = bus; 267 } 268 269 fn class(&self) -> Option<Arc<dyn Class>> { 270 let mut guard = self.inner(); 271 let r = guard.device_common.class.clone()?.upgrade(); 272 if r.is_none() { 273 guard.device_common.class = None; 274 } 275 276 return r; 277 } 278 279 fn set_class(&self, class: Option<Weak<dyn Class>>) { 280 self.inner().device_common.class = class; 281 } 282 283 fn driver(&self) -> Option<Arc<dyn Driver>> { 284 let r = self.inner().device_common.driver.clone()?.upgrade(); 285 if r.is_none() { 286 self.inner().device_common.driver = None; 287 } 288 289 return r; 290 } 291 292 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 293 self.inner().device_common.driver = driver; 294 } 295 296 fn is_dead(&self) -> bool { 297 false 298 } 299 300 fn can_match(&self) -> bool { 301 self.inner().device_common.can_match 302 } 303 304 fn set_can_match(&self, can_match: bool) { 305 self.inner().device_common.can_match = can_match; 306 } 307 308 fn state_synced(&self) -> bool { 309 true 310 } 311 } 312 313 impl VirtIONicDeviceInner { 314 pub fn new(driver_net: VirtIONet<HalImpl, VirtIOTransport, 2>) -> Self { 315 let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet( 316 wire::EthernetAddress(driver_net.mac_address()), 317 )); 318 319 iface_config.random_seed = rand() as u64; 320 321 let inner = Arc::new(SpinLock::new(VirtIoNetImpl::new(driver_net))); 322 let result = VirtIONicDeviceInner { inner }; 323 return result; 324 } 325 } 326 327 pub struct VirtioNetToken { 328 driver: VirtIONicDeviceInner, 329 rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 330 } 331 332 impl VirtioNetToken { 333 pub fn new( 334 driver: VirtIONicDeviceInner, 335 rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 336 ) -> Self { 337 return Self { driver, rx_buffer }; 338 } 339 } 340 341 impl phy::Device for VirtIONicDeviceInner { 342 type RxToken<'a> = VirtioNetToken where Self: 'a; 343 type TxToken<'a> = VirtioNetToken where Self: 'a; 344 345 fn receive( 346 &mut self, 347 _timestamp: smoltcp::time::Instant, 348 ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 349 match self.inner.lock().receive() { 350 Ok(buf) => Some(( 351 VirtioNetToken::new(self.clone(), Some(buf)), 352 VirtioNetToken::new(self.clone(), None), 353 )), 354 Err(virtio_drivers::Error::NotReady) => None, 355 Err(err) => panic!("VirtIO receive failed: {}", err), 356 } 357 } 358 359 fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> { 360 // kdebug!("VirtioNet: transmit"); 361 if self.inner.lock_irqsave().can_send() { 362 // kdebug!("VirtioNet: can send"); 363 return Some(VirtioNetToken::new(self.clone(), None)); 364 } else { 365 // kdebug!("VirtioNet: can not send"); 366 return None; 367 } 368 } 369 370 fn capabilities(&self) -> phy::DeviceCapabilities { 371 let mut caps = phy::DeviceCapabilities::default(); 372 // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。 373 caps.max_transmission_unit = 2000; 374 /* 375 Maximum burst size, in terms of MTU. 376 The network device is unable to send or receive bursts large than the value returned by this function. 377 If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated. 378 */ 379 caps.max_burst_size = Some(1); 380 return caps; 381 } 382 } 383 384 impl phy::TxToken for VirtioNetToken { 385 fn consume<R, F>(self, len: usize, f: F) -> R 386 where 387 F: FnOnce(&mut [u8]) -> R, 388 { 389 // // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 390 let mut driver_net = self.driver.inner.lock(); 391 let mut tx_buf = driver_net.new_tx_buffer(len); 392 let result = f(tx_buf.packet_mut()); 393 driver_net.send(tx_buf).expect("virtio_net send failed"); 394 return result; 395 } 396 } 397 398 impl phy::RxToken for VirtioNetToken { 399 fn consume<R, F>(self, f: F) -> R 400 where 401 F: FnOnce(&mut [u8]) -> R, 402 { 403 // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 404 let mut rx_buf = self.rx_buffer.unwrap(); 405 let result = f(rx_buf.packet_mut()); 406 self.driver 407 .inner 408 .lock() 409 .recycle_rx_buffer(rx_buf) 410 .expect("virtio_net recv failed"); 411 result 412 } 413 } 414 415 /// @brief virtio-net 驱动的初始化与测试 416 pub fn virtio_net(transport: VirtIOTransport, dev_id: Arc<DeviceId>) { 417 let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> = 418 match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) { 419 Ok(net) => net, 420 Err(_) => { 421 kerror!("VirtIONet init failed"); 422 return; 423 } 424 }; 425 let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address()); 426 let dev_inner = VirtIONicDeviceInner::new(driver_net); 427 let iface = VirtioInterface::new(dev_inner, dev_id); 428 kdebug!("To add virtio net: {}, mac: {}", iface.device_name(), mac); 429 virtio_device_manager() 430 .device_add(iface.clone() as Arc<dyn VirtIODevice>) 431 .expect("Add virtio net failed"); 432 } 433 434 impl NetDevice for VirtioInterface { 435 fn mac(&self) -> wire::EthernetAddress { 436 let mac: [u8; 6] = self.device_inner.inner.lock().mac_address(); 437 return wire::EthernetAddress::from_bytes(&mac); 438 } 439 440 #[inline] 441 fn nic_id(&self) -> usize { 442 return self.iface_id; 443 } 444 445 #[inline] 446 fn name(&self) -> String { 447 return self.iface_name.clone(); 448 } 449 450 fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> { 451 if ip_addrs.len() != 1 { 452 return Err(SystemError::EINVAL); 453 } 454 455 self.iface.lock().update_ip_addrs(|addrs| { 456 let dest = addrs.iter_mut().next(); 457 458 if let Some(dest) = dest { 459 *dest = ip_addrs[0]; 460 } else { 461 addrs 462 .push(ip_addrs[0]) 463 .expect("Push wire::IpCidr failed: full"); 464 } 465 }); 466 return Ok(()); 467 } 468 469 fn poll(&self, sockets: &mut iface::SocketSet) -> Result<(), SystemError> { 470 let timestamp: smoltcp::time::Instant = Instant::now().into(); 471 let mut guard = self.iface.lock(); 472 let poll_res = guard.poll(timestamp, self.device_inner.force_get_mut(), sockets); 473 // todo: notify!!! 474 // kdebug!("Virtio Interface poll:{poll_res}"); 475 if poll_res { 476 return Ok(()); 477 } 478 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 479 } 480 481 #[inline(always)] 482 fn inner_iface(&self) -> &SpinLock<iface::Interface> { 483 return &self.iface; 484 } 485 // fn as_any_ref(&'static self) -> &'static dyn core::any::Any { 486 // return self; 487 // } 488 } 489 490 impl KObject for VirtioInterface { 491 fn as_any_ref(&self) -> &dyn core::any::Any { 492 self 493 } 494 495 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 496 self.inner().kobj_common.kern_inode = inode; 497 } 498 499 fn inode(&self) -> Option<Arc<KernFSInode>> { 500 self.inner().kobj_common.kern_inode.clone() 501 } 502 503 fn parent(&self) -> Option<Weak<dyn KObject>> { 504 self.inner().kobj_common.parent.clone() 505 } 506 507 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 508 self.inner().kobj_common.parent = parent; 509 } 510 511 fn kset(&self) -> Option<Arc<KSet>> { 512 self.inner().kobj_common.kset.clone() 513 } 514 515 fn set_kset(&self, kset: Option<Arc<KSet>>) { 516 self.inner().kobj_common.kset = kset; 517 } 518 519 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 520 self.inner().kobj_common.kobj_type 521 } 522 523 fn name(&self) -> String { 524 self.device_name() 525 } 526 527 fn set_name(&self, _name: String) { 528 // do nothing 529 } 530 531 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 532 self.locked_kobj_state.read() 533 } 534 535 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 536 self.locked_kobj_state.write() 537 } 538 539 fn set_kobj_state(&self, state: KObjectState) { 540 *self.locked_kobj_state.write() = state; 541 } 542 543 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 544 self.inner().kobj_common.kobj_type = ktype; 545 } 546 } 547 548 #[unified_init(INITCALL_POSTCORE)] 549 fn virtio_net_driver_init() -> Result<(), SystemError> { 550 let driver = VirtIONetDriver::new(); 551 virtio_driver_manager() 552 .register(driver.clone() as Arc<dyn VirtIODriver>) 553 .expect("Add virtio net driver failed"); 554 unsafe { 555 VIRTIO_NET_DRIVER = Some(driver); 556 } 557 558 return Ok(()); 559 } 560 561 #[derive(Debug)] 562 #[cast_to([sync] VirtIODriver)] 563 #[cast_to([sync] Driver)] 564 struct VirtIONetDriver { 565 inner: SpinLock<InnerVirtIODriver>, 566 kobj_state: LockedKObjectState, 567 } 568 569 impl VirtIONetDriver { 570 pub fn new() -> Arc<Self> { 571 let inner = InnerVirtIODriver { 572 driver_common: DriverCommonData::default(), 573 kobj_common: KObjectCommonData::default(), 574 }; 575 Arc::new(VirtIONetDriver { 576 inner: SpinLock::new(inner), 577 kobj_state: LockedKObjectState::default(), 578 }) 579 } 580 581 fn inner(&self) -> SpinLockGuard<InnerVirtIODriver> { 582 return self.inner.lock(); 583 } 584 } 585 586 #[derive(Debug)] 587 struct InnerVirtIODriver { 588 driver_common: DriverCommonData, 589 kobj_common: KObjectCommonData, 590 } 591 592 impl VirtIODriver for VirtIONetDriver { 593 fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> { 594 let iface = device 595 .clone() 596 .arc_any() 597 .downcast::<VirtioInterface>() 598 .map_err(|_| { 599 kerror!( 600 "VirtIONetDriver::probe() failed: device is not a VirtioInterface. Device: '{:?}'", 601 device.name() 602 ); 603 SystemError::EINVAL 604 })?; 605 606 // 将网卡的接口信息注册到全局的网卡接口信息表中 607 NET_DEVICES 608 .write_irqsave() 609 .insert(iface.nic_id(), iface.clone()); 610 611 virtio_irq_manager() 612 .register_device(iface.clone()) 613 .expect("Register virtio net failed"); 614 615 return Ok(()); 616 } 617 } 618 619 impl Driver for VirtIONetDriver { 620 fn id_table(&self) -> Option<IdTable> { 621 Some(IdTable::new(DEVICE_NAME.to_string(), None)) 622 } 623 624 fn add_device(&self, device: Arc<dyn Device>) { 625 let iface = device 626 .arc_any() 627 .downcast::<VirtioInterface>() 628 .expect("VirtIONetDriver::add_device() failed: device is not a VirtioInterface"); 629 630 self.inner() 631 .driver_common 632 .devices 633 .push(iface as Arc<dyn Device>); 634 } 635 636 fn delete_device(&self, device: &Arc<dyn Device>) { 637 let _iface = device 638 .clone() 639 .arc_any() 640 .downcast::<VirtioInterface>() 641 .expect("VirtIONetDriver::delete_device() failed: device is not a VirtioInterface"); 642 643 let mut guard = self.inner(); 644 let index = guard 645 .driver_common 646 .devices 647 .iter() 648 .position(|dev| Arc::ptr_eq(device, dev)) 649 .expect("VirtIONetDriver::delete_device() failed: device not found"); 650 651 guard.driver_common.devices.remove(index); 652 } 653 654 fn devices(&self) -> Vec<Arc<dyn Device>> { 655 self.inner().driver_common.devices.clone() 656 } 657 658 fn bus(&self) -> Option<Weak<dyn Bus>> { 659 Some(Arc::downgrade(&virtio_bus()) as Weak<dyn Bus>) 660 } 661 662 fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) { 663 // do nothing 664 } 665 } 666 667 impl KObject for VirtIONetDriver { 668 fn as_any_ref(&self) -> &dyn Any { 669 self 670 } 671 672 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 673 self.inner().kobj_common.kern_inode = inode; 674 } 675 676 fn inode(&self) -> Option<Arc<KernFSInode>> { 677 self.inner().kobj_common.kern_inode.clone() 678 } 679 680 fn parent(&self) -> Option<Weak<dyn KObject>> { 681 self.inner().kobj_common.parent.clone() 682 } 683 684 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 685 self.inner().kobj_common.parent = parent; 686 } 687 688 fn kset(&self) -> Option<Arc<KSet>> { 689 self.inner().kobj_common.kset.clone() 690 } 691 692 fn set_kset(&self, kset: Option<Arc<KSet>>) { 693 self.inner().kobj_common.kset = kset; 694 } 695 696 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 697 self.inner().kobj_common.kobj_type 698 } 699 700 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 701 self.inner().kobj_common.kobj_type = ktype; 702 } 703 704 fn name(&self) -> String { 705 DEVICE_NAME.to_string() 706 } 707 708 fn set_name(&self, _name: String) { 709 // do nothing 710 } 711 712 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 713 self.kobj_state.read() 714 } 715 716 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 717 self.kobj_state.write() 718 } 719 720 fn set_kobj_state(&self, state: KObjectState) { 721 *self.kobj_state.write() = state; 722 } 723 } 724