From: Antonio Quartulli <a@unstable.cc>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, b.a.t.m.a.n@lists.open-mesh.org,
Sven Eckelmann <sven@narfation.org>,
Marek Lindner <mareklindner@neomailbox.ch>,
Antonio Quartulli <a@unstable.cc>
Subject: [PATCH 15/15] batman-adv: Split batadv_iv_ogm_orig_del_if function
Date: Wed, 4 May 2016 06:23:50 +0800 [thread overview]
Message-ID: <1462314230-16257-16-git-send-email-a@unstable.cc> (raw)
In-Reply-To: <1462314230-16257-1-git-send-email-a@unstable.cc>
From: Sven Eckelmann <sven@narfation.org>
batadv_iv_ogm_orig_del_if handles two different buffers bcast_own and
bcast_own_sum which should be resized. The error handling two for
allocating these buffers causes the complexity of this function. This can
be avoided completely when the function is split into a main function
handling the locking, freeing and call of the subfunctions.
The subfunction can then independently handle the resize of the buffers.
This also allows to easily reuse the old buffer (which always is larger) in
case a smaller buffer could not be allocated without increasing the code
complexity.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
net/batman-adv/bat_iv_ogm.c | 131 ++++++++++++++++++++++++++++----------------
1 file changed, 84 insertions(+), 47 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 682fcaec56e6..8c1710bba803 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -32,6 +32,7 @@
#include <linux/jiffies.h>
#include <linux/list.h>
#include <linux/kref.h>
+#include <linux/lockdep.h>
#include <linux/netdevice.h>
#include <linux/pkt_sched.h>
#include <linux/printk.h>
@@ -175,6 +176,79 @@ unlock:
}
/**
+ * batadv_iv_ogm_drop_bcast_own_entry - drop section of bcast_own
+ * @orig_node: the orig_node that has to be changed
+ * @max_if_num: the current amount of interfaces
+ * @del_if_num: the index of the interface being removed
+ */
+static void
+batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
+ int max_if_num, int del_if_num)
+{
+ size_t chunk_size;
+ size_t if_offset;
+ void *data_ptr;
+
+ lockdep_assert_held(&orig_node->bat_iv.ogm_cnt_lock);
+
+ chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS;
+ data_ptr = kmalloc_array(max_if_num, chunk_size, GFP_ATOMIC);
+ if (!data_ptr)
+ /* use old buffer when new one could not be allocated */
+ data_ptr = orig_node->bat_iv.bcast_own;
+
+ /* copy first part */
+ memmove(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size);
+
+ /* copy second part */
+ if_offset = (del_if_num + 1) * chunk_size;
+ memmove((char *)data_ptr + del_if_num * chunk_size,
+ (uint8_t *)orig_node->bat_iv.bcast_own + if_offset,
+ (max_if_num - del_if_num) * chunk_size);
+
+ /* bcast_own was shrunk down in new buffer; free old one */
+ if (orig_node->bat_iv.bcast_own != data_ptr) {
+ kfree(orig_node->bat_iv.bcast_own);
+ orig_node->bat_iv.bcast_own = data_ptr;
+ }
+}
+
+/**
+ * batadv_iv_ogm_drop_bcast_own_sum_entry - drop section of bcast_own_sum
+ * @orig_node: the orig_node that has to be changed
+ * @max_if_num: the current amount of interfaces
+ * @del_if_num: the index of the interface being removed
+ */
+static void
+batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
+ int max_if_num, int del_if_num)
+{
+ size_t if_offset;
+ void *data_ptr;
+
+ lockdep_assert_held(&orig_node->bat_iv.ogm_cnt_lock);
+
+ data_ptr = kmalloc_array(max_if_num, sizeof(u8), GFP_ATOMIC);
+ if (!data_ptr)
+ /* use old buffer when new one could not be allocated */
+ data_ptr = orig_node->bat_iv.bcast_own_sum;
+
+ memmove(data_ptr, orig_node->bat_iv.bcast_own_sum,
+ del_if_num * sizeof(u8));
+
+ if_offset = (del_if_num + 1) * sizeof(u8);
+ memmove((char *)data_ptr + del_if_num * sizeof(u8),
+ orig_node->bat_iv.bcast_own_sum + if_offset,
+ (max_if_num - del_if_num) * sizeof(u8));
+
+ /* bcast_own_sum was shrunk down in new buffer; free old one */
+ if (orig_node->bat_iv.bcast_own_sum != data_ptr) {
+ kfree(orig_node->bat_iv.bcast_own_sum);
+ orig_node->bat_iv.bcast_own_sum = data_ptr;
+ }
+}
+
+/**
* batadv_iv_ogm_orig_del_if - change the private structures of the orig_node to
* exclude the removed interface
* @orig_node: the orig_node that has to be changed
@@ -186,60 +260,23 @@ unlock:
static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
int max_if_num, int del_if_num)
{
- int ret = -ENOMEM;
- size_t chunk_size, if_offset;
- void *data_ptr = NULL;
-
spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
- /* last interface was removed */
- if (max_if_num == 0)
- goto free_bcast_own;
-
- chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS;
- data_ptr = kmalloc_array(max_if_num, chunk_size, GFP_ATOMIC);
- if (!data_ptr)
- goto unlock;
-
- /* copy first part */
- memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size);
-
- /* copy second part */
- if_offset = (del_if_num + 1) * chunk_size;
- memcpy((char *)data_ptr + del_if_num * chunk_size,
- (uint8_t *)orig_node->bat_iv.bcast_own + if_offset,
- (max_if_num - del_if_num) * chunk_size);
-
-free_bcast_own:
- kfree(orig_node->bat_iv.bcast_own);
- orig_node->bat_iv.bcast_own = data_ptr;
-
- if (max_if_num == 0)
- goto free_own_sum;
-
- data_ptr = kmalloc_array(max_if_num, sizeof(u8), GFP_ATOMIC);
- if (!data_ptr) {
+ if (max_if_num == 0) {
kfree(orig_node->bat_iv.bcast_own);
- goto unlock;
+ kfree(orig_node->bat_iv.bcast_own_sum);
+ orig_node->bat_iv.bcast_own = NULL;
+ orig_node->bat_iv.bcast_own_sum = NULL;
+ } else {
+ batadv_iv_ogm_drop_bcast_own_entry(orig_node, max_if_num,
+ del_if_num);
+ batadv_iv_ogm_drop_bcast_own_sum_entry(orig_node, max_if_num,
+ del_if_num);
}
- memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum,
- del_if_num * sizeof(u8));
-
- if_offset = (del_if_num + 1) * sizeof(u8);
- memcpy((char *)data_ptr + del_if_num * sizeof(u8),
- orig_node->bat_iv.bcast_own_sum + if_offset,
- (max_if_num - del_if_num) * sizeof(u8));
-
-free_own_sum:
- kfree(orig_node->bat_iv.bcast_own_sum);
- orig_node->bat_iv.bcast_own_sum = data_ptr;
-
- ret = 0;
-unlock:
spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
- return ret;
+ return 0;
}
/**
--
2.8.2
next prev parent reply other threads:[~2016-05-03 22:40 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1462314230-16257-1-git-send-email-a@unstable.cc>
2016-05-03 22:23 ` [PATCH 01/15] MAINTAINERS: Mark BATMAN ADVANCED mailing list as moderated Antonio Quartulli
2016-05-03 22:23 ` [PATCH 02/15] MAINTAINERS: Add BATMAN ADVANCED documentation files Antonio Quartulli
2016-05-03 22:23 ` [PATCH 03/15] batman-adv: Start new development cycle Antonio Quartulli
2016-05-03 22:23 ` [PATCH 04/15] batman-adv: use static string for table headers Antonio Quartulli
2016-05-03 22:23 ` [PATCH 05/15] batman-adv: use list_for_each_entry_safe Antonio Quartulli
2016-05-03 22:23 ` [PATCH 06/15] batman-adv: use to_delayed_work Antonio Quartulli
2016-05-03 22:23 ` [PATCH 07/15] batman-adv: fix wrong names in kerneldoc Antonio Quartulli
2016-05-03 22:23 ` [PATCH 08/15] batman-adv: Fix checkpatch warning about 'unsigned' type Antonio Quartulli
2016-05-03 22:23 ` [PATCH 09/15] batman-adv: Fix kerneldoc for batadv_compare_claim Antonio Quartulli
2016-05-03 22:23 ` [PATCH 10/15] batman-adv: Add kernel-doc for batadv_interface_rx Antonio Quartulli
2016-05-03 22:23 ` [PATCH 11/15] batman-adv: Fix function names on new line starting with '*' Antonio Quartulli
2016-05-03 22:23 ` [PATCH 12/15] batman-adv: fix debuginfo macro style issue Antonio Quartulli
2016-05-03 22:23 ` [PATCH 13/15] batman-adv: move and restructure batadv_v_ogm_forward Antonio Quartulli
2016-05-03 22:23 ` [PATCH 14/15] batman-adv: Merge batadv_v_ogm_orig_update into batadv_v_ogm_route_update Antonio Quartulli
2016-05-03 22:23 ` Antonio Quartulli [this message]
[not found] ` <1462314230-16257-1-git-send-email-a-2CpIooy/SPIKlTDg6p0iyA@public.gmane.org>
2016-05-04 20:30 ` pull request: batman-adv 20160504 David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1462314230-16257-16-git-send-email-a@unstable.cc \
--to=a@unstable.cc \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
--cc=davem@davemloft.net \
--cc=mareklindner@neomailbox.ch \
--cc=netdev@vger.kernel.org \
--cc=sven@narfation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).