Skip to content

Commit 3ccfd26

Browse files
authored
Merge pull request #1211 from fwsGonzo/dev
Various tweaks to use routing between different CPUs
2 parents a4cacea + 7669bb6 commit 3ccfd26

31 files changed

Lines changed: 160 additions & 124 deletions

File tree

api/fs/common.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@
2828

2929
namespace fs {
3030

31-
// Generic structure for directory entries
3231
struct Dirent;
33-
32+
struct File_system;
3433

3534
/**
3635
* @brief Type used as a building block to represent buffers
@@ -185,24 +184,23 @@ namespace fs {
185184
/** @var no_error: Always returns boolean false when used in expressions */
186185
extern error_t no_error;
187186

188-
/** Async function types **/
189-
using on_init_func = delegate<void(error_t)>;
187+
/** Async function types **/
188+
using on_init_func = delegate<void(error_t, File_system&)>;
190189
using on_ls_func = delegate<void(error_t, dirvec_t)>;
191190
using on_read_func = delegate<void(error_t, buffer_t, uint64_t)>;
192191
using on_stat_func = delegate<void(error_t, const Dirent&)>;
193192

194193

195-
struct List {
194+
struct List
195+
{
196196
error_t error;
197197
dirvec_t entries;
198198
auto begin() { return entries->begin(); }
199199
auto end() { return entries->end(); }
200200
auto cbegin() { return entries->cbegin(); }
201201
auto cend() { return entries->cend(); }
202-
203202
};
204203

205-
206-
} //< namespace fs
204+
} //< fs
207205

208206
#endif //< FS_COMMON_HPP

