Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove internal Cstruct.t #65

Merged
merged 17 commits into from Apr 19, 2024
Merged

Remove internal Cstruct.t #65

merged 17 commits into from Apr 19, 2024

Conversation

palainp
Copy link
Member

@palainp palainp commented Mar 12, 2024

Dear devs,
This PR wants to remove most of the Cstruct.t uses (the remaining is kept for ocaml-vchan and probably it can be difficult to change the API as it uses io-pages with Xen, but there is some ppx_cstruct that couldn't be changed anyway).
So as this was one of the first un-ppx_cstruct-ion for me, there is probably a lot of improvement to be done (I have a lot of Bytes.t / String conversion, and Bytes.blit that might be unwanted copies...) + I still have some missing Cstruct.hexdump-like that would be great to print out (those are limited to gUI.ml but qubes-mirage-firewall, that I use for testing the PR, doesn't use gUI.ml at all).
Any review / comments are welcome :)
Best,

Copy link
Member

@reynir reynir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if this library actually had any tests :D

A notable change is RExec.Client_flow uses bytes and is now even further away from Mirage_flow.S. However, the signature did not match Mirage_flow.S already so it's perhaps not a big loss. I recall qrexec being somewhat difficult to expose as a Mirage_flow.S as it is really two in-channels (stdout and stderr) and one out-channel (stdin) plus the possibility of EOF with and without exit code.

As you note there could be done less copying. Some of the functions could also take string over bytes. I'm fine with doing that in another PR.

I think we would need cstruct (or bigarray) at the edge due to xen/vchan details - but that's maybe okay. It seems we already copy cstructs around.

I have not done a thorough review and just skimmed some parts.

Did you do any tests to see if there's any difference in performance or memory usage?

@palainp
Copy link
Member Author

palainp commented Mar 13, 2024

Indeed a test suite would be great but I'm not sure to be able to write that :(

So far the only tests I've done are based on qubes-mirage-firewall usage and I didn't saw drop in performance (here the interface usage is quite limited and qubes-mirage-firewall bottleneck is more with Xen buffers for net packets than communication from/to using rExec, gUI, od dB).
I however saw some bits of improvment because we now don't allocate some Cstruct.t, like:

[2024-03-12 16:51:22] 2024-03-12T15:51:22-00:00: [DEBUG] [qubes.db] "/connected-ips" = "10.137.0.13"
[2024-03-12 16:51:22] malloc(): for 0 @0, new memory usage = 5526936
[2024-03-12 16:51:22] malloc(): for 4 @0xac8fa0, new memory usage = 5526960
[2024-03-12 16:51:22] malloc(): for 8 @0xac8fc0, new memory usage = 5526984
[2024-03-12 16:51:22] malloc(): for 12 @0xac8fe0, new memory usage = 5527008
[2024-03-12 16:51:23] 2024-03-12T15:51:23-00:00: [DEBUG] [qubes.rexec] remote end wants to use protocol version 3, continuing with version 3

becomes:

[2024-03-12 16:47:05] 2024-03-12T15:47:05-00:00: [DEBUG] [qubes.db] "/connected-ips" = "10.137.0.13"
[2024-03-12 16:47:05] malloc(): for 12 @0xabc330, new memory usage = 5540816
[2024-03-12 16:47:05] 2024-03-12T15:47:05-00:00: [DEBUG] [qubes.rexec] remote end wants to use protocol version 3, continuing with version 3

Here I suspect 0B, 4B and 8B to be some msg_header or similar (0B is more probably one of the mutable buffer). And the remaining 12B is, to me, either another ppx_cstruct generated structure, probably elsewhere, or the result of the last Cstruct creation [Cstruct.of_bytes c].

About the cstruct I've kept it for the ocaml-vchan usage and this seems unavoidable as it relies on io-pages which need to be adresses aligned, and thus cannot be an Ocaml item.

@palainp
Copy link
Member Author

palainp commented Mar 13, 2024

And thanks for the comments :)

