Skip to content

Commit e5a130d

Browse files
Implement configurable queue capacity and data size for block system
Signed-off-by: Ivan-Velickovic <i.velickovic@unsw.edu.au>
1 parent 3da4f78 commit e5a130d

File tree

3 files changed

+121
-55
lines changed

3 files changed

+121
-55
lines changed

src/c/c.zig

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -537,25 +537,35 @@ export fn sdfgen_sddf_i2c_serialise_config(system: *align(8) anyopaque, output_d
537537
export fn sdfgen_sddf_blk(c_sdf: *align(8) anyopaque, c_device: *align(8) anyopaque, driver: *align(8) anyopaque, virt: *align(8) anyopaque) ?*anyopaque {
538538
const sdf: *SystemDescription = @ptrCast(c_sdf);
539539
const device: *dtb.Node = @ptrCast(c_device);
540-
const block = allocator.create(sddf.Blk) catch @panic("OOM");
541-
block.* = sddf.Blk.init(allocator, sdf, device, @ptrCast(driver), @ptrCast(virt), .{}) catch |e| {
540+
const blk = allocator.create(sddf.Blk) catch @panic("OOM");
541+
blk.* = sddf.Blk.init(allocator, sdf, device, @ptrCast(driver), @ptrCast(virt), .{}) catch |e| {
542542
log.err("failed to initialiase blk system for device '{s}': {any}", .{ device.name, e });
543-
allocator.destroy(block);
543+
allocator.destroy(blk);
544544
return null;
545545
};
546546

547-
return block;
547+
return blk;
548548
}
549549

550550
export fn sdfgen_sddf_blk_destroy(system: *align(8) anyopaque) void {
551-
const block: *sddf.Blk = @ptrCast(system);
552-
block.deinit();
553-
allocator.destroy(block);
551+
const blk: *sddf.Blk = @ptrCast(system);
552+
blk.deinit();
553+
allocator.destroy(blk);
554554
}
555555

556-
export fn sdfgen_sddf_blk_add_client(system: *align(8) anyopaque, client: *align(8) anyopaque, partition: u32) bindings.sdfgen_sddf_status_t {
557-
const block: *sddf.Blk = @ptrCast(system);
558-
block.addClient(@ptrCast(client), .{ .partition = partition }) catch |e| {
556+
export fn sdfgen_sddf_blk_add_client(system: *align(8) anyopaque, client: *align(8) anyopaque, partition: u32, queue_capacity: [*c]u16, data_size: [*c]u32) bindings.sdfgen_sddf_status_t {
557+
var options: sddf.Blk.ClientOptions = .{
558+
.partition = partition,
559+
};
560+
if (queue_capacity != null) {
561+
options.queue_capacity = queue_capacity.*;
562+
}
563+
if (data_size != null) {
564+
options.data_size = data_size.*;
565+
}
566+
567+
const blk: *sddf.Blk = @ptrCast(system);
568+
blk.addClient(@ptrCast(client), options) catch |e| {
559569
switch (e) {
560570
sddf.Blk.Error.DuplicateClient => return 1,
561571
sddf.Blk.Error.InvalidClient => return 2,
@@ -568,15 +578,15 @@ export fn sdfgen_sddf_blk_add_client(system: *align(8) anyopaque, client: *align
568578
}
569579

570580
export fn sdfgen_sddf_blk_connect(system: *align(8) anyopaque) bool {
571-
const block: *sddf.Blk = @ptrCast(system);
572-
block.connect() catch return false;
581+
const blk: *sddf.Blk = @ptrCast(system);
582+
blk.connect() catch return false;
573583

574584
return true;
575585
}
576586

577587
export fn sdfgen_sddf_blk_serialise_config(system: *align(8) anyopaque, output_dir: [*c]u8) bool {
578-
const block: *sddf.Blk = @ptrCast(system);
579-
block.serialiseConfig(std.mem.span(output_dir)) catch return false;
588+
const blk: *sddf.Blk = @ptrCast(system);
589+
blk.serialiseConfig(std.mem.span(output_dir)) catch return false;
580590

581591
return true;
582592
}

src/python/module.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import ctypes
33
import importlib.util
44
from ctypes import (
5-
cast, c_void_p, c_char_p, c_int8, c_uint8, c_uint32, c_uint64, c_bool, POINTER, byref, pointer
5+
cast, c_void_p, c_char_p, c_int8, c_uint8, c_uint16, c_uint32, c_uint64, c_bool, POINTER, byref, pointer
66
)
77
from typing import Optional, List, Tuple
88
from enum import IntEnum
@@ -156,7 +156,7 @@ class SddfStatus(IntEnum):
156156
libsdfgen.sdfgen_sddf_blk_destroy.argtypes = [c_void_p]
157157

158158
libsdfgen.sdfgen_sddf_blk_add_client.restype = c_uint32
159-
libsdfgen.sdfgen_sddf_blk_add_client.argtypes = [c_void_p, c_void_p, c_uint32]
159+
libsdfgen.sdfgen_sddf_blk_add_client.argtypes = [c_void_p, c_void_p, c_uint32, POINTER(c_uint16), POINTER(c_uint32)]
160160

161161
libsdfgen.sdfgen_sddf_blk_connect.restype = c_bool
162162
libsdfgen.sdfgen_sddf_blk_connect.argtypes = [c_void_p]
@@ -302,6 +302,17 @@ def ffi_uint8_ptr(n: Optional[int]):
302302
return pointer(c_uint8(n))
303303

304304

305+
def ffi_uint16_ptr(n: Optional[int]):
306+
"""
307+
Convert an int value to a uint16_t pointer for FFI.
308+
If 'n' is None then we return None (which acts as a null pointer)
309+
"""
310+
if n is None:
311+
return None
312+
313+
return pointer(c_uint16(n))
314+
315+
305316
def ffi_uint32_ptr(n: Optional[int]):
306317
"""
307318
Convert an int value to a uint32_t pointer for FFI.
@@ -798,8 +809,21 @@ def __init__(
798809
if self._obj is None:
799810
raise Exception("failed to create blk system")
800811

801-
def add_client(self, client: SystemDescription.ProtectionDomain, *, partition: int):
802-
ret = libsdfgen.sdfgen_sddf_blk_add_client(self._obj, client._obj, partition)
812+
def add_client(
813+
self,
814+
client: SystemDescription.ProtectionDomain,
815+
*,
816+
partition: int,
817+
queue_capacity: Optional[int] = None,
818+
data_size: Optional[int] = None
819+
):
820+
ret = libsdfgen.sdfgen_sddf_blk_add_client(
821+
self._obj,
822+
client._obj,
823+
partition,
824+
ffi_uint16_ptr(queue_capacity),
825+
ffi_uint32_ptr(data_size)
826+
)
803827
if ret == SddfStatus.OK:
804828
return
805829
elif ret == SddfStatus.DUPLICATE_CLIENT:

src/sddf.zig

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -626,23 +626,28 @@ pub const I2c = struct {
626626
}
627627
};
628628

629+
// TODO: probably make all queue_capacity/num_buffers u32
629630
pub const Blk = struct {
630631
allocator: Allocator,
631632
sdf: *SystemDescription,
632633
driver: *Pd,
633634
device: *dtb.Node,
634635
device_res: ConfigResources.Device,
635636
virt: *Pd,
636-
clients: std.ArrayList(*Pd),
637-
client_partitions: std.ArrayList(u32),
637+
clients: std.ArrayList(Client),
638638
connected: bool = false,
639639
serialised: bool = false,
640-
// TODO: make this configurable per component
641-
queue_mr_size: usize = 2 * 1024 * 1024,
642-
// TODO: make configurable
643-
queue_capacity: u16 = 128,
640+
// Only needed for initialisation to read partition table
641+
driver_data_size: u32 = 4096,
644642
config: Blk.Config,
645643

644+
const Client = struct {
645+
pd: *Pd,
646+
partition: u32,
647+
queue_capacity: u16,
648+
data_size: u32,
649+
};
650+
646651
const Config = struct {
647652
driver: ConfigResources.Blk.Driver = undefined,
648653
virt_driver: ConfigResources.Blk.Virt.Driver = undefined,
@@ -666,8 +671,7 @@ pub const Blk = struct {
666671
return .{
667672
.allocator = allocator,
668673
.sdf = sdf,
669-
.clients = std.ArrayList(*Pd).init(allocator),
670-
.client_partitions = std.ArrayList(u32).init(allocator),
674+
.clients = std.ArrayList(Client).init(allocator),
671675
.driver = driver,
672676
.device = device,
673677
.device_res = std.mem.zeroInit(ConfigResources.Device, .{}),
@@ -681,19 +685,24 @@ pub const Blk = struct {
681685

682686
pub fn deinit(system: *Blk) void {
683687
system.clients.deinit();
684-
system.client_partitions.deinit();
685688
system.config.virt_clients.deinit();
686689
system.config.clients.deinit();
687690
}
688691

692+
// TODO: need to do more error checking on data size and queue capacity.
689693
pub const ClientOptions = struct {
694+
// Zero-index of device partition to use.
690695
partition: u32,
696+
// Maximum possible entries in a single queue.
697+
queue_capacity: u16 = 128,
698+
// Default to 2MB.
699+
data_size: u32 = 2 * 1024 * 1024,
691700
};
692701

693702
pub fn addClient(system: *Blk, client: *Pd, options: ClientOptions) Error!void {
694703
// Check that the client does not already exist
695704
for (system.clients.items) |existing_client| {
696-
if (std.mem.eql(u8, existing_client.name, client.name)) {
705+
if (std.mem.eql(u8, existing_client.pd.name, client.name)) {
697706
return Error.DuplicateClient;
698707
}
699708
}
@@ -705,15 +714,36 @@ pub const Blk = struct {
705714
log.err("invalid blk client, same name as virt '{s}", .{client.name});
706715
return Error.InvalidClient;
707716
}
708-
system.clients.append(client) catch @panic("Could not add client to Blk");
709-
system.client_partitions.append(options.partition) catch @panic("Could not add client to Blk");
717+
system.clients.append(.{
718+
.pd = client,
719+
.partition = options.partition,
720+
.queue_capacity = options.queue_capacity,
721+
.data_size = options.data_size,
722+
}) catch @panic("Could not add client to Blk");
723+
}
724+
725+
fn driverQueueCapacity(system: *Blk) u16 {
726+
var total_capacity: u16 = 0;
727+
for (system.clients.items) |client| {
728+
total_capacity += client.queue_capacity;
729+
}
730+
731+
return total_capacity;
732+
}
733+
734+
fn driverQueueMrSize(system: *Blk) u32 {
735+
// TODO: 128 bytes is enough for each queue entry, but need to be
736+
// better about how this is determined.
737+
return @as(u32, driverQueueCapacity(system)) * @as(u32, 128);
710738
}
711739

712740
pub fn connectDriver(system: *Blk) void {
713741
const sdf = system.sdf;
714742
const allocator = system.allocator;
715743
const driver = system.driver;
716744
const virt = system.virt;
745+
const queue_mr_size = driverQueueMrSize(system);
746+
const queue_capacity = driverQueueCapacity(system);
717747

718748
const mr_storage_info = Mr.create(allocator, "blk_driver_storage_info", STORAGE_INFO_REGION_SIZE, .{});
719749
const map_storage_info_driver = Map.create(mr_storage_info, system.driver.getMapVaddr(&mr_storage_info), .rw, .{});
@@ -723,23 +753,23 @@ pub const Blk = struct {
723753
driver.addMap(map_storage_info_driver);
724754
virt.addMap(map_storage_info_virt);
725755

726-
const mr_req = Mr.create(allocator, "blk_driver_request", system.queue_mr_size, .{});
756+
const mr_req = Mr.create(allocator, "blk_driver_request", queue_mr_size, .{});
727757
const map_req_driver = Map.create(mr_req, driver.getMapVaddr(&mr_req), .rw, .{});
728758
const map_req_virt = Map.create(mr_req, virt.getMapVaddr(&mr_req), .rw, .{});
729759

730760
sdf.addMemoryRegion(mr_req);
731761
driver.addMap(map_req_driver);
732762
virt.addMap(map_req_virt);
733763

734-
const mr_resp = Mr.create(allocator, "blk_driver_response", system.queue_mr_size, .{});
764+
const mr_resp = Mr.create(allocator, "blk_driver_response", queue_mr_size, .{});
735765
const map_resp_driver = Map.create(mr_resp, driver.getMapVaddr(&mr_resp), .rw, .{});
736766
const map_resp_virt = Map.create(mr_resp, virt.getMapVaddr(&mr_resp), .rw, .{});
737767

738768
sdf.addMemoryRegion(mr_resp);
739769
driver.addMap(map_resp_driver);
740770
virt.addMap(map_resp_virt);
741771

742-
const mr_data = Mr.physical(allocator, sdf, "blk_driver_data", system.queue_mr_size, .{});
772+
const mr_data = Mr.physical(allocator, sdf, "blk_driver_data", system.driver_data_size, .{});
743773
const map_data_virt = Map.create(mr_data, virt.getMapVaddr(&mr_data), .rw, .{});
744774

745775
sdf.addMemoryRegion(mr_data);
@@ -753,7 +783,7 @@ pub const Blk = struct {
753783
.storage_info = .createFromMap(map_storage_info_driver),
754784
.req_queue = .createFromMap(map_req_driver),
755785
.resp_queue = .createFromMap(map_resp_driver),
756-
.num_buffers = system.queue_capacity,
786+
.num_buffers = queue_capacity,
757787
.id = ch.pd_b_id,
758788
},
759789
};
@@ -763,70 +793,72 @@ pub const Blk = struct {
763793
.storage_info = .createFromMap(map_storage_info_virt),
764794
.req_queue = .createFromMap(map_req_virt),
765795
.resp_queue = .createFromMap(map_resp_virt),
766-
.num_buffers = system.queue_capacity,
796+
.num_buffers = queue_capacity,
767797
.id = ch.pd_a_id,
768798
},
769799
.data = .createFromMap(map_data_virt),
770800
};
771801
}
772802

773-
pub fn connectClient(system: *Blk, client: *Pd, i: usize) void {
803+
pub fn connectClient(system: *Blk, client: *Client, i: usize) void {
774804
const sdf = system.sdf;
775805
const allocator = system.allocator;
776-
const queue_mr_size = system.queue_mr_size;
806+
const queue_mr_size: u32 = @as(u32, client.queue_capacity) * @as(u32, 128);
807+
const data_mr_size = client.data_size;
808+
const client_pd = client.pd;
777809

778-
const mr_storage_info = Mr.create(allocator, fmt(allocator, "blk_client_{s}_storage_info", .{client.name}), STORAGE_INFO_REGION_SIZE, .{});
810+
const mr_storage_info = Mr.create(allocator, fmt(allocator, "blk_client_{s}_storage_info", .{client_pd.name}), STORAGE_INFO_REGION_SIZE, .{});
779811
const map_storage_info_virt = Map.create(mr_storage_info, system.virt.getMapVaddr(&mr_storage_info), .rw, .{});
780-
const map_storage_info_client = Map.create(mr_storage_info, client.getMapVaddr(&mr_storage_info), .r, .{});
812+
const map_storage_info_client = Map.create(mr_storage_info, client_pd.getMapVaddr(&mr_storage_info), .r, .{});
781813

782814
system.sdf.addMemoryRegion(mr_storage_info);
783815
system.virt.addMap(map_storage_info_virt);
784-
client.addMap(map_storage_info_client);
816+
client_pd.addMap(map_storage_info_client);
785817

786-
const mr_req = Mr.create(allocator, fmt(allocator, "blk_client_{s}_request", .{client.name}), queue_mr_size, .{});
818+
const mr_req = Mr.create(allocator, fmt(allocator, "blk_client_{s}_request", .{client_pd.name}), queue_mr_size, .{});
787819
const map_req_virt = Map.create(mr_req, system.virt.getMapVaddr(&mr_req), .rw, .{});
788-
const map_req_client = Map.create(mr_req, client.getMapVaddr(&mr_req), .rw, .{});
820+
const map_req_client = Map.create(mr_req, client_pd.getMapVaddr(&mr_req), .rw, .{});
789821

790822
system.sdf.addMemoryRegion(mr_req);
791823
system.virt.addMap(map_req_virt);
792-
client.addMap(map_req_client);
824+
client_pd.addMap(map_req_client);
793825

794-
const mr_resp = Mr.create(allocator, fmt(allocator, "blk_client_{s}_response", .{client.name}), queue_mr_size, .{});
826+
const mr_resp = Mr.create(allocator, fmt(allocator, "blk_client_{s}_response", .{client_pd.name}), queue_mr_size, .{});
795827
const map_resp_virt = Map.create(mr_resp, system.virt.getMapVaddr(&mr_resp), .rw, .{});
796-
const map_resp_client = Map.create(mr_resp, client.getMapVaddr(&mr_resp), .rw, .{});
828+
const map_resp_client = Map.create(mr_resp, client_pd.getMapVaddr(&mr_resp), .rw, .{});
797829

798830
system.sdf.addMemoryRegion(mr_resp);
799831
system.virt.addMap(map_resp_virt);
800-
client.addMap(map_resp_client);
832+
client_pd.addMap(map_resp_client);
801833

802-
const mr_data = Mr.physical(allocator, sdf, fmt(allocator, "blk_client_{s}_data", .{client.name}), queue_mr_size, .{});
834+
const mr_data = Mr.physical(allocator, sdf, fmt(allocator, "blk_client_{s}_data", .{client_pd.name}), data_mr_size, .{});
803835
const map_data_virt = Map.create(mr_data, system.virt.getMapVaddr(&mr_data), .rw, .{});
804-
const map_data_client = Map.create(mr_data, client.getMapVaddr(&mr_data), .rw, .{});
836+
const map_data_client = Map.create(mr_data, client_pd.getMapVaddr(&mr_data), .rw, .{});
805837

806838
system.sdf.addMemoryRegion(mr_data);
807839
system.virt.addMap(map_data_virt);
808-
client.addMap(map_data_client);
840+
client_pd.addMap(map_data_client);
809841

810-
const ch = Channel.create(system.virt, client, .{}) catch unreachable;
842+
const ch = Channel.create(system.virt, client_pd, .{}) catch unreachable;
811843
system.sdf.addChannel(ch);
812844

813845
system.config.virt_clients.append(.{
814846
.conn = .{
815847
.storage_info = .createFromMap(map_storage_info_virt),
816848
.req_queue = .createFromMap(map_req_virt),
817849
.resp_queue = .createFromMap(map_resp_virt),
818-
.num_buffers = system.queue_capacity,
850+
.num_buffers = client.queue_capacity,
819851
.id = ch.pd_a_id,
820852
},
821853
.data = .createFromMap(map_data_virt),
822-
.partition = system.client_partitions.items[i],
854+
.partition = system.clients.items[i].partition,
823855
}) catch @panic("could not add virt client config");
824856

825857
system.config.clients.append(.{ .virt = .{
826858
.storage_info = .createFromMap(map_storage_info_client),
827859
.req_queue = .createFromMap(map_req_client),
828860
.resp_queue = .createFromMap(map_resp_client),
829-
.num_buffers = system.queue_capacity,
861+
.num_buffers = client.queue_capacity,
830862
.id = ch.pd_b_id,
831863
}, .data = .createFromMap(map_data_client) }) catch @panic("could not add client config");
832864
}
@@ -839,7 +871,7 @@ pub const Blk = struct {
839871
// 2. Connect the driver to the virtualiser
840872
system.connectDriver();
841873
// 3. Connect each client to the virtualiser
842-
for (system.clients.items, 0..) |client, i| {
874+
for (system.clients.items, 0..) |*client, i| {
843875
system.connectClient(client, i);
844876
}
845877

@@ -858,7 +890,7 @@ pub const Blk = struct {
858890
try data.serialize(allocator, virt_config, prefix, "blk_virt");
859891

860892
for (system.config.clients.items, 0..) |config, i| {
861-
const client_config = fmt(allocator, "blk_client_{s}", .{system.clients.items[i].name});
893+
const client_config = fmt(allocator, "blk_client_{s}", .{system.clients.items[i].pd.name});
862894
try data.serialize(allocator, config, prefix, client_config);
863895
}
864896

0 commit comments

Comments
 (0)