diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-15 20:07:58 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-15 20:07:58 -0500 |
| commit | 27cb8823e26cecd03c00d82dfb501f6c144b3445 (patch) | |
| tree | 7f0db862866d342e8d80e8452eb651c6c4dbf3b6 | |
| parent | 988adfdffdd43cfd841df734664727993076d7cb (diff) | |
| parent | b1b9891441fa33fd0d49b5cb3aa7f04bca1cc1db (diff) | |
Merge tag 'rpmsg-3.19-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg
Pull rpmsg update from Ohad Ben-Cohen:
"A single patch from Suman Anna which makes rpmsg use less buffers when
small vrings are being used"
* tag 'rpmsg-3.19-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg:
rpmsg: use less buffers when vrings are small
| -rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index b6135d4d54eb..92f6af6da699 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | * @svq: tx virtqueue | 41 | * @svq: tx virtqueue |
| 42 | * @rbufs: kernel address of rx buffers | 42 | * @rbufs: kernel address of rx buffers |
| 43 | * @sbufs: kernel address of tx buffers | 43 | * @sbufs: kernel address of tx buffers |
| 44 | * @num_bufs: total number of buffers for rx and tx | ||
| 44 | * @last_sbuf: index of last tx buffer used | 45 | * @last_sbuf: index of last tx buffer used |
| 45 | * @bufs_dma: dma base addr of the buffers | 46 | * @bufs_dma: dma base addr of the buffers |
| 46 | * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders. | 47 | * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders. |
| @@ -60,6 +61,7 @@ struct virtproc_info { | |||
| 60 | struct virtio_device *vdev; | 61 | struct virtio_device *vdev; |
| 61 | struct virtqueue *rvq, *svq; | 62 | struct virtqueue *rvq, *svq; |
| 62 | void *rbufs, *sbufs; | 63 | void *rbufs, *sbufs; |
| 64 | unsigned int num_bufs; | ||
| 63 | int last_sbuf; | 65 | int last_sbuf; |
| 64 | dma_addr_t bufs_dma; | 66 | dma_addr_t bufs_dma; |
| 65 | struct mutex tx_lock; | 67 | struct mutex tx_lock; |
| @@ -86,13 +88,14 @@ struct rpmsg_channel_info { | |||
| 86 | #define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) | 88 | #define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv) |
| 87 | 89 | ||
| 88 | /* | 90 | /* |
| 89 | * We're allocating 512 buffers of 512 bytes for communications, and then | 91 | * We're allocating buffers of 512 bytes each for communications. The |
| 90 | * using the first 256 buffers for RX, and the last 256 buffers for TX. | 92 | * number of buffers will be computed from the number of buffers supported |
| 93 | * by the vring, upto a maximum of 512 buffers (256 in each direction). | ||
| 91 | * | 94 | * |
| 92 | * Each buffer will have 16 bytes for the msg header and 496 bytes for | 95 | * Each buffer will have 16 bytes for the msg header and 496 bytes for |
| 93 | * the payload. | 96 | * the payload. |
| 94 | * | 97 | * |
| 95 | * This will require a total space of 256KB for the buffers. | 98 | * This will utilize a maximum total space of 256KB for the buffers. |
| 96 | * | 99 | * |
| 97 | * We might also want to add support for user-provided buffers in time. | 100 | * We might also want to add support for user-provided buffers in time. |
| 98 | * This will allow bigger buffer size flexibility, and can also be used | 101 | * This will allow bigger buffer size flexibility, and can also be used |
| @@ -102,9 +105,8 @@ struct rpmsg_channel_info { | |||
| 102 | * can change this without changing anything in the firmware of the remote | 105 | * can change this without changing anything in the firmware of the remote |
| 103 | * processor. | 106 | * processor. |
| 104 | */ | 107 | */ |
| 105 | #define RPMSG_NUM_BUFS (512) | 108 | #define MAX_RPMSG_NUM_BUFS (512) |
| 106 | #define RPMSG_BUF_SIZE (512) | 109 | #define RPMSG_BUF_SIZE (512) |
| 107 | #define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE) | ||
| 108 | 110 | ||
| 109 | /* | 111 | /* |
| 110 | * Local addresses are dynamically allocated on-demand. | 112 | * Local addresses are dynamically allocated on-demand. |
| @@ -579,7 +581,7 @@ static void *get_a_tx_buf(struct virtproc_info *vrp) | |||
| 579 | * either pick the next unused tx buffer | 581 | * either pick the next unused tx buffer |
| 580 | * (half of our buffers are used for sending messages) | 582 | * (half of our buffers are used for sending messages) |
| 581 | */ | 583 | */ |
| 582 | if (vrp->last_sbuf < RPMSG_NUM_BUFS / 2) | 584 | if (vrp->last_sbuf < vrp->num_bufs / 2) |
| 583 | ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++; | 585 | ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++; |
| 584 | /* or recycle a used one */ | 586 | /* or recycle a used one */ |
| 585 | else | 587 | else |
| @@ -948,6 +950,7 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
| 948 | struct virtproc_info *vrp; | 950 | struct virtproc_info *vrp; |
| 949 | void *bufs_va; | 951 | void *bufs_va; |
| 950 | int err = 0, i; | 952 | int err = 0, i; |
| 953 | size_t total_buf_space; | ||
| 951 | 954 | ||
| 952 | vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); | 955 | vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); |
| 953 | if (!vrp) | 956 | if (!vrp) |
| @@ -968,10 +971,22 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
| 968 | vrp->rvq = vqs[0]; | 971 | vrp->rvq = vqs[0]; |
| 969 | vrp->svq = vqs[1]; | 972 | vrp->svq = vqs[1]; |
| 970 | 973 | ||
| 974 | /* we expect symmetric tx/rx vrings */ | ||
| 975 | WARN_ON(virtqueue_get_vring_size(vrp->rvq) != | ||
| 976 | virtqueue_get_vring_size(vrp->svq)); | ||
| 977 | |||
| 978 | /* we need less buffers if vrings are small */ | ||
| 979 | if (virtqueue_get_vring_size(vrp->rvq) < MAX_RPMSG_NUM_BUFS / 2) | ||
| 980 | vrp->num_bufs = virtqueue_get_vring_size(vrp->rvq) * 2; | ||
| 981 | else | ||
| 982 | vrp->num_bufs = MAX_RPMSG_NUM_BUFS; | ||
| 983 | |||
| 984 | total_buf_space = vrp->num_bufs * RPMSG_BUF_SIZE; | ||
| 985 | |||
| 971 | /* allocate coherent memory for the buffers */ | 986 | /* allocate coherent memory for the buffers */ |
| 972 | bufs_va = dma_alloc_coherent(vdev->dev.parent->parent, | 987 | bufs_va = dma_alloc_coherent(vdev->dev.parent->parent, |
| 973 | RPMSG_TOTAL_BUF_SPACE, | 988 | total_buf_space, &vrp->bufs_dma, |
| 974 | &vrp->bufs_dma, GFP_KERNEL); | 989 | GFP_KERNEL); |
| 975 | if (!bufs_va) { | 990 | if (!bufs_va) { |
| 976 | err = -ENOMEM; | 991 | err = -ENOMEM; |
| 977 | goto vqs_del; | 992 | goto vqs_del; |
| @@ -984,10 +999,10 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
| 984 | vrp->rbufs = bufs_va; | 999 | vrp->rbufs = bufs_va; |
| 985 | 1000 | ||
| 986 | /* and half is dedicated for TX */ | 1001 | /* and half is dedicated for TX */ |
| 987 | vrp->sbufs = bufs_va + RPMSG_TOTAL_BUF_SPACE / 2; | 1002 | vrp->sbufs = bufs_va + total_buf_space / 2; |
| 988 | 1003 | ||
| 989 | /* set up the receive buffers */ | 1004 | /* set up the receive buffers */ |
| 990 | for (i = 0; i < RPMSG_NUM_BUFS / 2; i++) { | 1005 | for (i = 0; i < vrp->num_bufs / 2; i++) { |
| 991 | struct scatterlist sg; | 1006 | struct scatterlist sg; |
| 992 | void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE; | 1007 | void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE; |
| 993 | 1008 | ||
| @@ -1023,8 +1038,8 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
| 1023 | return 0; | 1038 | return 0; |
| 1024 | 1039 | ||
| 1025 | free_coherent: | 1040 | free_coherent: |
| 1026 | dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, | 1041 | dma_free_coherent(vdev->dev.parent->parent, total_buf_space, |
| 1027 | bufs_va, vrp->bufs_dma); | 1042 | bufs_va, vrp->bufs_dma); |
| 1028 | vqs_del: | 1043 | vqs_del: |
| 1029 | vdev->config->del_vqs(vrp->vdev); | 1044 | vdev->config->del_vqs(vrp->vdev); |
| 1030 | free_vrp: | 1045 | free_vrp: |
| @@ -1042,6 +1057,7 @@ static int rpmsg_remove_device(struct device *dev, void *data) | |||
| 1042 | static void rpmsg_remove(struct virtio_device *vdev) | 1057 | static void rpmsg_remove(struct virtio_device *vdev) |
| 1043 | { | 1058 | { |
| 1044 | struct virtproc_info *vrp = vdev->priv; | 1059 | struct virtproc_info *vrp = vdev->priv; |
| 1060 | size_t total_buf_space = vrp->num_bufs * RPMSG_BUF_SIZE; | ||
| 1045 | int ret; | 1061 | int ret; |
| 1046 | 1062 | ||
| 1047 | vdev->config->reset(vdev); | 1063 | vdev->config->reset(vdev); |
| @@ -1057,8 +1073,8 @@ static void rpmsg_remove(struct virtio_device *vdev) | |||
| 1057 | 1073 | ||
| 1058 | vdev->config->del_vqs(vrp->vdev); | 1074 | vdev->config->del_vqs(vrp->vdev); |
| 1059 | 1075 | ||
| 1060 | dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, | 1076 | dma_free_coherent(vdev->dev.parent->parent, total_buf_space, |
| 1061 | vrp->rbufs, vrp->bufs_dma); | 1077 | vrp->rbufs, vrp->bufs_dma); |
| 1062 | 1078 | ||
| 1063 | kfree(vrp); | 1079 | kfree(vrp); |
| 1064 | } | 1080 | } |
