From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dan.gora@gmail.com>
Received: from mail-oi0-f65.google.com (mail-oi0-f65.google.com
 [209.85.218.65]) by dpdk.org (Postfix) with ESMTP id 7402A1B532
 for <dev@dpdk.org>; Fri, 29 Jun 2018 03:55:52 +0200 (CEST)
Received: by mail-oi0-f65.google.com with SMTP id k81-v6so7044861oib.4
 for <dev@dpdk.org>; Thu, 28 Jun 2018 18:55:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=sender:from:to:cc:subject:date:message-id:in-reply-to:references;
 bh=fGC1/toUFvY8asYAO6HL+f7p7INZeOaqNCTBQH8reiw=;
 b=WBLo+UUeLp65fwHeCzu+NwE3buAJJzDkHhVFJLqE57AMDX3OXutBmsxJa9drUsHLNv
 530csrwr81LfDeodVP2ryXaHHb/X+vrGhOXfT5gqU2RUEZuMU5JUSOFasIF8aAvRI+Ef
 Xa28BXT1J1GO6nr1HcaHbSejHDmFOKCTHzEz++Y1DVY5ys6TPwFNR3R3ZcqyR5iYb5t+
 Ilrsyiit5dH/01sXgNb8nHBPcJ2/Oxr+5aDC0oFK0NNbpnJ6O59vkFzqU1Usm2nWlrXH
 lWujXR09zm9olBqgNlQMwYwA3EIWP3euB8KwYsjlYH/vz10X0y20Yn9Ov91/kJjG8xX0
 8Z8A==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:sender:from:to:cc:subject:date:message-id
 :in-reply-to:references;
 bh=fGC1/toUFvY8asYAO6HL+f7p7INZeOaqNCTBQH8reiw=;
 b=VlfCtBlXtscNvOmDKFvWuvL9tw5w2CPUJIzVw8K1mjfEdL2v3gW7R/cghVNCfYEynv
 B4giW1sBAx8xwov9uMh/iqwhr35z/yWe6h/5n0M0y/LMQottyTHGbqJnTuhibckZyNj/
 M3YiDVRv0r3uMVzq2rrFQ3vVxsEMZ6/kEMuRJDBgDAMu5aJ+QBMAeswa8evlAGgoaXw6
 yEQ/97ZSUc4mLZXMWfxUKc6CLyKyb82jYNISqTXec0dm5b8qQSKlM0c4wZafGl9gSxAy
 r5+4qfASiJcU56c4MCsE6IML+KEaMvizDG24RbmHEWei7xJkhLjfvdiU9A9hJJSyUU3A
 drXA==
X-Gm-Message-State: APt69E0dDgujYwcNflouwrgX7x3ZH5jFI0qh16C+F3dL9QOoYy8GG/BI
 X01f140mJI+H8X3XMnJbOZw=
X-Google-Smtp-Source: AAOMgpdXfWCpxXMq7VvmXL+m8/X+4ORonQE9NTT+FGe2afbwu/dSrz6LDDlLX6dIM2UAxe6Y0Zug8Q==
X-Received: by 2002:aca:a93:: with SMTP id k19-v6mr7492877oiy.83.1530237351653; 
 Thu, 28 Jun 2018 18:55:51 -0700 (PDT)
Received: from linux.adax.com (172-11-198-60.lightspeed.sntcca.sbcglobal.net.
 [172.11.198.60])
 by smtp.gmail.com with ESMTPSA id n3-v6sm3941288otk.38.2018.06.28.18.55.50
 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);
 Thu, 28 Jun 2018 18:55:50 -0700 (PDT)
Sender: Dan Gora <dan.gora@gmail.com>
From: Dan Gora <dg@adax.com>
To: ferruh.yigit@intel.com
Cc: dev@dpdk.org,
	Dan Gora <dg@adax.com>
Date: Thu, 28 Jun 2018 18:55:01 -0700
Message-Id: <20180629015508.26599-4-dg@adax.com>
X-Mailer: git-send-email 2.18.0.rc1.1.g6f333ff2f
In-Reply-To: <20180629015508.26599-1-dg@adax.com>
References: <20180628224513.18391-1-dg@adax.com>
 <20180629015508.26599-1-dg@adax.com>
