diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-06-09 12:07:06 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-06-09 12:07:06 -0400 |
commit | c463ac972315a0c86bb20b8d35225baa75caf899 (patch) | |
tree | fccefe1583f3d8a64aca969ec299b60da473d5e1 | |
parent | 144ad2a6c56b6109ff0f64074863ae5cf1c1698a (diff) |
netfilter: nfnetlink_queue: some optimizations
- Use an atomic_t for id_sequence to avoid a spin_lock/spin_unlock pair
- Group highly modified struct nfqnl_instance fields together
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | net/netfilter/nfnetlink_queue.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 12e1ab37fcd8..d05605b38f6f 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -46,17 +46,19 @@ struct nfqnl_instance { | |||
46 | int peer_pid; | 46 | int peer_pid; |
47 | unsigned int queue_maxlen; | 47 | unsigned int queue_maxlen; |
48 | unsigned int copy_range; | 48 | unsigned int copy_range; |
49 | unsigned int queue_total; | ||
50 | unsigned int queue_dropped; | 49 | unsigned int queue_dropped; |
51 | unsigned int queue_user_dropped; | 50 | unsigned int queue_user_dropped; |
52 | 51 | ||
53 | unsigned int id_sequence; /* 'sequence' of pkt ids */ | ||
54 | 52 | ||
55 | u_int16_t queue_num; /* number of this queue */ | 53 | u_int16_t queue_num; /* number of this queue */ |
56 | u_int8_t copy_mode; | 54 | u_int8_t copy_mode; |
57 | 55 | /* | |
58 | spinlock_t lock; | 56 | * Following fields are dirtied for each queued packet, |
59 | 57 | * keep them in same cache line if possible. | |
58 | */ | ||
59 | spinlock_t lock; | ||
60 | unsigned int queue_total; | ||
61 | atomic_t id_sequence; /* 'sequence' of pkt ids */ | ||
60 | struct list_head queue_list; /* packets in queue */ | 62 | struct list_head queue_list; /* packets in queue */ |
61 | }; | 63 | }; |
62 | 64 | ||
@@ -238,32 +240,24 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
238 | 240 | ||
239 | outdev = entry->outdev; | 241 | outdev = entry->outdev; |
240 | 242 | ||
241 | spin_lock_bh(&queue->lock); | 243 | switch ((enum nfqnl_config_mode)ACCESS_ONCE(queue->copy_mode)) { |
242 | |||
243 | switch ((enum nfqnl_config_mode)queue->copy_mode) { | ||
244 | case NFQNL_COPY_META: | 244 | case NFQNL_COPY_META: |
245 | case NFQNL_COPY_NONE: | 245 | case NFQNL_COPY_NONE: |
246 | break; | 246 | break; |
247 | 247 | ||
248 | case NFQNL_COPY_PACKET: | 248 | case NFQNL_COPY_PACKET: |
249 | if (entskb->ip_summed == CHECKSUM_PARTIAL && | 249 | if (entskb->ip_summed == CHECKSUM_PARTIAL && |
250 | skb_checksum_help(entskb)) { | 250 | skb_checksum_help(entskb)) |
251 | spin_unlock_bh(&queue->lock); | ||
252 | return NULL; | 251 | return NULL; |
253 | } | 252 | |
254 | if (queue->copy_range == 0 | 253 | data_len = ACCESS_ONCE(queue->copy_range); |
255 | || queue->copy_range > entskb->len) | 254 | if (data_len == 0 || data_len > entskb->len) |
256 | data_len = entskb->len; | 255 | data_len = entskb->len; |
257 | else | ||
258 | data_len = queue->copy_range; | ||
259 | 256 | ||
260 | size += nla_total_size(data_len); | 257 | size += nla_total_size(data_len); |
261 | break; | 258 | break; |
262 | } | 259 | } |
263 | 260 | ||
264 | entry->id = queue->id_sequence++; | ||
265 | |||
266 | spin_unlock_bh(&queue->lock); | ||
267 | 261 | ||
268 | skb = alloc_skb(size, GFP_ATOMIC); | 262 | skb = alloc_skb(size, GFP_ATOMIC); |
269 | if (!skb) | 263 | if (!skb) |
@@ -278,6 +272,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
278 | nfmsg->version = NFNETLINK_V0; | 272 | nfmsg->version = NFNETLINK_V0; |
279 | nfmsg->res_id = htons(queue->queue_num); | 273 | nfmsg->res_id = htons(queue->queue_num); |
280 | 274 | ||
275 | entry->id = atomic_inc_return(&queue->id_sequence); | ||
281 | pmsg.packet_id = htonl(entry->id); | 276 | pmsg.packet_id = htonl(entry->id); |
282 | pmsg.hw_protocol = entskb->protocol; | 277 | pmsg.hw_protocol = entskb->protocol; |
283 | pmsg.hook = entry->hook; | 278 | pmsg.hook = entry->hook; |
@@ -866,7 +861,7 @@ static int seq_show(struct seq_file *s, void *v) | |||
866 | inst->peer_pid, inst->queue_total, | 861 | inst->peer_pid, inst->queue_total, |
867 | inst->copy_mode, inst->copy_range, | 862 | inst->copy_mode, inst->copy_range, |
868 | inst->queue_dropped, inst->queue_user_dropped, | 863 | inst->queue_dropped, inst->queue_user_dropped, |
869 | inst->id_sequence, 1); | 864 | atomic_read(&inst->id_sequence), 1); |
870 | } | 865 | } |
871 | 866 | ||
872 | static const struct seq_operations nfqnl_seq_ops = { | 867 | static const struct seq_operations nfqnl_seq_ops = { |