From dc8fcb26807c734cf79d8a82d2ba655f226ad135 Mon Sep 17 00:00:00 2001 From: Frederic Robra Date: Wed, 4 Sep 2019 15:10:03 +0200 Subject: prepared kernel module to have configurable number of connections --- src/kernel/net.c | 55 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 13 deletions(-) (limited to 'src/kernel/net.c') diff --git a/src/kernel/net.c b/src/kernel/net.c index f4665bf..061deb1 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -73,7 +73,7 @@ static void dnbd3_timer(struct timer_list *arg) busy = dnbd3_is_mq_busy(dev); if (dev->timer_count % TIMER_INTERVAL_KEEPALIVE_PACKET == 0) { - for (i = 0; i < NUMBER_CONNECTIONS; i++) { + for (i = 0; i < dev->number_connections; i++) { if (!test_bit(i, &busy) && dnbd3_is_sock_alive(dev->socks[i])) { queue_work(dnbd3_wq, &dev->socks[i].keepalive_worker); } @@ -294,7 +294,7 @@ static int dnbd3_compare_plan(const void *lhs, const void *rhs) static void dnbd3_lock_all_socks(struct dnbd3_device *dev) { int i; - for (i = 0; i < NUMBER_CONNECTIONS; i++) { + for (i = 0; i < dev->number_connections; i++) { mutex_lock(&dev->socks[i].tx_lock); } } @@ -302,7 +302,7 @@ static void dnbd3_lock_all_socks(struct dnbd3_device *dev) static void dnbd3_unlock_all_socks(struct dnbd3_device *dev) { int i; - for (i = 0; i < NUMBER_CONNECTIONS; i++) { + for (i = 0; i < dev->number_connections; i++) { mutex_unlock(&dev->socks[i].tx_lock); } } @@ -312,7 +312,7 @@ static void dnbd3_print_conenction_plan(struct dnbd3_device *dev, { int i; debug_dev(dev, "connection plan:"); - for (i = 0; i < NUMBER_CONNECTIONS; i++) { + for (i = 0; i < dev->number_connections; i++) { debug_server(dev, plan[i], "server %d with avg rtt %llu:", i, plan[i]->avg_rtt); } @@ -328,14 +328,20 @@ static void dnbd3_print_conenction_plan(struct dnbd3_device *dev, */ static int dnbd3_adjust_connections(struct dnbd3_device *dev) { int i, j, fallback, alive; - struct dnbd3_server *plan[NUMBER_CONNECTIONS]; + struct dnbd3_server **plan; struct dnbd3_server **servers = dnbd3_sort_server(dev); + plan = kmalloc(sizeof(struct dnbd3_server *) * dev->number_connections, + GFP_KERNEL); + if (!plan) { + error_dev(dev, "kmalloc failed"); + } + if (servers && servers[0]->host.type != 0) { plan[0] = servers[0]; fallback = 0; j = 1; - for (i = 1; i < NUMBER_CONNECTIONS; i++) { + for (i = 1; i < dev->number_connections; i++) { if (servers[j]->host.type != 0 && servers[j]->avg_rtt < RTT_UNKNOWN) { if (RTT_FACTOR(plan[i - 1]->avg_rtt) > @@ -353,13 +359,13 @@ static int dnbd3_adjust_connections(struct dnbd3_device *dev) { } kfree(servers); - sort(plan, NUMBER_CONNECTIONS, sizeof(struct dnbd3_server *), + sort(plan, dev->number_connections, sizeof(struct dnbd3_server *), &dnbd3_compare_plan, NULL); dnbd3_print_conenction_plan(dev, plan); dnbd3_lock_all_socks(dev); alive = 0; - for (i = 0; i < NUMBER_CONNECTIONS; i++) { + for (i = 0; i < dev->number_connections; i++) { if (plan[i] != dev->socks[i].server || !dnbd3_is_sock_alive(dev->socks[i])) { @@ -405,7 +411,7 @@ static void dnbd3_panic_worker(struct work_struct *work) int i; int sock_alive = 0; dev = container_of(work, struct dnbd3_device, panic_worker); - for (i = 0; i < NUMBER_CONNECTIONS; i++) { + for (i = 0; i < dev->number_connections; i++) { if (!dnbd3_is_sock_alive(dev->socks[i]) || dev->socks[i].server->failures > 1000) { panic = true; @@ -445,7 +451,7 @@ static int dnbd3_meassure_rtt(struct dnbd3_device *dev, int result; uint64_t rtt = RTT_UNREACHABLE; struct dnbd3_sock sock = { - .sock_nr = NUMBER_CONNECTIONS, + .sock_nr = dev->number_connections, .sock = NULL, .device = dev, .server = server @@ -505,11 +511,13 @@ static int dnbd3_meassure_rtt(struct dnbd3_device *dev, rtt = (uint64_t)((end.tv_sec - start.tv_sec) * 1000000ull + (end.tv_usec - start.tv_usec)); - debug_sock(&sock, "new rrt is %llu", rtt); error: sock.server->rtts[dev->discovery_count % 4] = rtt; sock.server->avg_rtt = dnbd3_average_rtt(sock.server); + + debug_sock(&sock, "meassured rrt: %llu; avg_rtt: %llu", rtt, + sock.server->avg_rtt); if (result <= 0) { server->failures++; } @@ -846,8 +854,22 @@ static int dnbd3_socket_disconnect(struct dnbd3_sock *sock) */ int dnbd3_net_connect(struct dnbd3_device *dev) { - int result; + int i, result; debug_dev(dev, "connecting to server"); + dev->socks = kmalloc(sizeof(struct dnbd3_sock) * + dev->number_connections, GFP_KERNEL); + if (!dev->socks) { + error_dev(dev, "kmalloc failed"); + } + memset(dev->socks, 0, sizeof(struct dnbd3_sock) * + dev->number_connections); + for (i = 0; i < dev->number_connections; i++) { + dev->socks[i].device = dev; + dev->socks[i].sock_nr = i; + mutex_init(&dev->socks[i].tx_lock); + } + debug_dev(dev, "set nr hw queues to %d", dev->number_connections); + blk_mq_update_nr_hw_queues(&dev->tag_set, dev->number_connections); if (dev->alt_servers[0].host.type == 0) { return -ENONET; @@ -888,19 +910,26 @@ int dnbd3_net_disconnect(struct dnbd3_device *dev) int i; int result = 0; + if (!dev->socks) { + info_dev(dev, "not connected"); + } + del_timer_sync(&dev->timer); /* be sure it does not recover while disconnecting */ cancel_work_sync(&dev->discovery_worker); cancel_work_sync(&dev->panic_worker); - for (i = 0; i < NUMBER_CONNECTIONS; i++) { + for (i = 0; i < dev->number_connections; i++) { if (dev->socks[i].sock) { mutex_lock(&dev->socks[i].tx_lock); if (dnbd3_socket_disconnect(&dev->socks[i])) { result = -EIO; } mutex_unlock(&dev->socks[i].tx_lock); + mutex_destroy(&dev->socks[i].tx_lock); } } + kfree(dev->socks); + dev->socks = NULL; dev->connected = false; return result; } -- cgit v1.2.3-55-g7522