diff options
-rw-r--r-- | src/kernel/core.c | 5 | ||||
-rw-r--r-- | src/kernel/mq.c | 24 | ||||
-rw-r--r-- | src/kernel/mq.h | 2 | ||||
-rw-r--r-- | src/kernel/net-txrx.c | 8 | ||||
-rw-r--r-- | src/kernel/net.c | 28 |
5 files changed, 53 insertions, 14 deletions
diff --git a/src/kernel/core.c b/src/kernel/core.c index 6e5b82b..8582b5c 100644 --- a/src/kernel/core.c +++ b/src/kernel/core.c @@ -250,6 +250,7 @@ int dnbd3_add_device(struct dnbd3_device *dev, int minor) for (i = 0; i < NUMBER_CONNECTIONS; i++) { dev->socks[i].device = dev; dev->socks[i].sock_nr = i; + mutex_init(&dev->socks[i]->tx_lock); } disk = alloc_disk(1); @@ -403,6 +404,7 @@ static void dnbd3_dev_remove(struct dnbd3_device *dev) { struct gendisk *disk = dev->disk; struct request_queue *q; + int i; dnbd3_net_disconnect(dev); @@ -419,6 +421,9 @@ static void dnbd3_dev_remove(struct dnbd3_device *dev) dev->imgname = NULL; } mutex_destroy(&dev->device_lock); + for (i = 0; i < NUMBER_CONNECTIONS; i++) { + mutex_destroy(&dev->socks[i]->tx_lock); + } } /** diff --git a/src/kernel/mq.c b/src/kernel/mq.c index 94f06f2..60673b0 100644 --- a/src/kernel/mq.c +++ b/src/kernel/mq.c @@ -28,9 +28,9 @@ * dnbd3_busy_iter - iterator for blk_mq_tagset_busy_iter * @req: the request * @priv: the passed argument from blk_mq_tagset_busy_iter - * @arg2: unknown + * @arg: unknown */ -static void dnbd3_busy_iter(struct request *req, void *priv, bool arg2) +static void dnbd3_busy_iter(struct request *req, void *priv, bool arg) { struct dnbd3_cmd *cmd = blk_mq_rq_to_pdu(req); unsigned long *busy = (unsigned long *) priv; @@ -70,6 +70,26 @@ unsigned long dnbd3_is_mq_busy(struct dnbd3_device *dev) return busy; } +static void dnbd3_busy_iter_requeue(struct request *req, void *priv, bool arg) +{ + struct dnbd3_sock *sock = priv; + struct dnbd3_cmd *cmd = blk_mq_rq_to_pdu(req); + if (!mutex_trylock(&cmd->lock)) { + /* request is in sending, so we will not requeue */ + return; + } + debug_sock(sock, "requeue busy request %p", req); + dnbd3_requeue_cmd(cmd); + mutex_unlock(&cmd->lock); +} + +void dndb3_reque_busy_requests(struct dnbd3_sock *sock) +{ + struct blk_mq_tag_set *set = &sock->device->tag_set; + blk_mq_tagset_busy_iter(set, dnbd3_busy_iter_requeue, sock); +} + + /** * dnbd3_requeue_cmd - requeue a command once diff --git a/src/kernel/mq.h b/src/kernel/mq.h index 821fd91..94b09f9 100644 --- a/src/kernel/mq.h +++ b/src/kernel/mq.h @@ -31,6 +31,8 @@ */ unsigned long dnbd3_is_mq_busy(struct dnbd3_device *dev); +void dndb3_reque_busy_requests(struct dnbd3_sock *sock); + /** * dnbd3_requeue_cmd - requeue a command once * @cmd: the command to requeue diff --git a/src/kernel/net-txrx.c b/src/kernel/net-txrx.c index d905ce9..7226a3e 100644 --- a/src/kernel/net-txrx.c +++ b/src/kernel/net-txrx.c @@ -183,6 +183,8 @@ error: * dnbd3_send_request_cmd - send a dndb3 cmd * @sock: the socket where the request is send * @dnbd3_cmd: the dnbd3 cmd to send + * + * the tx_lock of the socket must be held */ int dnbd3_send_request_cmd(struct dnbd3_sock *sock, uint16_t dnbd3_cmd) { @@ -211,10 +213,12 @@ int dnbd3_send_request_cmd(struct dnbd3_sock *sock, uint16_t dnbd3_cmd) goto error; } - mutex_lock(&sock->tx_lock); + if (unlikely(!sock->sock)) { + result = -EIO; + goto error; + } sock->pending = req; result = dnbd3_send_request(sock, req, NULL); - mutex_unlock(&sock->tx_lock); error: if (req) { diff --git a/src/kernel/net.c b/src/kernel/net.c index cb4e76c..67f9c74 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -75,14 +75,11 @@ static void dnbd3_timer(struct timer_list *arg) } } - if (!busy) { - /* start after 4 seconds */ - if (dev->timer_count % TIMER_INTERVAL_PROBE_NORMAL == 4) { - queue_work(dnbd3_wq, &dev->discovery_worker); - } - - + /* start after 2 seconds */ + if (dev->timer_count % TIMER_INTERVAL_PROBE_NORMAL == 2) { + queue_work(dnbd3_wq, &dev->discovery_worker); } + dev->timer_count++; dev->timer.expires = jiffies + HZ; add_timer(&dev->timer); @@ -185,7 +182,9 @@ static void dnbd3_keepalive_worker(struct work_struct *work) sock = container_of(work, struct dnbd3_sock, keepalive_worker); if (sock->server != NULL && !sock->panic) { debug_sock(sock, "starting keepalive worker"); + mutex_lock(&sock->tx_lock); dnbd3_send_request_cmd(sock, CMD_KEEPALIVE); + mutex_unlock(&sock->tx_lock); } } @@ -237,6 +236,7 @@ static int dnbd3_panic_connect(struct dnbd3_device *dev) { struct dnbd3_server *working = NULL; int i; + debug_dev(dev, "panic connect"); for (i = 0; i < NUMBER_CONNECTIONS; i++) { if (dnbd3_is_sock_alive(dev->socks[i])) { working = dev->socks[i].server; @@ -273,7 +273,7 @@ static int dnbd3_adjust_connections(struct dnbd3_device *dev) { int i, j, fallback; struct dnbd3_server *plan[NUMBER_CONNECTIONS]; struct dnbd3_server **servers = dnbd3_sort_server(dev); -//TODO don't connect to anyting bader then rtt unknown + if (servers && servers[0]->host.type != 0) { plan[0] = servers[0]; fallback = 0; @@ -300,6 +300,8 @@ static int dnbd3_adjust_connections(struct dnbd3_device *dev) { i, plan[i]->avg_rtt); } kfree(servers); + //TODO connection plan sortieren + for (i = 0; i < NUMBER_CONNECTIONS; i++) { if (plan[i] != dev->socks[i].server) { if (dnbd3_is_sock_alive(dev->socks[i])) { @@ -677,13 +679,13 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock, result = -EIO; goto error; } - mutex_unlock(&sock->tx_lock); sock->panic = false; if (!sock->sock) { error_sock(sock, "socket is not connected"); server->failures++; + mutex_unlock(&sock->tx_lock); result = -EIO; goto error; } @@ -691,15 +693,17 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock, result = dnbd3_send_request_cmd(sock, CMD_SELECT_IMAGE); if (result <= 0) { - error_sock(sock, "connection to image %s failed", dev->imgname); + mutex_unlock(&sock->tx_lock); result = -EIO; goto error; } + result = dnbd3_receive_cmd(sock, &reply); if (result <= 0) { error_sock(sock, "receive cmd to image %s failed", dev->imgname); + mutex_unlock(&sock->tx_lock); result = -EIO; goto error; } @@ -707,6 +711,7 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock, || reply.size < 4) { error_sock(sock, "receive select image wrong header %s", dev->imgname); + mutex_unlock(&sock->tx_lock); result = -EIO; goto error; } @@ -714,6 +719,7 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock, if (result <= 0) { error_sock(sock, "receive cmd select image %s failed", dev->imgname); + mutex_unlock(&sock->tx_lock); result = -EIO; goto error; } @@ -730,6 +736,7 @@ static int dnbd3_socket_connect(struct dnbd3_sock *sock, if (dnbd3_send_request_cmd(sock, CMD_GET_SERVERS) <= 0) { error_sock(sock, "failed to get servers in discovery"); } + mutex_unlock(&sock->tx_lock); return 0; error: @@ -770,6 +777,7 @@ static int dnbd3_socket_disconnect(struct dnbd3_sock *sock) */ if (sock->sock) { kernel_sock_shutdown(sock->sock, SHUT_RDWR); + dndb3_reque_busy_requests(sock); } mutex_unlock(&sock->tx_lock); mutex_destroy(&sock->tx_lock); |