changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / lisp/ffi/uring/pkg.lisp

changeset 698: 96958d3eb5b0
parent: f08ae719ab2a
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
1 ;;; uring/pkg.lisp --- URING Systems
2 
3 ;; /usr/include/liburing.h
4 
5 ;;; Commentary:
6 
7 ;; IO_URING is our preferred means of IO on Linux. The bindings here
8 ;; are used by the high-level library IO.
9 
10 ;; As a point of reference, we look to the SB-SYS:SERVE-EVENT function
11 ;; in SBCL. This is an async event loop which dispatches to a backend
12 ;; based on features. On Linux it will use either poll or select(2),
13 ;; neither of which are particularly fast.
14 
15 ;; Using the bindings provided by this library we will implement an
16 ;; alternative backend to dispatch to.
17 
18 ;; ref: https://kernel.dk/io_uring.pdf
19 
20 ;; guide: https://unixism.net/loti/low_level.html
21 
22 ;; tokio/io-uring: https://github.com/tokio-rs/io-uring
23 
24 #|
25 
26 There are two fundamental operations associated with an async
27 interface: the act of submitting a request, and the event that is
28 associated with the completion of said request.
29 
30 For submitting IO, the application is the producer and the kernel is
31 the consumer. The opposite is true for completions - here the kernel
32 produces completion events and the application consumes them.
33 
34 Hence, we need a pair of rings to provide an effective communication
35 channel between an application and the kernel. That pair of rings is
36 at the core of the new interface, io_uring.
37 
38 They are suitably named submission queue (SQ), and completion
39 queue (CQ), and form the foundation of the new interface.
40 
41 |#
42 ;;; Code:
43 (defpackage :uring
44  (:use :cl :std :sb-alien)
45  (:import-from :sb-posix :file-descriptor :sap-or-nil)
46  (:import-from :obj/build :build :build-from)
47  (:export :load-uring :io-uring-cq :io-uring-cq*
48  :completion-queue-offsets :completion-queue
49  :completion-queue-entry :completion-queue-entry-32
50  :io-uring-sq :io-uring-sq* :submission-queue-offsets :submission-queue
51  :io-uring-cqe :io-uring-cqe* :io-uring-sqe :io-uring-sqe*
52  :submission-queue-entry :submission-queue-entry-128
53  :io-memory-map :parse-io-uring-params :io-params :io-uring
54  :uring :*default-io-params* :uring-builder :setup-queue
55  :make-queue :build-submitter :sigset-t :cpu-set-t
56  :cpu-mask-t :recv-msg-out :cancel-builder :mmapped-region
57  :with-io-uring :with-new-io-uring :io-uring-get-sqe :io-uring-sqe-set-flags
58  :with-io-sqe :with-new-io-sqe :with-io-cqe :with-new-io-cqe
59  :io-uring-prep-rw :io-uring* :make-io-restriction :io-restriction
60  :io-restriction-p :*default-io-params* :*default-io-entry-count* :io-submitter
61  :make-io-submitter))
62 
63 (in-package :uring)
64 (define-alien-loader "uring" t "/usr/lib/")
65 ;; defaults on x86_64
66 (defconstant +cpu-setsize+ 16)
67 (defconstant +sigset-nwords+ 16)
68 (defconstant +ncpu-bits+ 16)
69 
70 (define-alien-type kernel-rwf-t int)
71 
72 (define-alien-type io-uring-op unsigned-int)
73 
74 (define-alien-type io-uring-restriction-slot2
75  (union io-uring-restriction-slot2
76  (register-op unsigned-char)
77  (sqe-op unsigned-char)
78  (sqe-flags unsigned-char)))
79 
80 (define-alien-type io-uring-restriction
81  (struct io-uring-restriction
82  (opcode unsigned-short)
83  (op-or-flags (union io-uring-restriction-slot2))
84  (resv unsigned-char)
85  (resv2 (array unsigned-int 3))))
86 
87 (define-alien-type io-uring-buf-ring-resv-and-tail
88  (struct io-uring-buf-ring-resv-and-tail
89  (resv1 unsigned-long)
90  (resv2 unsigned-int)
91  (resv3 unsigned-short)
92  (tail unsigned-short)))
93 
94 (define-alien-type io-uring-buf-ring-slot1
95  (union io-uring-buf-ring-slot1
96  (resv-and-tail io-uring-buf-ring-resv-and-tail)
97  (bufs (* (struct io-uring-buf)))))
98 
99 (define-alien-type io-uring-buf-ring
100  (struct io-uring-buf-ring
101  (tail-or-bufs (union io-uring-buf-ring-slot1))))
102 
103 (define-alien-type io-uring-sqe-cmd-op-and-pad
104  (struct io-uring-sqe-cmd-op-and-pad
105  (cmd-op unsigned-int)
106  (pad unsigned-int)))
107 
108 (define-alien-type io-uring-sqe-slot5
109  (union io-uring-sqe-slot5
110  (off unsigned-long)
111  (addr2 unsigned-long)
112  (cmd-op-and-pad (struct io-uring-sqe-cmd-op-and-pad))))
113 
114 (define-alien-type io-uring-sqe-slot6
115  (union io-uring-sqe-slot6
116  (addr unsigned-long)
117  (splice-off-in unsigned-long)))
118 
119 (define-alien-type io-uring-sqe-slot8
120  (union io-uring-sqe-slot8
121  (rw-flags kernel-rwf-t)
122  (fsync-flags unsigned-int)
123  (poll-events unsigned-short)
124  (poll32-events unsigned-int)
125  (sync-range-flags unsigned-int)
126  (msg-flags unsigned-int)
127  (timeout-flags unsigned-int)
128  (accept-flags unsigned-int)
129  (cancel-flags unsigned-int)
130  (open-flags unsigned-int)
131  (statx-flags unsigned-int)
132  (fadvise-advice unsigned-int)
133  (splice-flags unsigned-int)
134  (rename-flags unsigned-int)
135  (unlink-flags unsigned-int)
136  (hardlink-flags unsigned-int)
137  (xattr-flags unsigned-int)
138  (msg-ring-flags unsigned-int)
139  (uring-cmd-flags unsigned-int)))
140 
141 (define-alien-type io-uring-sqe-slot10
142  (union io-uring-sqe-slot10
143  (buf-index unsigned-short)
144  (buf-group unsigned-short)))
145 
146 (define-alien-type io-uring-sqe-addr-len-and-pad
147  (struct io-uring-sqe-addr-len-and-pad
148  (addr-len unsigned-short)
149  (pad3 (array unsigned-short 1))))
150 
151 (define-alien-type io-uring-sqe-slot12
152  (union io-uring-sqe-slot12
153  (splice-fd-in int)
154  (file-index unsigned-int)
155  (addr-len-and-pad (struct io-uring-sqe-addr-len-and-pad))))
156 
157 (define-alien-type io-uring-sqe-addr3-and-pad
158  (struct io-uring-sqe-addr3-and-pad
159  (addr3 unsigned-long)
160  (pad2 (array unsigned-long 1))))
161 
162 (define-alien-type io-uring-sqe-slot13
163  (union io-uring-sqe-slot13
164  (addr3-and-pad (struct io-uring-sqe-addr3-and-pad))
165  (cmd (array unsigned-char 0))))
166 
167 (define-alien-type io-uring-sqe
168  (struct io-uring-sqe
169  (opcode unsigned-char)
170  (flags unsigned-char)
171  (ioprio unsigned-short)
172  (fd int)
173  (off-addr-cmd (union io-uring-sqe-slot5))
174  (addr-or-splice-off-in (union io-uring-sqe-slot6))
175  (len unsigned-int)
176  (flags2 (union io-uring-sqe-slot8))
177  (user-data unsigned-long)
178  (buf-opt (union io-uring-sqe-slot10))
179  (personality unsigned-short)
180  (splice-index-addr (union io-uring-sqe-slot12))
181  (addr-or-cmd (union io-uring-sqe-slot13))))
182 
183 (define-alien-type io-uring-sqe* (* (struct io-uring-sqe)))
184 (define-alien-type io-uring-cqe* (* (struct io-uring-cqe)))
185 
186 ;; NOTE 2024-05-12: alpha and mips use 535,536,537
187 (defconstant +nr-io-uring-setup+ 425)
188 (defconstant +nr-io-uring-enter+ 426)
189 (defconstant +nr-io-uring-register+ 427)
190 
191 (define-alien-type io-uring-sq
192  (struct io-uring-sq
193  (khead (* unsigned))
194  (ktail (* unsigned))
195  (kring-mask (* unsigned))
196  (kring-entries (* unsigned))
197  (kflags (* unsigned))
198  (kdropped (* unsigned))
199  (array (* unsigned))
200  (sqes (* (struct io-uring-sqe)))
201  (sqe-head unsigned)
202  (sqe-tail unsigned)
203  (ring-sz sb-unix:size-t)
204  (ring-ptr (* t))
205  (ring-mask unsigned)
206  (ring-entries unsigned)
207  (pad (array unsigned 2))))
208 
209 (define-alien-type io-uring-sq* (* (struct io-uring-sq)))
210 
211 (define-alien-type io-uring-cq
212  (struct io-uring-cq
213  (khead (* unsigned))
214  (ktail (* unsigned))
215  (kring-mask (* unsigned))
216  (kring-entries (* unsigned))
217  (kflags (* unsigned))
218  (koverflow (* unsigned))
219  (cqes (* (struct io-uring-cqe)))
220  (ring-sz sb-unix:size-t)
221  (ring-ptr (* t))
222  (ring-mask unsigned)
223  (ring-entries unsigned)
224  (pad (array unsigned-int 2))))
225 
226 (define-alien-type io-uring-cq* (* (struct io-uring-cq)))
227 
228 (define-alien-type io-uring
229  (struct io-uring
230  (sq (struct io-uring-sq))
231  (cq (struct io-uring-cq))
232  (flags unsigned)
233  (ring-fd int)
234  (features unsigned)
235  (enter-ring-fd int)
236  (int-flags unsigned-char)
237  (pad (array unsigned-char 3))
238  (pad2 unsigned)))
239 
240 (define-alien-type io-uring* (* (struct io-uring)))
241 
242 (define-alien-type io-uring-probe* (* (struct io-uring-probe)))