mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 11:37:06 +02:00
mem-buf-msgq: Reduce buffer free complexity
Reuse the same buffer for each message in mem_buf_msgq_recv_fn() instead of allocating a new one for each message, and freeing it in a dozen different locations depending on what type of message it is. If a consumer of the message needs to defer its work to a workqueue, it must allocate a new copy of the message. Change-Id: Ia5583bc7dc9937211f25624f7a679d34fe8fb521 Signed-off-by: Patrick Daly <quic_pdaly@quicinc.com>
This commit is contained in:
parent
0f6efbf911
commit
63bddcd463
|
|
@ -445,6 +445,7 @@ static void mem_buf_alloc_req_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
resp_msg = mem_buf_construct_alloc_resp(req_msg, ret, hdl);
|
||||
|
||||
kfree(rmt_msg->msg);
|
||||
kfree(rmt_msg);
|
||||
if (IS_ERR(resp_msg))
|
||||
|
|
@ -510,7 +511,6 @@ static int mem_buf_alloc_resp_hdlr(void *hdlr_data, void *msg_buf, size_t size,
|
|||
|
||||
trace_receive_alloc_resp_msg(alloc_resp);
|
||||
if (!(mem_buf_capability & MEM_BUF_CAP_CONSUMER)) {
|
||||
kfree(msg_buf);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
|
|
@ -521,23 +521,26 @@ static int mem_buf_alloc_resp_hdlr(void *hdlr_data, void *msg_buf, size_t size,
|
|||
membuf->memparcel_hdl = get_alloc_resp_hdl(alloc_resp);
|
||||
}
|
||||
|
||||
kfree(msg_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Functions invoked when treating allocation requests to other VMs. */
|
||||
static void mem_buf_alloc_req_hdlr(void *hdlr_data, void *buf, size_t size)
|
||||
static void mem_buf_alloc_req_hdlr(void *hdlr_data, void *_buf, size_t size)
|
||||
{
|
||||
struct mem_buf_rmt_msg *rmt_msg;
|
||||
void *buf;
|
||||
|
||||
if (!(mem_buf_capability & MEM_BUF_CAP_SUPPLIER)) {
|
||||
kfree(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
rmt_msg = kmalloc(sizeof(*rmt_msg), GFP_KERNEL);
|
||||
if (!rmt_msg) {
|
||||
kfree(buf);
|
||||
if (!rmt_msg)
|
||||
return;
|
||||
|
||||
buf = kmemdup(_buf, size, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
kfree(rmt_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -547,18 +550,22 @@ static void mem_buf_alloc_req_hdlr(void *hdlr_data, void *buf, size_t size)
|
|||
queue_work(mem_buf_wq, &rmt_msg->work);
|
||||
}
|
||||
|
||||
static void mem_buf_relinquish_hdlr(void *hdlr_data, void *buf, size_t size)
|
||||
static void mem_buf_relinquish_hdlr(void *hdlr_data, void *_buf, size_t size)
|
||||
{
|
||||
struct mem_buf_rmt_msg *rmt_msg;
|
||||
void *buf;
|
||||
|
||||
if (!(mem_buf_capability & MEM_BUF_CAP_SUPPLIER)) {
|
||||
kfree(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
rmt_msg = kmalloc(sizeof(*rmt_msg), GFP_KERNEL);
|
||||
if (!rmt_msg) {
|
||||
kfree(buf);
|
||||
if (!rmt_msg)
|
||||
return;
|
||||
|
||||
buf = kmemdup(_buf, size, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
kfree(rmt_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -310,7 +310,6 @@ static void mem_buf_process_alloc_resp(struct mem_buf_msgq_desc *desc, void *buf
|
|||
if (!alloc_resp->ret) {
|
||||
desc->msgq_ops->relinquish_memparcel_hdl(desc->hdlr_data, hdr->txn_id,
|
||||
alloc_resp->hdl);
|
||||
kfree(buf);
|
||||
}
|
||||
} else {
|
||||
txn->txn_ret = desc->msgq_ops->alloc_resp_hdlr(desc->hdlr_data, buf, size,
|
||||
|
|
@ -328,7 +327,6 @@ static void mem_buf_process_msg(struct mem_buf_msgq_desc *desc, void *buf, size_
|
|||
if (size < sizeof(*hdr) || hdr->msg_size != size) {
|
||||
pr_err("%s: message received is not of a proper size: 0x%lx\n",
|
||||
__func__, size);
|
||||
kfree(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -345,7 +343,6 @@ static void mem_buf_process_msg(struct mem_buf_msgq_desc *desc, void *buf, size_
|
|||
default:
|
||||
pr_err("%s: received message of unknown type: %d\n", __func__,
|
||||
hdr->msg_type);
|
||||
kfree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -367,20 +364,20 @@ static int mem_buf_msgq_recv_fn(void *data)
|
|||
size_t size;
|
||||
int ret;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
buf = kzalloc(GH_MSGQ_MAX_MSG_SIZE_BYTES, GFP_KERNEL);
|
||||
if (!buf)
|
||||
continue;
|
||||
buf = kzalloc(GH_MSGQ_MAX_MSG_SIZE_BYTES, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
ret = gh_msgq_recv(desc->msgq_hdl, buf, GH_MSGQ_MAX_MSG_SIZE_BYTES, &size, 0);
|
||||
if (ret < 0) {
|
||||
kfree(buf);
|
||||
pr_err_ratelimited("%s failed to receive message rc: %d\n", __func__, ret);
|
||||
} else {
|
||||
mem_buf_process_msg(desc, buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user