Commit 1555583b authored by Dominique Martinet's avatar Dominique Martinet Committed by Greg Kroah-Hartman

9p: embed fcall in req to round down buffer allocs

[ Upstream commit 523adb6c ]

'msize' is often a power of two, or at least page-aligned, so avoiding
an overhead of two dozen bytes for each allocation will help the
allocator do its work and reduce memory fragmentation.

Link: http://lkml.kernel.org/r/1533825236-22896-1-git-send-email-asmadeus@codewreck.orgSuggested-by: default avatarMatthew Wilcox <willy@infradead.org>
Signed-off-by: default avatarDominique Martinet <dominique.martinet@cea.fr>
Reviewed-by: default avatarGreg Kurz <groug@kaod.org>
Acked-by: default avatarJun Piao <piaojun@huawei.com>
Cc: Matthew Wilcox <willy@infradead.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 3ea4cf42
...@@ -95,8 +95,8 @@ struct p9_req_t { ...@@ -95,8 +95,8 @@ struct p9_req_t {
int status; int status;
int t_err; int t_err;
wait_queue_head_t wq; wait_queue_head_t wq;
struct p9_fcall *tc; struct p9_fcall tc;
struct p9_fcall *rc; struct p9_fcall rc;
void *aux; void *aux;
struct list_head req_list; struct list_head req_list;
}; };
...@@ -230,6 +230,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode, ...@@ -230,6 +230,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
kgid_t gid, struct p9_qid *); kgid_t gid, struct p9_qid *);
int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status);
int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl); int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl);
void p9_fcall_fini(struct p9_fcall *fc);
struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status); void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
......
This diff is collapsed.
...@@ -354,7 +354,7 @@ static void p9_read_work(struct work_struct *work) ...@@ -354,7 +354,7 @@ static void p9_read_work(struct work_struct *work)
goto error; goto error;
} }
if (m->req->rc == NULL) { if (!m->req->rc.sdata) {
p9_debug(P9_DEBUG_ERROR, p9_debug(P9_DEBUG_ERROR,
"No recv fcall for tag %d (req %p), disconnecting!\n", "No recv fcall for tag %d (req %p), disconnecting!\n",
m->rc.tag, m->req); m->rc.tag, m->req);
...@@ -362,7 +362,7 @@ static void p9_read_work(struct work_struct *work) ...@@ -362,7 +362,7 @@ static void p9_read_work(struct work_struct *work)
err = -EIO; err = -EIO;
goto error; goto error;
} }
m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall); m->rc.sdata = m->req->rc.sdata;
memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity); memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
m->rc.capacity = m->rc.size; m->rc.capacity = m->rc.size;
} }
...@@ -372,7 +372,7 @@ static void p9_read_work(struct work_struct *work) ...@@ -372,7 +372,7 @@ static void p9_read_work(struct work_struct *work)
*/ */
if ((m->req) && (m->rc.offset == m->rc.capacity)) { if ((m->req) && (m->rc.offset == m->rc.capacity)) {
p9_debug(P9_DEBUG_TRANS, "got new packet\n"); p9_debug(P9_DEBUG_TRANS, "got new packet\n");
m->req->rc->size = m->rc.offset; m->req->rc.size = m->rc.offset;
spin_lock(&m->client->lock); spin_lock(&m->client->lock);
if (m->req->status != REQ_STATUS_ERROR) if (m->req->status != REQ_STATUS_ERROR)
status = REQ_STATUS_RCVD; status = REQ_STATUS_RCVD;
...@@ -469,8 +469,8 @@ static void p9_write_work(struct work_struct *work) ...@@ -469,8 +469,8 @@ static void p9_write_work(struct work_struct *work)
p9_debug(P9_DEBUG_TRANS, "move req %p\n", req); p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
list_move_tail(&req->req_list, &m->req_list); list_move_tail(&req->req_list, &m->req_list);
m->wbuf = req->tc->sdata; m->wbuf = req->tc.sdata;
m->wsize = req->tc->size; m->wsize = req->tc.size;
m->wpos = 0; m->wpos = 0;
spin_unlock(&m->client->lock); spin_unlock(&m->client->lock);
} }
...@@ -663,7 +663,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) ...@@ -663,7 +663,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
struct p9_conn *m = &ts->conn; struct p9_conn *m = &ts->conn;
p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
m, current, req->tc, req->tc->id); m, current, &req->tc, req->tc.id);
if (m->err < 0) if (m->err < 0)
return m->err; return m->err;
......
...@@ -122,7 +122,7 @@ struct p9_rdma_context { ...@@ -122,7 +122,7 @@ struct p9_rdma_context {
dma_addr_t busa; dma_addr_t busa;
union { union {
struct p9_req_t *req; struct p9_req_t *req;
struct p9_fcall *rc; struct p9_fcall rc;
}; };
}; };
...@@ -320,8 +320,8 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -320,8 +320,8 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc)
if (wc->status != IB_WC_SUCCESS) if (wc->status != IB_WC_SUCCESS)
goto err_out; goto err_out;
c->rc->size = wc->byte_len; c->rc.size = wc->byte_len;
err = p9_parse_header(c->rc, NULL, NULL, &tag, 1); err = p9_parse_header(&c->rc, NULL, NULL, &tag, 1);
if (err) if (err)
goto err_out; goto err_out;
...@@ -331,12 +331,13 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -331,12 +331,13 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc)
/* Check that we have not yet received a reply for this request. /* Check that we have not yet received a reply for this request.
*/ */
if (unlikely(req->rc)) { if (unlikely(req->rc.sdata)) {
pr_err("Duplicate reply for request %d", tag); pr_err("Duplicate reply for request %d", tag);
goto err_out; goto err_out;
} }
req->rc = c->rc; req->rc.size = c->rc.size;
req->rc.sdata = c->rc.sdata;
p9_client_cb(client, req, REQ_STATUS_RCVD); p9_client_cb(client, req, REQ_STATUS_RCVD);
out: out:
...@@ -361,7 +362,7 @@ send_done(struct ib_cq *cq, struct ib_wc *wc) ...@@ -361,7 +362,7 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
container_of(wc->wr_cqe, struct p9_rdma_context, cqe); container_of(wc->wr_cqe, struct p9_rdma_context, cqe);
ib_dma_unmap_single(rdma->cm_id->device, ib_dma_unmap_single(rdma->cm_id->device,
c->busa, c->req->tc->size, c->busa, c->req->tc.size,
DMA_TO_DEVICE); DMA_TO_DEVICE);
up(&rdma->sq_sem); up(&rdma->sq_sem);
kfree(c); kfree(c);
...@@ -401,7 +402,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c) ...@@ -401,7 +402,7 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c)
struct ib_sge sge; struct ib_sge sge;
c->busa = ib_dma_map_single(rdma->cm_id->device, c->busa = ib_dma_map_single(rdma->cm_id->device,
c->rc->sdata, client->msize, c->rc.sdata, client->msize,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
goto error; goto error;
...@@ -443,9 +444,9 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) ...@@ -443,9 +444,9 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
**/ **/
if (unlikely(atomic_read(&rdma->excess_rc) > 0)) { if (unlikely(atomic_read(&rdma->excess_rc) > 0)) {
if ((atomic_sub_return(1, &rdma->excess_rc) >= 0)) { if ((atomic_sub_return(1, &rdma->excess_rc) >= 0)) {
/* Got one ! */ /* Got one! */
kfree(req->rc); p9_fcall_fini(&req->rc);
req->rc = NULL; req->rc.sdata = NULL;
goto dont_need_post_recv; goto dont_need_post_recv;
} else { } else {
/* We raced and lost. */ /* We raced and lost. */
...@@ -459,7 +460,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) ...@@ -459,7 +460,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
err = -ENOMEM; err = -ENOMEM;
goto recv_error; goto recv_error;
} }
rpl_context->rc = req->rc; rpl_context->rc.sdata = req->rc.sdata;
/* /*
* Post a receive buffer for this request. We need to ensure * Post a receive buffer for this request. We need to ensure
...@@ -479,7 +480,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) ...@@ -479,7 +480,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
goto recv_error; goto recv_error;
} }
/* remove posted receive buffer from request structure */ /* remove posted receive buffer from request structure */
req->rc = NULL; req->rc.sdata = NULL;
dont_need_post_recv: dont_need_post_recv:
/* Post the request */ /* Post the request */
...@@ -491,7 +492,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) ...@@ -491,7 +492,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
c->req = req; c->req = req;
c->busa = ib_dma_map_single(rdma->cm_id->device, c->busa = ib_dma_map_single(rdma->cm_id->device,
c->req->tc->sdata, c->req->tc->size, c->req->tc.sdata, c->req->tc.size,
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) { if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) {
err = -EIO; err = -EIO;
...@@ -501,7 +502,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) ...@@ -501,7 +502,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req)
c->cqe.done = send_done; c->cqe.done = send_done;
sge.addr = c->busa; sge.addr = c->busa;
sge.length = c->req->tc->size; sge.length = c->req->tc.size;
sge.lkey = rdma->pd->local_dma_lkey; sge.lkey = rdma->pd->local_dma_lkey;
wr.next = NULL; wr.next = NULL;
......
...@@ -155,7 +155,7 @@ static void req_done(struct virtqueue *vq) ...@@ -155,7 +155,7 @@ static void req_done(struct virtqueue *vq)
} }
if (len) { if (len) {
req->rc->size = len; req->rc.size = len;
p9_client_cb(chan->client, req, REQ_STATUS_RCVD); p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
} }
} }
...@@ -273,12 +273,12 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) ...@@ -273,12 +273,12 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
out_sgs = in_sgs = 0; out_sgs = in_sgs = 0;
/* Handle out VirtIO ring buffers */ /* Handle out VirtIO ring buffers */
out = pack_sg_list(chan->sg, 0, out = pack_sg_list(chan->sg, 0,
VIRTQUEUE_NUM, req->tc->sdata, req->tc->size); VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
if (out) if (out)
sgs[out_sgs++] = chan->sg; sgs[out_sgs++] = chan->sg;
in = pack_sg_list(chan->sg, out, in = pack_sg_list(chan->sg, out,
VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity); VIRTQUEUE_NUM, req->rc.sdata, req->rc.capacity);
if (in) if (in)
sgs[out_sgs + in_sgs++] = chan->sg + out; sgs[out_sgs + in_sgs++] = chan->sg + out;
...@@ -416,15 +416,15 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, ...@@ -416,15 +416,15 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
if (n != outlen) { if (n != outlen) {
__le32 v = cpu_to_le32(n); __le32 v = cpu_to_le32(n);
memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4); memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
outlen = n; outlen = n;
} }
/* The size field of the message must include the length of the /* The size field of the message must include the length of the
* header and the length of the data. We didn't actually know * header and the length of the data. We didn't actually know
* the length of the data until this point so add it in now. * the length of the data until this point so add it in now.
*/ */
sz = cpu_to_le32(req->tc->size + outlen); sz = cpu_to_le32(req->tc.size + outlen);
memcpy(&req->tc->sdata[0], &sz, sizeof(sz)); memcpy(&req->tc.sdata[0], &sz, sizeof(sz));
} else if (uidata) { } else if (uidata) {
int n = p9_get_mapped_pages(chan, &in_pages, uidata, int n = p9_get_mapped_pages(chan, &in_pages, uidata,
inlen, &offs, &need_drop); inlen, &offs, &need_drop);
...@@ -433,7 +433,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, ...@@ -433,7 +433,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
if (n != inlen) { if (n != inlen) {
__le32 v = cpu_to_le32(n); __le32 v = cpu_to_le32(n);
memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4); memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
inlen = n; inlen = n;
} }
} }
...@@ -445,7 +445,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, ...@@ -445,7 +445,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
/* out data */ /* out data */
out = pack_sg_list(chan->sg, 0, out = pack_sg_list(chan->sg, 0,
VIRTQUEUE_NUM, req->tc->sdata, req->tc->size); VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
if (out) if (out)
sgs[out_sgs++] = chan->sg; sgs[out_sgs++] = chan->sg;
...@@ -464,7 +464,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, ...@@ -464,7 +464,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
* alloced memory and payload onto the user buffer. * alloced memory and payload onto the user buffer.
*/ */
in = pack_sg_list(chan->sg, out, in = pack_sg_list(chan->sg, out,
VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len); VIRTQUEUE_NUM, req->rc.sdata, in_hdr_len);
if (in) if (in)
sgs[out_sgs + in_sgs++] = chan->sg + out; sgs[out_sgs + in_sgs++] = chan->sg + out;
......
...@@ -141,7 +141,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) ...@@ -141,7 +141,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
struct xen_9pfs_front_priv *priv = NULL; struct xen_9pfs_front_priv *priv = NULL;
RING_IDX cons, prod, masked_cons, masked_prod; RING_IDX cons, prod, masked_cons, masked_prod;
unsigned long flags; unsigned long flags;
u32 size = p9_req->tc->size; u32 size = p9_req->tc.size;
struct xen_9pfs_dataring *ring; struct xen_9pfs_dataring *ring;
int num; int num;
...@@ -154,7 +154,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) ...@@ -154,7 +154,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
if (!priv || priv->client != client) if (!priv || priv->client != client)
return -EINVAL; return -EINVAL;
num = p9_req->tc->tag % priv->num_rings; num = p9_req->tc.tag % priv->num_rings;
ring = &priv->rings[num]; ring = &priv->rings[num];
again: again:
...@@ -176,7 +176,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) ...@@ -176,7 +176,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE); masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE);
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE); masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
xen_9pfs_write_packet(ring->data.out, p9_req->tc->sdata, size, xen_9pfs_write_packet(ring->data.out, p9_req->tc.sdata, size,
&masked_prod, masked_cons, XEN_9PFS_RING_SIZE); &masked_prod, masked_cons, XEN_9PFS_RING_SIZE);
p9_req->status = REQ_STATUS_SENT; p9_req->status = REQ_STATUS_SENT;
...@@ -229,12 +229,12 @@ static void p9_xen_response(struct work_struct *work) ...@@ -229,12 +229,12 @@ static void p9_xen_response(struct work_struct *work)
continue; continue;
} }
memcpy(req->rc, &h, sizeof(h)); memcpy(&req->rc, &h, sizeof(h));
req->rc->offset = 0; req->rc.offset = 0;
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE); masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
/* Then, read the whole packet (including the header) */ /* Then, read the whole packet (including the header) */
xen_9pfs_read_packet(req->rc->sdata, ring->data.in, h.size, xen_9pfs_read_packet(req->rc.sdata, ring->data.in, h.size,
masked_prod, &masked_cons, masked_prod, &masked_cons,
XEN_9PFS_RING_SIZE); XEN_9PFS_RING_SIZE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment