MCPcopy Create free account
hub / github.com/Simple-XX/SimpleKernel / SubmitChain

Method SubmitChain

src/device/virtio/virt_queue/split.hpp:460–513  ·  view source on GitHub ↗

* @brief 提交 Scatter-Gather 描述符链 * * 从空闲链表分配描述符,按顺序组装 readable(设备只读)和 * writable(设备可写) 缓冲区为描述符链,自动设置 NEXT 标志串联,并提交到 * Available Ring。 * * 描述符链顺序:[readable_0, ..., readable_N, writable_0, ..., writable_M] * - readable 部分:flags = kDescFNext(无 kDescFWrite) * - writable 部分:flags = kDescFNext | kDescFWrite * - 最后一个描述符清除 kDescFNext * * 调用者在调用此方法后仍需调用内存屏障 + Transport::Noti

Source from the content-addressed store, hash-verified

458 * @see 架构文档 §3 Scatter-Gather
459 */
460 [[nodiscard]] auto SubmitChain(const IoVec* readable, size_t readable_count,
461 const IoVec* writable, size_t writable_count)
462 -> Expected<uint16_t> {
463 size_t total = readable_count + writable_count;
464 if (total == 0) {
465 return std::unexpected(Error{ErrorCode::kInvalidArgument});
466 }
467 if (num_free_ < static_cast<uint16_t>(total)) {
468 return std::unexpected(Error{ErrorCode::kNoFreeDescriptors});
469 }
470
471 uint16_t head = free_head_;
472 uint16_t prev_idx = 0xFFFF;
473
474 for (size_t i = 0; i < readable_count; ++i) {
475 uint16_t idx = free_head_;
476 free_head_ = desc_[free_head_].next;
477 --num_free_;
478
479 desc_[idx].addr = readable[i].phys_addr;
480 desc_[idx].len = static_cast<uint32_t>(readable[i].len);
481 desc_[idx].flags = std::to_underlying(DescFlags::kDescFNext);
482
483 if (prev_idx != 0xFFFF) {
484 desc_[prev_idx].next = idx;
485 }
486 prev_idx = idx;
487 }
488
489 for (size_t i = 0; i < writable_count; ++i) {
490 uint16_t idx = free_head_;
491 free_head_ = desc_[free_head_].next;
492 --num_free_;
493
494 desc_[idx].addr = writable[i].phys_addr;
495 desc_[idx].len = static_cast<uint32_t>(writable[i].len);
496 desc_[idx].flags = std::to_underlying(DescFlags::kDescFNext) |
497 std::to_underlying(DescFlags::kDescFWrite);
498 if (prev_idx != 0xFFFF) {
499 desc_[prev_idx].next = idx;
500 }
501 prev_idx = idx;
502 }
503
504 desc_[prev_idx].flags =
505 desc_[prev_idx].flags & ~std::to_underlying(DescFlags::kDescFNext);
506
507 // 写屏障:确保描述符写入在 Available Ring 更新之前对设备可见
508 cpu_io::Wmb();
509
510 Submit(head);
511
512 return head;
513 }
514
515 /**
516 * @brief 释放整条描述符链

Callers 2

DoEnqueueMethod · 0.80

Calls 1

WmbFunction · 0.85

Tested by

no test coverage detected