summaryrefslogtreecommitdiffstats
path: root/src/kernel/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/net.c')
-rw-r--r--src/kernel/net.c55
1 files changed, 42 insertions, 13 deletions
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;
}