api/fs/disk.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace fs {
4242

4343
struct Partition;
4444
using on_parts_func = delegate<void(fs::error_t, std::vector<Partition>&)>;
45-
using on_init_func = delegate<void(fs::error_t)>;
45+
using on_init_func = delegate<void(fs::error_t, File_system&)>;
4646
using lba_t = uint32_t;
4747

4848
enum partition_t {

api/fs/filesystem.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ namespace fs {
2727
struct Dirent;
2828

2929
struct File_system {
30-
31-
/** Initialize this filesystem with LBA at @base_sector */
32-
virtual void init(uint64_t lba, uint64_t size, on_init_func on_init) = 0;
33-
3430
/** Get unique (per device type) device id for underlying device.*/
3531
virtual Device_id device_id() = 0;
3632

@@ -76,6 +72,9 @@ namespace fs {
7672
/** Returns the name of this filesystem */
7773
virtual std::string name() const = 0;
7874

75+
/** Initialize this filesystem with LBA at @base_sector */
76+
virtual void init(uint64_t lba, uint64_t size, on_init_func on_init) = 0;
77+
7978
/** Default destructor */
8079
virtual ~File_system() noexcept = default;
8180
}; //< class File_system

api/net/buffer_store.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,10 @@ namespace net
8282
std::vector<buffer_t> available_;
8383
int cpu;
8484
static bool smp_enabled_;
85+
#ifndef INCLUDEOS_SINGLE_THREADED
8586
// has strict alignment reqs, so put at end
8687
spinlock_t plock;
87-
88+
#endif
8889
BufferStore(BufferStore&) = delete;
8990
BufferStore(BufferStore&&) = delete;
9091
BufferStore& operator=(BufferStore&) = delete;

api/net/inet.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ namespace net {
100100
virtual void force_start_send_queues() = 0;
101101

102102
virtual void move_to_this_cpu() = 0;
103+
virtual int get_cpu_id() const noexcept = 0;
103104

104105
}; //< class Inet<LINKLAYER, IPV>
105106
} //< namespace net

api/net/inet4.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ namespace net {
194194

195195
void move_to_this_cpu() override;
196196

197+
int get_cpu_id() const noexcept override {
198+
return this->cpu_id;
199+
}
200+
197201
/** Return the stack on the given Nic */
198202
template <int N = 0>
199203
static auto&& stack()
@@ -248,6 +252,7 @@ namespace net {
248252

249253
std::shared_ptr<net::DHClient> dhcp_{};
250254

255+
int cpu_id;
251256
const uint16_t MTU_;
252257

253258
friend class Super_stack;

api/smp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ public:
120120
// call this to signal that tasks are queued up
121121
static void signal();
122122

123+
// trigger interrupt on specified CPU
124+
static void unicast(int cpu, uint8_t intr);
123125
// broadcast-trigger interrupt on all waiting APs
124126
static void broadcast(uint8_t intr);
125127

examples/acorn/service.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ void Service::start(const std::string&) {
7272
disk = fs::new_shared_memdisk();
7373

7474
// mount the main partition in the Master Boot Record
75-
disk->init_fs([](fs::error_t err) {
76-
75+
disk->init_fs(
76+
[](fs::error_t err, auto& fs)
77+
{
7778
if (err) panic("Could not mount filesystem, retreating...\n");
7879

7980
/** IP STACK SETUP **/
@@ -152,11 +153,12 @@ void Service::start(const std::string&) {
152153
router.use("/api/dashboard", dashboard_->router());
153154

154155
// Fallback route for angular application - serve index.html if route is not found
155-
router.on_get("/app/.*", [](auto, auto res) {
156+
router.on_get("/app/.*",
157+
[&fs](auto, auto res) {
156158
#ifdef VERBOSE_WEBSERVER
157159
printf("[@GET:/app/*] Fallback route - try to serve index.html\n");
158160
#endif
159-
disk->fs().cstat("/public/app/index.html", [res](auto err, const auto& entry) {
161+
fs.cstat("/public/app/index.html", [res](auto err, const auto& entry) {
160162
if(err) {
161163
res->send_code(http::Not_Found);
162164
} else {

src/arch/x86/smp.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,12 @@ void ::SMP::broadcast(uint8_t irq)
165165
{
166166
x86::APIC::get().bcast_ipi(IRQ_BASE + irq);
167167
}
168+
void ::SMP::unicast(int cpu, uint8_t irq)
169+
{
170+
x86::APIC::get().send_ipi(cpu, IRQ_BASE + irq);
171+
}
168172

169173
static spinlock_t __global_lock = 0;
170-
static spinlock_t __memory_lock = 0;
171174

172175
void ::SMP::global_lock() noexcept
173176
{
@@ -180,6 +183,8 @@ void ::SMP::global_unlock() noexcept
180183

181184
/// SMP variants of malloc and free ///
182185
#ifndef INCLUDEOS_SINGLE_THREADED
186+
static spinlock_t __memory_lock = 0;
187+
183188
#include <malloc.h>
184189
void* malloc(size_t size)
185190
{

src/drivers/virtionet.cpp

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,11 @@ void VirtioNet::get_config() {
4444
VirtioNet::VirtioNet(hw::PCI_Device& d)
4545
: Virtio(d),
4646
Link(Link_protocol{{this, &VirtioNet::transmit}, mac()},
47-
std::max(2048u, queue_size(0) * 2), 2048 /* half-page buffers */),
47+
std::max(256u, queue_size(0) * 2), 2048 /* half-page buffers */),
4848
packets_rx_{Statman::get().create(Stat::UINT64, device_name() + ".packets_rx").get_uint64()},
4949
packets_tx_{Statman::get().create(Stat::UINT64, device_name() + ".packets_tx").get_uint64()}
5050
{
5151
INFO("VirtioNet", "Driver initializing");
52-
static_assert(VIRTIO_HDR_OFFSET >= sizeof(virtio_net_hdr),
53-
"Must be at least larger than the driver header itself");
5452

5553
uint32_t needed_features = 0
5654
| (1 << VIRTIO_NET_F_MAC)
@@ -188,20 +186,17 @@ void VirtioNet::msix_conf_handler()
188186
}
189187
void VirtioNet::msix_recv_handler()
190188
{
191-
bool dequeued_rx = false;
189+
int dequeued_rx = 0;
192190
rx_q.disable_interrupts();
193191
// handle incoming packets as long as bufstore has available buffers
194192
while (rx_q.new_incoming())
195193
{
196194
auto res = rx_q.dequeue();
197-
auto pckt_ptr = recv_packet(res.data(), res.size());
198-
Link::receive(std::move(pckt_ptr));
195+
Link::receive( recv_packet(res.data(), res.size()) );
199196

197+
dequeued_rx++;
200198
// Requeue a new buffer
201-
if (bufstore().available() > 0)
202-
add_receive_buffer(bufstore().get_buffer());
203-
204-
dequeued_rx = true;
199+
add_receive_buffer(bufstore().get_buffer());
205200

206201
// Stat increase packets received
207202
packets_rx_++;
@@ -248,7 +243,7 @@ void VirtioNet::add_receive_buffer(uint8_t* pkt)
248243
auto* vnet = pkt + sizeof(Packet);
249244

250245
Token token1 {{vnet, sizeof(virtio_net_hdr)}, Token::IN };
251-
Token token2 {{vnet + VIRTIO_HDR_OFFSET, packet_len()}, Token::IN };
246+
Token token2 {{vnet + sizeof(virtio_net_hdr), packet_len()}, Token::IN };
252247

253248
std::array<Token, 2> tokens {{ token1, token2 }};
254249
rx_q.enqueue(tokens);
@@ -263,19 +258,25 @@ VirtioNet::recv_packet(uint8_t* data, uint16_t size)
263258
assert(bufstore().is_buffer((uint8_t*) ptr));
264259
#endif
265260

266-
new (ptr) net::Packet(frame_offset_device(), size - frame_offset_device(), frame_offset_device() + packet_len(), &bufstore());
261+
new (ptr) net::Packet(
262+
sizeof(virtio_net_hdr),
263+
size - sizeof(virtio_net_hdr),
264+
sizeof(virtio_net_hdr) + packet_len(),
265+
&bufstore());
267266

268267
return net::Packet_ptr(ptr);
269268
}
270269

271270
net::Packet_ptr
272271
VirtioNet::create_packet(int link_offset)
273272
{
274-
debug("<Virtionet> Creating packet, device offset %i (virtionet header size %i) link offset %i \n",
275-
frame_offset_device(), sizeof(virtio_net_hdr), link_offset);
276273
auto* ptr = (net::Packet*) bufstore().get_buffer();
277274

278-
new (ptr) net::Packet(frame_offset_device() + link_offset, 0, frame_offset_device() + packet_len(), &bufstore());
275+
new (ptr) net::Packet(
276+
sizeof(virtio_net_hdr) + link_offset,
277+
0,
278+
sizeof(virtio_net_hdr) + packet_len(),
279+
&bufstore());
279280

280281
return net::Packet_ptr(ptr);
281282
}
@@ -314,7 +315,8 @@ void VirtioNet::transmit(net::Packet_ptr pckt) {
314315
net::Packet_ptr tail = std::move(pckt);
315316

316317
// Transmit all we can directly
317-
while (tx_q.num_free() and tail) {
318+
while (tx_q.num_free() and tail != nullptr)
319+
{
318320
debug("%i tokens left in TX queue \n", tx_q.num_free());
319321
// next in line
320322
auto next = tail->detach_tail();
@@ -325,20 +327,22 @@ void VirtioNet::transmit(net::Packet_ptr pckt) {
325327
transmitted++;
326328
// Stat increase packets transmitted
327329
packets_tx_++;
328-
329-
if (!tail) break;
330330
}
331331

332-
// Notify virtio about new packets
333332
if (LIKELY(transmitted)) {
333+
#ifdef NO_DEFERRED_KICK
334+
tx_q.enable_interrupts();
335+
tx_q.kick();
336+
#else
334337
begin_deferred_kick();
338+
#endif
335339
}
336340

337341
// Buffer the rest
338342
if (UNLIKELY(tail)) {
339343
debug("Buffering remaining packets..\n");
340344
add_to_tx_buffer(std::move(tail));
341-
}
345+
}
342346
}
343347

344348
void VirtioNet::enqueue(net::Packet* pckt)
@@ -357,10 +361,7 @@ void VirtioNet::enqueue(net::Packet* pckt)
357361

358362
void VirtioNet::begin_deferred_kick()
359363
{
360-
#ifdef NO_DEFERRED_KICK
361-
tx_q.enable_interrupts();
362-
tx_q.kick();
363-
#else
364+
#ifndef NO_DEFERRED_KICK
364365
if (!deferred_kick) {
365366
deferred_kick = true;
366367
PER_CPU(deferred_devs).devs.push_back(this);
@@ -371,9 +372,11 @@ void VirtioNet::begin_deferred_kick()
371372
void VirtioNet::handle_deferred_devices()
372373
{
373374
#ifndef NO_DEFERRED_KICK
374-
for (auto* dev : PER_CPU(deferred_devs).devs) {
375-
// kick transmitq
375+
for (auto* dev : PER_CPU(deferred_devs).devs)
376+
if (dev->deferred_kick)
377+
{
376378
dev->deferred_kick = false;
379+
// kick transmitq
377380
dev->tx_q.enable_interrupts();
378381
dev->tx_q.kick();
379382
}

0 commit comments

Comments
 (0)