Subject: [dpdk-dev] [PATCH v2 03/10] kni: don't touch struct kni_dev after
	freeing
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Fri, 29 Jun 2018 01:55:52 -0000

Since the struct kni_dev is allocated as part of the netdev with
alloc_netdev, when free_netdev is called, this also frees the struct
kni_dev embedded in it.

This means that we cannot touch struct kni_dev after calling
free_netdev since that memory was already deallocated.

Separate unregistering the net_dev with unregister_netdev from freeing
the net_device and kni_dev structures into separate functions and
ensure that we do not touch anything in the kni_dev structure after
freeing it (ie don't call list_del(), etc...).

Signed-off-by: Dan Gora <dg@adax.com>
---
 kernel/linux/kni/kni_dev.h  |  1 +
 kernel/linux/kni/kni_misc.c | 28 +++++++++++++++++++++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h
index ed42989cc..f9aa90ff9 100644
--- a/kernel/linux/kni/kni_dev.h
+++ b/kernel/linux/kni/kni_dev.h
@@ -37,6 +37,7 @@ struct kni_dev {
 	struct list_head list;
 
 	struct net_device_stats stats;
+	uint16_t registered;         /* 0 if already released, 1 otherwise */
 	uint16_t group_id;           /* Group ID of a group of KNI devices */
 	uint32_t core_id;            /* Core ID to bind */
 	char name[RTE_KNI_NAMESIZE]; /* Network device name */
diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c
index d889ffc4b..1c38cfa1a 100644
--- a/kernel/linux/kni/kni_misc.c
+++ b/kernel/linux/kni/kni_misc.c
@@ -184,17 +184,34 @@ kni_dev_remove(struct kni_dev *dev)
 			ixgbe_kni_remove(dev->pci_dev);
 		else if (pci_match_id(igb_pci_tbl, dev->pci_dev))
 			igb_kni_remove(dev->pci_dev);
+		dev->pci_dev = NULL;
 	}
 #endif
 
-	if (dev->net_dev) {
+	if (dev->registered) {
 		unregister_netdev(dev->net_dev);
-		free_netdev(dev->net_dev);
+		dev->registered = 0;
 	}
 
 	return 0;
 }
 
+static void
+kni_dev_free(struct kni_dev *dev)
+{
+	struct net_device *net_dev;
+	/*
+	 * Remember that struct kni_dev is part of the netdev
+	 * structure, so we free *both* with free_netdev.
+	 */
+	if (dev == NULL)
+		return;
+	net_dev = dev->net_dev;
+	dev->net_dev = NULL;
+	if (net_dev)
+		free_netdev(net_dev);
+}
+
 static int
 kni_release(struct inode *inode, struct file *file)
 {
@@ -224,6 +241,7 @@ kni_release(struct inode *inode, struct file *file)
 		kni_dev_remove(dev);
 		kni_net_release_fifo_phy(dev);
 		list_del(&dev->list);
+		kni_dev_free(dev);
 	}
 	up_write(&knet->kni_list_lock);
 
@@ -457,15 +475,18 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
 	if (ret) {
 		pr_err("error %i registering device \"%s\"\n",
 					ret, dev_info.name);
+		kni_dev_remove(kni);
 		kni_net_release_fifo_phy(kni);
-		free_netdev(net_dev);
+		kni_dev_free(kni);
 		return -ENODEV;
 	}
+	kni->registered = 1;
 
 	ret = kni_run_thread(knet, kni, dev_info.force_bind);
 	if (ret != 0) {
 		kni_dev_remove(kni);
 		kni_net_release_fifo_phy(kni);
+		kni_dev_free(kni);
 		return ret;
 	}
 
@@ -550,6 +571,7 @@ kni_ioctl_free(struct net *net, uint32_t ioctl_num,
 
 		kni_net_release_fifo_phy(dev);
 		list_del(&dev->list);
+		kni_dev_free(dev);
 		up_write(&knet->kni_list_lock);
 		pr_info("Successfully freed kni interface: %s\n",
 			dev_info.name);
-- 
2.18.0.rc1.1.g6f333ff2f