And a last note is to me, even if there is no memory nor bandwidth improvement, it would help regarding the GC job as Bytes.t seem to be better collected than malloced memory. So I'm only aiming to avoid a drop in performance :)

lib/gUI.ml Outdated Show resolved Hide resolved
lib/gUI.ml Outdated Show resolved Hide resolved
@hannesm
Copy link
Member

hannesm commented Mar 15, 2024

Hmm, maybe ohex should in pp if the data is < 16 bytes not emit any newlines, and no addresses and no byte representation?

@palainp
Copy link
Member Author

palainp commented Mar 17, 2024

So with the last commit I now have only Strings and less copies.
I'm quite not sure about the int32_le_string_creation (in lib/formats.ml):

let of_int32_le i =
  assert(i < Int32.max_int);
  let i = Int32.to_int i in
  String.init 4 (fun p -> Char.chr ((i lsr (p*8)) land 0xff))

There is probably something better to create strings as 4B from a int32?

About ohex.pp I would love if there is something like an optional parameter (default to not activated) to only prints the bytes values (I like the current separation between 2B packs, but without the addresses, nor the end of lines).

@palainp
Copy link
Member Author

palainp commented Mar 17, 2024

Oh :( String.get_int32_le only exists since 4.13. I'm not sure what's the best move bump lower to 4.13 (this is what I'd do but so far it was 4.06, the step is to big?) / stick with the Bytes / any intermediate solution?

A second point is now I have in lib/formats.ml a lot of getter/setter commented out, maybe it can be ok to remove all those lines?

@reynir
Copy link
Member

reynir commented Mar 17, 2024 via email

@palainp
Copy link
Member Author

palainp commented Mar 18, 2024

Thank you @reynir , I applied your suggestion in 930796d :)

lib/rExec.ml Outdated Show resolved Hide resolved
Co-authored-by: Hannes Menhert <hannes@mehnert.org>
Co-authored-by: Reynir Björnsson <reynir@reynir.dk>
lib/formats.ml Outdated Show resolved Hide resolved
@palainp
Copy link
Member Author

palainp commented Mar 20, 2024

So far I think it's ready for review. EDIT: The original code used uint32_t with ppx_cstruct and I swapped to Int32.t everywhere. It seems that the manipulated values are fine with that modification (0<x<2^31).

The remaining thing I worried about it the last Cstruct.t bits (interface with ocaml-vchan) and particulary the Cstruct.t creation in lib/msg_chan.ml:66 (let cs = List.map Cstruct.of_string buffers in).

Using small strings in Cstruct.of_string still leads to small Cstruct.t creations. I haven't checked whether it's possible to concat all the strings together and use Vchan_xen.write instead of writev, but I wonder if that sounds plausible to change the ocaml-vchan API to accept Strings and deal with Cstruct.t there.

@hannesm
Copy link
Member

hannesm commented Apr 18, 2024

I appreciate this work, and would like to spend some time reviewing it. About the ocaml-vchan "move to string" line of work -- this is best done as a separate step since it is quite involved. I suggest to review & merge this first (and cut a release), and once we're cstruct-free in mirage-flow etc., we can adapt the remaining occurences here.

@hannesm
Copy link
Member

hannesm commented Apr 18, 2024

I took the liberty to cleanup whitespaces, rename String.t to string, and remove Lwt.fail_with usage.

IMHO fine to merge & release.

Copy link
Member

@hannesm hannesm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏾

@palainp
Copy link
Member Author

palainp commented Apr 19, 2024

Thank you for your review and the modifications!

@palainp palainp merged commit 7318294 into mirage:main Apr 19, 2024
1 check passed
@palainp palainp deleted the no-cstruct branch April 19, 2024 08:47
palainp added a commit to palainp/opam-repository that referenced this pull request Apr 19, 2024
palainp added a commit to palainp/opam-repository that referenced this pull request Apr 19, 2024
CHANGES:

- Remove internal Cstruct.t (mirage/mirage-qubes#65, @reynir @hannesm @palainp)
- Add lower bound for Lwt to 5.7.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants