Skip to content

Commit

Permalink
Employ an approach that avoids copying contents of received network p…
Browse files Browse the repository at this point in the history
…ackets.
  • Loading branch information
pgj committed Aug 23, 2012
1 parent ecb4a60 commit fb0077a
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 151 deletions.
89 changes: 10 additions & 79 deletions packages/mirage-platform/lib/netif.ml
Expand Up @@ -28,88 +28,19 @@
open Lwt open Lwt
open Printf open Printf


type sring = {
buf: Io_page.t;
header_size: int;
slot_size: int;
nr_ents: int;
}

let sring_hdr_size = 64 (* sizeof(struct sring_hdr) *)

cstruct sring_hdr {
uint16_t sr_cur;
uint16_t sr_avail;
uint16_t sr_size;
uint16_t sr_slotsize;
uint8_t sr_pad[56]
} as little_endian

let sslot_size = 2 (* sizeof(struct sslot) *)

cstruct sslot {
uint16_t ss_len
} as little_endian

let nr_ents sring = sring.nr_ents

let avail_packet sring =
let hdr = Io_page.sub sring.buf 0 sring.header_size in
get_sring_hdr_sr_avail hdr

let slot sring i =
let idx = i land (sring.nr_ents - 1) in
let off = sring.header_size + (idx * sslot_size) in
let s = Io_page.sub sring.buf off sslot_size in
let size = get_sslot_ss_len s in
let off = sring.header_size + (sring.nr_ents * sslot_size) +
(idx * sring.slot_size) in
Io_page.sub sring.buf off size

let top_packet sring = slot sring (get_sring_hdr_sr_cur (sring.buf))

let pop_packet sring =
let b = sring.buf in
let i = get_sring_hdr_sr_cur b in
let n = get_sring_hdr_sr_avail b in
set_sring_hdr_sr_cur b ((i + 1) land (sring.nr_ents - 1));
set_sring_hdr_sr_avail b (n - 1);
return ()

let of_buf buf slot_size =
let power_of_2 x =
let x = x lor (x lsr 1) in
let x = x lor (x lsr 2) in
let x = x lor (x lsr 4) in
let x = x lor (x lsr 8) in
let x = x lor (x lsr 16) in
let x = x lor (x lsr 32) in
x - (x lsr 1)
in
let header_size = sring_hdr_size in
let total = Io_page.length buf in
let free_bytes = total - header_size in
let nr_ents = power_of_2 (free_bytes / slot_size) in
assert (header_size + (nr_ents * (sslot_size + slot_size)) < total);
set_sring_hdr_sr_cur buf 0;
set_sring_hdr_sr_avail buf 0;
set_sring_hdr_sr_size buf nr_ents;
set_sring_hdr_sr_slotsize buf slot_size;
{ buf; header_size; slot_size; nr_ents }

type t = { type t = {
backend_id: int; backend_id: int;
backend: string; backend: string;
mac: string; mac: string;
mutable active: bool; mutable active: bool;
rx_ring: sring;
} }


type id = string type id = string


external get_vifs: unit -> id list = "caml_get_vifs" external get_vifs: unit -> id list = "caml_get_vifs"
external plug_vif: id -> Io_page.t -> bool * int * string = "caml_plug_vif" external plug_vif: id -> bool * int * string = "caml_plug_vif"
external unplug_vif: id -> unit = "caml_unplug_vif" external unplug_vif: id -> unit = "caml_unplug_vif"
external get_mbufs : int -> Io_page.t list = "caml_get_mbufs"


let devices : (id, t) Hashtbl.t = Hashtbl.create 1 let devices : (id, t) Hashtbl.t = Hashtbl.create 1


Expand All @@ -128,10 +59,8 @@ let plug id =
return (Hashtbl.find devices id) return (Hashtbl.find devices id)
with Not_found -> with Not_found ->
let backend = id in let backend = id in
let buf = Io_page.get ~pages_per_block:33 () in let active,backend_id,mac = plug_vif id in
let rx_ring = of_buf buf 2048 in let t = { backend_id; backend; mac; active } in
let active,backend_id,mac = plug_vif id buf in
let t = { backend_id; backend; mac; active; rx_ring } in
Hashtbl.add devices id t; Hashtbl.add devices id t;
return t return t


Expand Down Expand Up @@ -161,10 +90,12 @@ let writev ifc pages =
return () return ()


let rx_poll ifc fn = let rx_poll ifc fn =
while_lwt (avail_packet ifc.rx_ring > 0) do let mbufs = get_mbufs ifc.backend_id in
fn (top_packet ifc.rx_ring) >> Lwt_list.iter_s (fun m ->
pop_packet ifc.rx_ring try_lwt fn m
done with exn ->
return (printf "Exception on receive: %s\n%!" (Printexc.to_string exn)))
mbufs


let listen ifc fn = let listen ifc fn =
let rec poll_t () = let rec poll_t () =
Expand Down

0 comments on commit fb0077a

Please sign in to comment.