From: Patrick McHardy <kaber@trash.net>
To: xiaosuo@gmail.com
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [PATCH] netfilter: use idr instead of list to speed up packet lookup by id
Date: Wed, 07 Apr 2010 13:48:46 +0200 [thread overview]
Message-ID: <4BBC711E.7050602@trash.net> (raw)
In-Reply-To: <4BBBFE21.9070507@gmail.com>
Changli Gao wrote:
> use idr instead of list to speed up packet lookup by id.
>
> The current implementations of nfnetlink_queue, ip_queue and ip6_queue
> are all use list to save the packets queued. If the verdicts aren't
> received in order, the lookup for the corresponding packets isn't
> efficient. As the ids is generated and maintained in kernel, we can use
> idr to speed up the lookup. The side effect of this patch is fixing the
> potential id overlap in nfnetlink_queue.
This doesn't compile:
net/netfilter/nfnetlink_queue.c:57: error: field 'idr' has incomplete type
net/netfilter/nfnetlink_queue.c: In function 'instance_create':
net/netfilter/nfnetlink_queue.c:112: error: implicit declaration of
function 'idr_init'
net/netfilter/nfnetlink_queue.c: In function 'instance_destroy_rcu':
net/netfilter/nfnetlink_queue.c:143: error: implicit declaration of
function 'idr_destroy'
net/netfilter/nfnetlink_queue.c: In function 'find_dequeue_entry':
net/netfilter/nfnetlink_queue.c:170: error: implicit declaration of
function 'idr_find'
net/netfilter/nfnetlink_queue.c:170: warning: assignment makes pointer
from integer without a cast
net/netfilter/nfnetlink_queue.c:172: error: implicit declaration of
function 'idr_remove'
net/netfilter/nfnetlink_queue.c: In function 'nfqnl_flush':
net/netfilter/nfnetlink_queue.c:188: error: implicit declaration of
function 'idr_get_next'
net/netfilter/nfnetlink_queue.c:188: warning: assignment makes pointer
from integer without a cast
net/netfilter/nfnetlink_queue.c: In function 'nfqnl_build_packet_message':
net/netfilter/nfnetlink_queue.c:253: error: implicit declaration of
function 'idr_pre_get'
net/netfilter/nfnetlink_queue.c:254: error: implicit declaration of
function 'idr_get_new'
I'm interested in how this affects performance for the vast majority
of users, which process messages in order. A simple hash table looks
like a better choice here since we know the maximum number of entries
in advance and also could have the user specify the desired hash size.
> @@ -223,6 +211,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
> struct sk_buff *entskb = entry->skb;
> struct net_device *indev;
> struct net_device *outdev;
> + u32 id;
>
> size = NLMSG_SPACE(sizeof(struct nfgenmsg))
> + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
> @@ -262,7 +251,11 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
> break;
> }
>
> - entry->id = queue->id_sequence++;
> + if (!idr_pre_get(&queue->idr, GFP_ATOMIC) ||
> + idr_get_new(&queue->idr, entry, &id) != 0) {
> + spin_unlock_bh(&queue->lock);
> + return NULL;
> + }
>
> spin_unlock_bh(&queue->lock);
You probably shouldn't be making the entry visible before the message
is successfully built and sent.
>
> @@ -279,7 +272,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
> nfmsg->version = NFNETLINK_V0;
> nfmsg->res_id = htons(queue->queue_num);
>
> - pmsg.packet_id = htonl(entry->id);
> + pmsg.packet_id = htonl(id);
> pmsg.hw_protocol = entskb->protocol;
> pmsg.hook = entry->hook;
>
> @@ -375,6 +368,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
> }
>
> nlh->nlmsg_len = skb->tail - old_tail;
> + *pid = id;
> return skb;
>
> nlmsg_failure:
> @@ -383,6 +377,9 @@ nla_put_failure:
> kfree_skb(skb);
> if (net_ratelimit())
> printk(KERN_ERR "nf_queue: error creating packet message\n");
> + spin_lock_bh(&queue->lock);
> + idr_remove(&queue->idr, id);
> + spin_unlock_bh(&queue->lock);
> return NULL;
> }
>
> @@ -392,6 +389,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
> struct sk_buff *nskb;
> struct nfqnl_instance *queue;
> int err;
> + u32 id;
>
> /* rcu_read_lock()ed by nf_hook_slow() */
> queue = instance_lookup(queuenum);
> @@ -401,7 +399,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
> if (queue->copy_mode == NFQNL_COPY_NONE)
> goto err_out;
>
> - nskb = nfqnl_build_packet_message(queue, entry);
> + nskb = nfqnl_build_packet_message(queue, entry, &id);
> if (nskb == NULL)
> goto err_out;
>
> @@ -426,7 +424,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
> goto err_out_unlock;
> }
>
> - __enqueue_entry(queue, entry);
> + queue->queue_total++;
>
> spin_unlock_bh(&queue->lock);
> return 0;
> @@ -434,6 +432,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
> err_out_free_nskb:
> kfree_skb(nskb);
> err_out_unlock:
> + idr_remove(&queue->idr, id);
> spin_unlock_bh(&queue->lock);
> err_out:
> return -1;
> @@ -867,7 +866,7 @@ static int seq_show(struct seq_file *s, void *v)
> inst->peer_pid, inst->queue_total,
> inst->copy_mode, inst->copy_range,
> inst->queue_dropped, inst->queue_user_dropped,
> - inst->id_sequence, 1);
> + 0, 1);
> }
>
> static const struct seq_operations nfqnl_seq_ops = {
>
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
next prev parent reply other threads:[~2010-04-07 11:48 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-07 3:38 [PATCH] netfilter: use idr instead of list to speed up packet lookup by id Changli Gao
2010-04-07 11:48 ` Patrick McHardy [this message]
2010-04-07 12:25 ` Eric Dumazet
2010-04-07 13:03 ` Patrick McHardy
2010-04-07 13:42 ` Changli Gao
2010-04-07 13:30 ` Changli Gao
2010-04-07 13:40 ` Patrick McHardy
2010-04-07 14:07 ` Changli Gao
2010-04-07 14:16 ` Patrick McHardy
2010-04-07 14:33 ` Changli Gao
2010-04-07 14:41 ` Patrick McHardy
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=4BBC711E.7050602@trash.net \
--to=kaber@trash.net \
--cc=netfilter-devel@vger.kernel.org \
--cc=xiaosuo@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.