diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/9p/trans_virtio.c | 17 | ||||
| -rw-r--r-- | net/ceph/msgpool.c | 40 | ||||
| -rw-r--r-- | net/ceph/osd_client.c | 22 |
3 files changed, 58 insertions, 21 deletions
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 175b5135bdcf..e317583fcc73 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -263,7 +263,6 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) | |||
| 263 | { | 263 | { |
| 264 | int in, out, inp, outp; | 264 | int in, out, inp, outp; |
| 265 | struct virtio_chan *chan = client->trans; | 265 | struct virtio_chan *chan = client->trans; |
| 266 | char *rdata = (char *)req->rc+sizeof(struct p9_fcall); | ||
| 267 | unsigned long flags; | 266 | unsigned long flags; |
| 268 | size_t pdata_off = 0; | 267 | size_t pdata_off = 0; |
| 269 | struct trans_rpage_info *rpinfo = NULL; | 268 | struct trans_rpage_info *rpinfo = NULL; |
| @@ -346,7 +345,8 @@ req_retry_pinned: | |||
| 346 | * Arrange in such a way that server places header in the | 345 | * Arrange in such a way that server places header in the |
| 347 | * alloced memory and payload onto the user buffer. | 346 | * alloced memory and payload onto the user buffer. |
| 348 | */ | 347 | */ |
| 349 | inp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, 11); | 348 | inp = pack_sg_list(chan->sg, out, |
| 349 | VIRTQUEUE_NUM, req->rc->sdata, 11); | ||
| 350 | /* | 350 | /* |
| 351 | * Running executables in the filesystem may result in | 351 | * Running executables in the filesystem may result in |
| 352 | * a read request with kernel buffer as opposed to user buffer. | 352 | * a read request with kernel buffer as opposed to user buffer. |
| @@ -366,8 +366,8 @@ req_retry_pinned: | |||
| 366 | } | 366 | } |
| 367 | in += inp; | 367 | in += inp; |
| 368 | } else { | 368 | } else { |
| 369 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, | 369 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, |
| 370 | req->rc->capacity); | 370 | req->rc->sdata, req->rc->capacity); |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc); | 373 | err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc); |
| @@ -592,7 +592,14 @@ static struct p9_trans_module p9_virtio_trans = { | |||
| 592 | .close = p9_virtio_close, | 592 | .close = p9_virtio_close, |
| 593 | .request = p9_virtio_request, | 593 | .request = p9_virtio_request, |
| 594 | .cancel = p9_virtio_cancel, | 594 | .cancel = p9_virtio_cancel, |
| 595 | .maxsize = PAGE_SIZE*VIRTQUEUE_NUM, | 595 | |
| 596 | /* | ||
| 597 | * We leave one entry for input and one entry for response | ||
| 598 | * headers. We also skip one more entry to accomodate, address | ||
| 599 | * that are not at page boundary, that can result in an extra | ||
| 600 | * page in zero copy. | ||
| 601 | */ | ||
| 602 | .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3), | ||
| 596 | .pref = P9_TRANS_PREF_PAYLOAD_SEP, | 603 | .pref = P9_TRANS_PREF_PAYLOAD_SEP, |
| 597 | .def = 0, | 604 | .def = 0, |
| 598 | .owner = THIS_MODULE, | 605 | .owner = THIS_MODULE, |
diff --git a/net/ceph/msgpool.c b/net/ceph/msgpool.c index d5f2d97ac05c..1f4cb30a42c5 100644 --- a/net/ceph/msgpool.c +++ b/net/ceph/msgpool.c | |||
| @@ -7,27 +7,37 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/ceph/msgpool.h> | 8 | #include <linux/ceph/msgpool.h> |
| 9 | 9 | ||
| 10 | static void *alloc_fn(gfp_t gfp_mask, void *arg) | 10 | static void *msgpool_alloc(gfp_t gfp_mask, void *arg) |
| 11 | { | 11 | { |
| 12 | struct ceph_msgpool *pool = arg; | 12 | struct ceph_msgpool *pool = arg; |
| 13 | void *p; | 13 | struct ceph_msg *msg; |
| 14 | 14 | ||
| 15 | p = ceph_msg_new(0, pool->front_len, gfp_mask); | 15 | msg = ceph_msg_new(0, pool->front_len, gfp_mask); |
| 16 | if (!p) | 16 | if (!msg) { |
| 17 | pr_err("msgpool %s alloc failed\n", pool->name); | 17 | dout("msgpool_alloc %s failed\n", pool->name); |
| 18 | return p; | 18 | } else { |
| 19 | dout("msgpool_alloc %s %p\n", pool->name, msg); | ||
| 20 | msg->pool = pool; | ||
| 21 | } | ||
| 22 | return msg; | ||
| 19 | } | 23 | } |
| 20 | 24 | ||
| 21 | static void free_fn(void *element, void *arg) | 25 | static void msgpool_free(void *element, void *arg) |
| 22 | { | 26 | { |
| 23 | ceph_msg_put(element); | 27 | struct ceph_msgpool *pool = arg; |
| 28 | struct ceph_msg *msg = element; | ||
| 29 | |||
| 30 | dout("msgpool_release %s %p\n", pool->name, msg); | ||
| 31 | msg->pool = NULL; | ||
| 32 | ceph_msg_put(msg); | ||
| 24 | } | 33 | } |
| 25 | 34 | ||
| 26 | int ceph_msgpool_init(struct ceph_msgpool *pool, | 35 | int ceph_msgpool_init(struct ceph_msgpool *pool, |
| 27 | int front_len, int size, bool blocking, const char *name) | 36 | int front_len, int size, bool blocking, const char *name) |
| 28 | { | 37 | { |
| 38 | dout("msgpool %s init\n", name); | ||
| 29 | pool->front_len = front_len; | 39 | pool->front_len = front_len; |
| 30 | pool->pool = mempool_create(size, alloc_fn, free_fn, pool); | 40 | pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool); |
| 31 | if (!pool->pool) | 41 | if (!pool->pool) |
| 32 | return -ENOMEM; | 42 | return -ENOMEM; |
| 33 | pool->name = name; | 43 | pool->name = name; |
| @@ -36,14 +46,17 @@ int ceph_msgpool_init(struct ceph_msgpool *pool, | |||
| 36 | 46 | ||
| 37 | void ceph_msgpool_destroy(struct ceph_msgpool *pool) | 47 | void ceph_msgpool_destroy(struct ceph_msgpool *pool) |
| 38 | { | 48 | { |
| 49 | dout("msgpool %s destroy\n", pool->name); | ||
| 39 | mempool_destroy(pool->pool); | 50 | mempool_destroy(pool->pool); |
| 40 | } | 51 | } |
| 41 | 52 | ||
| 42 | struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, | 53 | struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, |
| 43 | int front_len) | 54 | int front_len) |
| 44 | { | 55 | { |
| 56 | struct ceph_msg *msg; | ||
| 57 | |||
| 45 | if (front_len > pool->front_len) { | 58 | if (front_len > pool->front_len) { |
| 46 | pr_err("msgpool_get pool %s need front %d, pool size is %d\n", | 59 | dout("msgpool_get %s need front %d, pool size is %d\n", |
| 47 | pool->name, front_len, pool->front_len); | 60 | pool->name, front_len, pool->front_len); |
| 48 | WARN_ON(1); | 61 | WARN_ON(1); |
| 49 | 62 | ||
| @@ -51,14 +64,19 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, | |||
| 51 | return ceph_msg_new(0, front_len, GFP_NOFS); | 64 | return ceph_msg_new(0, front_len, GFP_NOFS); |
| 52 | } | 65 | } |
| 53 | 66 | ||
| 54 | return mempool_alloc(pool->pool, GFP_NOFS); | 67 | msg = mempool_alloc(pool->pool, GFP_NOFS); |
| 68 | dout("msgpool_get %s %p\n", pool->name, msg); | ||
| 69 | return msg; | ||
| 55 | } | 70 | } |
| 56 | 71 | ||
| 57 | void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) | 72 | void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) |
| 58 | { | 73 | { |
| 74 | dout("msgpool_put %s %p\n", pool->name, msg); | ||
| 75 | |||
| 59 | /* reset msg front_len; user may have changed it */ | 76 | /* reset msg front_len; user may have changed it */ |
| 60 | msg->front.iov_len = pool->front_len; | 77 | msg->front.iov_len = pool->front_len; |
| 61 | msg->hdr.front_len = cpu_to_le32(pool->front_len); | 78 | msg->hdr.front_len = cpu_to_le32(pool->front_len); |
| 62 | 79 | ||
| 63 | kref_init(&msg->kref); /* retake single ref */ | 80 | kref_init(&msg->kref); /* retake single ref */ |
| 81 | mempool_free(msg, pool->pool); | ||
| 64 | } | 82 | } |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index ce310eee708d..16836a7df7a6 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
| @@ -685,6 +685,18 @@ static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) | |||
| 685 | put_osd(osd); | 685 | put_osd(osd); |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | static void remove_all_osds(struct ceph_osd_client *osdc) | ||
| 689 | { | ||
| 690 | dout("__remove_old_osds %p\n", osdc); | ||
| 691 | mutex_lock(&osdc->request_mutex); | ||
| 692 | while (!RB_EMPTY_ROOT(&osdc->osds)) { | ||
| 693 | struct ceph_osd *osd = rb_entry(rb_first(&osdc->osds), | ||
| 694 | struct ceph_osd, o_node); | ||
| 695 | __remove_osd(osdc, osd); | ||
| 696 | } | ||
| 697 | mutex_unlock(&osdc->request_mutex); | ||
| 698 | } | ||
| 699 | |||
| 688 | static void __move_osd_to_lru(struct ceph_osd_client *osdc, | 700 | static void __move_osd_to_lru(struct ceph_osd_client *osdc, |
| 689 | struct ceph_osd *osd) | 701 | struct ceph_osd *osd) |
| 690 | { | 702 | { |
| @@ -701,14 +713,14 @@ static void __remove_osd_from_lru(struct ceph_osd *osd) | |||
| 701 | list_del_init(&osd->o_osd_lru); | 713 | list_del_init(&osd->o_osd_lru); |
| 702 | } | 714 | } |
| 703 | 715 | ||
| 704 | static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all) | 716 | static void remove_old_osds(struct ceph_osd_client *osdc) |
| 705 | { | 717 | { |
| 706 | struct ceph_osd *osd, *nosd; | 718 | struct ceph_osd *osd, *nosd; |
| 707 | 719 | ||
| 708 | dout("__remove_old_osds %p\n", osdc); | 720 | dout("__remove_old_osds %p\n", osdc); |
| 709 | mutex_lock(&osdc->request_mutex); | 721 | mutex_lock(&osdc->request_mutex); |
| 710 | list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { | 722 | list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { |
| 711 | if (!remove_all && time_before(jiffies, osd->lru_ttl)) | 723 | if (time_before(jiffies, osd->lru_ttl)) |
| 712 | break; | 724 | break; |
| 713 | __remove_osd(osdc, osd); | 725 | __remove_osd(osdc, osd); |
| 714 | } | 726 | } |
| @@ -751,6 +763,7 @@ static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new) | |||
| 751 | struct rb_node *parent = NULL; | 763 | struct rb_node *parent = NULL; |
| 752 | struct ceph_osd *osd = NULL; | 764 | struct ceph_osd *osd = NULL; |
| 753 | 765 | ||
| 766 | dout("__insert_osd %p osd%d\n", new, new->o_osd); | ||
| 754 | while (*p) { | 767 | while (*p) { |
| 755 | parent = *p; | 768 | parent = *p; |
| 756 | osd = rb_entry(parent, struct ceph_osd, o_node); | 769 | osd = rb_entry(parent, struct ceph_osd, o_node); |
| @@ -1144,7 +1157,7 @@ static void handle_osds_timeout(struct work_struct *work) | |||
| 1144 | 1157 | ||
| 1145 | dout("osds timeout\n"); | 1158 | dout("osds timeout\n"); |
| 1146 | down_read(&osdc->map_sem); | 1159 | down_read(&osdc->map_sem); |
| 1147 | remove_old_osds(osdc, 0); | 1160 | remove_old_osds(osdc); |
| 1148 | up_read(&osdc->map_sem); | 1161 | up_read(&osdc->map_sem); |
| 1149 | 1162 | ||
| 1150 | schedule_delayed_work(&osdc->osds_timeout_work, | 1163 | schedule_delayed_work(&osdc->osds_timeout_work, |
| @@ -1862,8 +1875,7 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc) | |||
| 1862 | ceph_osdmap_destroy(osdc->osdmap); | 1875 | ceph_osdmap_destroy(osdc->osdmap); |
| 1863 | osdc->osdmap = NULL; | 1876 | osdc->osdmap = NULL; |
| 1864 | } | 1877 | } |
| 1865 | remove_old_osds(osdc, 1); | 1878 | remove_all_osds(osdc); |
| 1866 | WARN_ON(!RB_EMPTY_ROOT(&osdc->osds)); | ||
| 1867 | mempool_destroy(osdc->req_mempool); | 1879 | mempool_destroy(osdc->req_mempool); |
| 1868 | ceph_msgpool_destroy(&osdc->msgpool_op); | 1880 | ceph_msgpool_destroy(&osdc->msgpool_op); |
| 1869 | ceph_msgpool_destroy(&osdc->msgpool_op_reply); | 1881 | ceph_msgpool_destroy(&osdc->msgpool_op_reply); |
