Skip to content

Commit 27d25d1

Browse files
authored
[libc] Increase RPC opcode to 32-bit and use a class byte (#116905)
Summary: Currently, the RPC interface uses a basic opcode to communicate with the server. This currently is 16 bits. There's no reason for this to be 16 bits, because on the GPU a 32-bit write is the same as a 16-bit write performance wise. Additionally, I am now making all the `libc` based opcodes qualified with the 'c' type, mimiciing how Linux handles `ioctls` all coming from the same driver. This will make it easier to extend the interface when it's exported directly.
1 parent 4f1b20f commit 27d25d1

File tree

7 files changed

+50
-47
lines changed

7 files changed

+50
-47
lines changed

libc/docs/gpu/rpc.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,6 @@ associated with relocatable device code linking.
302302
Extensions
303303
----------
304304

305-
We describe which operation the RPC server should take with a 16-bit opcode. We
306-
consider the first 32768 numbers to be reserved while the others are free to
307-
use.
305+
The opcode is a 32-bit integer that must be unique to the requested operation.
306+
All opcodes used by ``libc`` internally have the character ``c`` in the most
307+
significant byte.

libc/include/llvm-libc-types/rpc_opcodes_t.h

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,41 @@
99
#ifndef LLVM_LIBC_TYPES_RPC_OPCODES_T_H
1010
#define LLVM_LIBC_TYPES_RPC_OPCODES_T_H
1111

12+
#define LLVM_LIBC_RPC_BASE 'c'
13+
#define LLVM_LIBC_OPCODE(n) (LLVM_LIBC_RPC_BASE << 24 | n)
14+
1215
typedef enum {
13-
RPC_NOOP = 0,
14-
RPC_EXIT,
15-
RPC_WRITE_TO_STDOUT,
16-
RPC_WRITE_TO_STDERR,
17-
RPC_WRITE_TO_STREAM,
18-
RPC_WRITE_TO_STDOUT_NEWLINE,
19-
RPC_READ_FROM_STREAM,
20-
RPC_READ_FGETS,
21-
RPC_OPEN_FILE,
22-
RPC_CLOSE_FILE,
23-
RPC_MALLOC,
24-
RPC_FREE,
25-
RPC_HOST_CALL,
26-
RPC_ABORT,
27-
RPC_FEOF,
28-
RPC_FERROR,
29-
RPC_CLEARERR,
30-
RPC_FSEEK,
31-
RPC_FTELL,
32-
RPC_FFLUSH,
33-
RPC_UNGETC,
34-
RPC_PRINTF_TO_STDOUT,
35-
RPC_PRINTF_TO_STDERR,
36-
RPC_PRINTF_TO_STREAM,
37-
RPC_PRINTF_TO_STDOUT_PACKED,
38-
RPC_PRINTF_TO_STDERR_PACKED,
39-
RPC_PRINTF_TO_STREAM_PACKED,
40-
RPC_REMOVE,
41-
RPC_RENAME,
42-
RPC_SYSTEM,
43-
RPC_LAST = 0xFFFF,
16+
RPC_NOOP = LLVM_LIBC_OPCODE(0),
17+
RPC_EXIT = LLVM_LIBC_OPCODE(1),
18+
RPC_WRITE_TO_STDOUT = LLVM_LIBC_OPCODE(2),
19+
RPC_WRITE_TO_STDERR = LLVM_LIBC_OPCODE(3),
20+
RPC_WRITE_TO_STREAM = LLVM_LIBC_OPCODE(4),
21+
RPC_WRITE_TO_STDOUT_NEWLINE = LLVM_LIBC_OPCODE(5),
22+
RPC_READ_FROM_STREAM = LLVM_LIBC_OPCODE(6),
23+
RPC_READ_FGETS = LLVM_LIBC_OPCODE(7),
24+
RPC_OPEN_FILE = LLVM_LIBC_OPCODE(8),
25+
RPC_CLOSE_FILE = LLVM_LIBC_OPCODE(9),
26+
RPC_MALLOC = LLVM_LIBC_OPCODE(10),
27+
RPC_FREE = LLVM_LIBC_OPCODE(11),
28+
RPC_HOST_CALL = LLVM_LIBC_OPCODE(12),
29+
RPC_ABORT = LLVM_LIBC_OPCODE(13),
30+
RPC_FEOF = LLVM_LIBC_OPCODE(14),
31+
RPC_FERROR = LLVM_LIBC_OPCODE(15),
32+
RPC_CLEARERR = LLVM_LIBC_OPCODE(16),
33+
RPC_FSEEK = LLVM_LIBC_OPCODE(17),
34+
RPC_FTELL = LLVM_LIBC_OPCODE(18),
35+
RPC_FFLUSH = LLVM_LIBC_OPCODE(19),
36+
RPC_UNGETC = LLVM_LIBC_OPCODE(20),
37+
RPC_PRINTF_TO_STDOUT = LLVM_LIBC_OPCODE(21),
38+
RPC_PRINTF_TO_STDERR = LLVM_LIBC_OPCODE(22),
39+
RPC_PRINTF_TO_STREAM = LLVM_LIBC_OPCODE(23),
40+
RPC_PRINTF_TO_STDOUT_PACKED = LLVM_LIBC_OPCODE(24),
41+
RPC_PRINTF_TO_STDERR_PACKED = LLVM_LIBC_OPCODE(25),
42+
RPC_PRINTF_TO_STREAM_PACKED = LLVM_LIBC_OPCODE(26),
43+
RPC_REMOVE = LLVM_LIBC_OPCODE(27),
44+
RPC_RENAME = LLVM_LIBC_OPCODE(28),
45+
RPC_SYSTEM = LLVM_LIBC_OPCODE(29),
46+
RPC_LAST = 0xFFFFFFFF,
4447
} rpc_opcode_t;
4548

4649
#endif // LLVM_LIBC_TYPES_RPC_OPCODES_T_H

libc/src/__support/RPC/rpc.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static_assert(sizeof(Buffer) == 64, "Buffer size mismatch");
5151
/// perform and which threads are active in the slots.
5252
struct Header {
5353
uint64_t mask;
54-
uint16_t opcode;
54+
uint32_t opcode;
5555
};
5656

5757
/// The maximum number of parallel ports that the RPC interface can support.
@@ -319,11 +319,11 @@ template <bool T> struct Port {
319319
template <typename A>
320320
LIBC_INLINE void recv_n(void **dst, uint64_t *size, A &&alloc);
321321

322-
LIBC_INLINE uint16_t get_opcode() const {
322+
LIBC_INLINE uint32_t get_opcode() const {
323323
return process.header[index].opcode;
324324
}
325325

326-
LIBC_INLINE uint16_t get_index() const { return index; }
326+
LIBC_INLINE uint32_t get_index() const { return index; }
327327

328328
LIBC_INLINE void close() {
329329
// Wait for all lanes to finish using the port.
@@ -357,7 +357,7 @@ struct Client {
357357
: process(port_count, buffer) {}
358358

359359
using Port = rpc::Port<false>;
360-
template <uint16_t opcode> LIBC_INLINE Port open();
360+
template <uint32_t opcode> LIBC_INLINE Port open();
361361

362362
private:
363363
Process<false> process;
@@ -518,7 +518,7 @@ LIBC_INLINE void Port<T>::recv_n(void **dst, uint64_t *size, A &&alloc) {
518518
/// port. Each port instance uses an associated \p opcode to tell the server
519519
/// what to do. The Client interface provides the appropriate lane size to the
520520
/// port using the platform's returned value.
521-
template <uint16_t opcode>
521+
template <uint32_t opcode>
522522
[[clang::convergent]] LIBC_INLINE Client::Port Client::open() {
523523
// Repeatedly perform a naive linear scan for a port that can be opened to
524524
// send data.

libc/src/stdio/gpu/file.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ LIBC_INLINE ::FILE *to_stream(uintptr_t f) {
4949
return stream;
5050
}
5151

52-
template <uint16_t opcode>
52+
template <uint32_t opcode>
5353
LIBC_INLINE uint64_t write_impl(::FILE *file, const void *data, size_t size) {
5454
uint64_t ret = 0;
5555
rpc::Client::Port port = rpc::client.open<opcode>();

libc/src/stdio/gpu/vfprintf_utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
namespace LIBC_NAMESPACE_DECL {
1818

19-
template <uint16_t opcode>
19+
template <uint32_t opcode>
2020
LIBC_INLINE int vfprintf_impl(::FILE *__restrict file,
2121
const char *__restrict format, size_t format_size,
2222
va_list vlist) {

libc/utils/gpu/server/llvmlibc_rpc_server.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ rpc_status_t rpc_handle_server(rpc_device_t rpc_device);
7979
/// Register a callback to handle an opcode from the RPC client. The associated
8080
/// data must remain accessible as long as the user intends to handle the server
8181
/// with this callback.
82-
rpc_status_t rpc_register_callback(rpc_device_t rpc_device, uint16_t opcode,
82+
rpc_status_t rpc_register_callback(rpc_device_t rpc_device, uint32_t opcode,
8383
rpc_opcode_callback_ty callback, void *data);
8484

8585
/// Obtain a pointer to a local client buffer that can be copied directly to the

libc/utils/gpu/server/rpc_server.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ static void handle_printf(rpc::Server::Port &port, TempStorage &temp_storage) {
215215
template <uint32_t lane_size>
216216
rpc_status_t handle_server_impl(
217217
rpc::Server &server,
218-
const std::unordered_map<uint16_t, rpc_opcode_callback_ty> &callbacks,
219-
const std::unordered_map<uint16_t, void *> &callback_data,
218+
const std::unordered_map<uint32_t, rpc_opcode_callback_ty> &callbacks,
219+
const std::unordered_map<uint32_t, void *> &callback_data,
220220
uint32_t &index) {
221221
auto port = server.try_open(lane_size, index);
222222
if (!port)
@@ -477,8 +477,8 @@ struct Device {
477477
void *buffer;
478478
rpc::Server server;
479479
rpc::Client client;
480-
std::unordered_map<uint16_t, rpc_opcode_callback_ty> callbacks;
481-
std::unordered_map<uint16_t, void *> callback_data;
480+
std::unordered_map<uint32_t, rpc_opcode_callback_ty> callbacks;
481+
std::unordered_map<uint32_t, void *> callback_data;
482482
};
483483

484484
rpc_status_t rpc_server_init(rpc_device_t *rpc_device, uint64_t num_ports,
@@ -528,7 +528,7 @@ rpc_status_t rpc_handle_server(rpc_device_t rpc_device) {
528528
}
529529
}
530530

531-
rpc_status_t rpc_register_callback(rpc_device_t rpc_device, uint16_t opcode,
531+
rpc_status_t rpc_register_callback(rpc_device_t rpc_device, uint32_t opcode,
532532
rpc_opcode_callback_ty callback,
533533
void *data) {
534534
if (!rpc_device.handle)

0 commit comments

Comments
 (0)