-
Notifications
You must be signed in to change notification settings - Fork 124
Improve large buffers and demonstrate with OpenAI protocol support #1353
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
Changes from all commits
8e872fb
4004bc7
e5c2621
8aad6d4
e4269bf
7cf980b
b966704
d56db26
8d60460
51985af
14a3af9
2bb9d35
80a40e2
9c3cd13
18af86a
5ef78b6
eb58d99
1b19f9f
ef580fb
dc3966c
7b44dbb
7056ae9
9a41f80
8fd63df
5d81bcf
bf6ec0e
9ebf022
f5a8208
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in | ||
| all copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| THE SOFTWARE. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |||||
| #include <bpfcore/vmlinux.h> | ||||||
| #include <bpfcore/bpf_builtins.h> | ||||||
| #include <bpfcore/bpf_helpers.h> | ||||||
| #include <bpfcore/utils.h> | ||||||
|
|
||||||
| #include <common/common.h> | ||||||
| #include <common/http_types.h> | ||||||
|
|
@@ -441,22 +442,15 @@ static __always_inline void process_http_response(http_info_t *info, const unsig | |||||
| static __always_inline void handle_http_response(unsigned char *small_buf, | ||||||
| pid_connection_info_t *pid_conn, | ||||||
| http_info_t *info, | ||||||
| int orig_len, | ||||||
| u8 direction, | ||||||
| u8 ssl) { | ||||||
| int orig_len) { | ||||||
| process_http_response(info, small_buf); | ||||||
| cleanup_http_request_data(pid_conn, info); | ||||||
|
|
||||||
| if ((direction != TCP_SEND) || | ||||||
| high_request_volume /*|| (ssl != NO_SSL) || (orig_len < KPROBES_LARGE_RESPONSE_LEN)*/) { | ||||||
| if (high_request_volume) { | ||||||
| finish_http(info, pid_conn); | ||||||
| } else { | ||||||
| if (ssl) { | ||||||
| finish_http(info, pid_conn); | ||||||
| } else { | ||||||
| bpf_dbg_printk("Delaying finish http for large request, orig_len=%d", orig_len); | ||||||
| info->delayed = 1; | ||||||
| } | ||||||
| bpf_dbg_printk("Delaying finish http for large request, orig_len=%d", orig_len); | ||||||
| info->delayed = 1; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -483,22 +477,49 @@ static __always_inline int http_send_large_buffer(http_info_t *req, | |||||
| large_buf->action = action; | ||||||
| large_buf->tp = req->tp; | ||||||
|
|
||||||
| large_buf->len = bytes_len; | ||||||
| if (large_buf->len >= http_buffer_size) { | ||||||
| large_buf->len = http_buffer_size; | ||||||
| bpf_dbg_printk("WARN: buffer is full, truncating data"); | ||||||
| req->has_large_buffers = true; | ||||||
|
|
||||||
| u32 available_bytes = bytes_len; | ||||||
| // limit by the userspace requested size | ||||||
| if (available_bytes > http_buffer_size) { | ||||||
| available_bytes = http_buffer_size; | ||||||
| } | ||||||
| // limit by the maximum bytes we can ever export | ||||||
| bpf_clamp_umax(available_bytes, k_large_buffer_read_limit); | ||||||
|
|
||||||
| bpf_probe_read(large_buf->buf, large_buf->len & k_large_buf_payload_max_size_mask, u_buf); | ||||||
| bpf_dbg_printk("sending large buffer, total size=%d, packet_type=%d, direction %d", | ||||||
| bytes_len, | ||||||
| packet_type, | ||||||
| direction); | ||||||
|
|
||||||
| u32 total_size = sizeof(tcp_large_buffer_t); | ||||||
| total_size += large_buf->len > sizeof(void *) ? large_buf->len : sizeof(void *); | ||||||
| const uint32_t niter = (available_bytes / k_large_buf_payload_max_size) + | ||||||
|
mmat11 marked this conversation as resolved.
|
||||||
| ((available_bytes % k_large_buf_payload_max_size) > 0); | ||||||
|
rafaelroquetto marked this conversation as resolved.
|
||||||
|
|
||||||
| req->has_large_buffers = true; | ||||||
| int b = 0; | ||||||
| for (; b < niter; b++) { | ||||||
| const u32 offset = b * k_large_buf_payload_max_size; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and then this becomes
Suggested change
otherwise your stride is potentially larger than |
||||||
| if (offset >= k_large_buffer_read_limit) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
if we can read at most |
||||||
| break; | ||||||
| } | ||||||
| u32 read_size = available_bytes; | ||||||
|
rafaelroquetto marked this conversation as resolved.
|
||||||
| bpf_clamp_umax(read_size, k_large_buf_payload_max_size); | ||||||
|
rafaelroquetto marked this conversation as resolved.
|
||||||
| bpf_probe_read(large_buf->buf, read_size, (void *)(&u_buf[offset])); | ||||||
|
|
||||||
| // left here intentionally for debugging | ||||||
| // bpf_dbg_printk("sending large buffer, size=%d, action=%d", read_size, action); | ||||||
|
|
||||||
| large_buf->len = read_size; | ||||||
|
|
||||||
| bpf_dbg_printk("sending large buffer, size=%d", bytes_len); | ||||||
| u32 total_size = sizeof(tcp_large_buffer_t); | ||||||
| total_size += large_buf->len > sizeof(void *) ? large_buf->len : sizeof(void *); | ||||||
|
|
||||||
| bpf_clamp_umax(total_size, k_large_buf_max_size); | ||||||
| bpf_ringbuf_output(&events, large_buf, total_size, get_flags()); | ||||||
|
|
||||||
| available_bytes -= read_size; | ||||||
| large_buf->action = k_large_buf_action_append; | ||||||
| } | ||||||
|
|
||||||
| bpf_ringbuf_output(&events, large_buf, total_size & k_large_buf_max_size_mask, get_flags()); | ||||||
| return 0; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -659,9 +680,9 @@ __obi_protocol_http(struct pt_regs *ctx, unsigned char *(*tp_loop_fn)(unsigned c | |||||
| args->packet_type, | ||||||
| args->direction, | ||||||
| k_large_buf_action_init); | ||||||
| handle_http_response( | ||||||
| args->small_buf, &args->pid_conn, info, args->bytes_len, args->direction, args->ssl); | ||||||
| handle_http_response(args->small_buf, &args->pid_conn, info, args->bytes_len); | ||||||
| } else if (still_reading(info)) { | ||||||
| // print here | ||||||
| http_send_large_buffer(info, | ||||||
| (void *)args->u_buf, | ||||||
| args->bytes_len, | ||||||
|
|
@@ -670,7 +691,9 @@ __obi_protocol_http(struct pt_regs *ctx, unsigned char *(*tp_loop_fn)(unsigned c | |||||
| k_large_buf_action_append); | ||||||
|
|
||||||
| info->len += args->bytes_len; | ||||||
| } else if (still_responding(info)) { | ||||||
| info->end_monotime_ns = bpf_ktime_get_ns(); | ||||||
| info->resp_len += args->bytes_len; | ||||||
| } | ||||||
|
|
||||||
| return 0; | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be misunderstanding so please bear with me.
http_buffer_sizeis always meant to be less thank_large_buf_payload_max_size(i.e.k_large_buf_payload_max_sizeis a ceiling).So capping
available_bytestohttp_buffer_sizemeans that you will always end up sending a single large buffer (niter == 1) and I am assuming the intent here is to sliceavailable_bytesintoNlarge buffers, so I think this block should be removed - then see below.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not necessarily, it's set by userspace and while there's a cap on the config setting, I don't want to leave it up to userspace to decide.
User space can set 2K, or 200K. If it's 2K we should only send 2K. If it's 200K, it should send 64K.