|
1 | 1 | #ifndef __NET_FRAG_H__
|
2 | 2 | #define __NET_FRAG_H__
|
3 | 3 |
|
| 4 | +#include <linux/percpu_counter.h> |
| 5 | + |
4 | 6 | struct netns_frags {
|
5 | 7 | int nqueues;
|
6 | 8 | struct list_head lru_list;
|
7 | 9 |
|
8 |
| - /* Its important for performance to keep lru_list and mem on |
9 |
| - * separate cachelines |
| 10 | + /* The percpu_counter "mem" need to be cacheline aligned. |
| 11 | + * mem.count must not share cacheline with other writers |
10 | 12 | */
|
11 |
| - atomic_t mem ____cacheline_aligned_in_smp; |
| 13 | + struct percpu_counter mem ____cacheline_aligned_in_smp; |
| 14 | + |
12 | 15 | /* sysctls */
|
13 | 16 | int timeout;
|
14 | 17 | int high_thresh;
|
@@ -81,29 +84,36 @@ static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f
|
81 | 84 |
|
82 | 85 | /* Memory Tracking Functions. */
|
83 | 86 |
|
| 87 | +/* The default percpu_counter batch size is not big enough to scale to |
| 88 | + * fragmentation mem acct sizes. |
| 89 | + * The mem size of a 64K fragment is approx: |
| 90 | + * (44 fragments * 2944 truesize) + frag_queue struct(200) = 129736 bytes |
| 91 | + */ |
| 92 | +static unsigned int frag_percpu_counter_batch = 130000; |
| 93 | + |
84 | 94 | static inline int frag_mem_limit(struct netns_frags *nf)
|
85 | 95 | {
|
86 |
| - return atomic_read(&nf->mem); |
| 96 | + return percpu_counter_read(&nf->mem); |
87 | 97 | }
|
88 | 98 |
|
89 | 99 | static inline void sub_frag_mem_limit(struct inet_frag_queue *q, int i)
|
90 | 100 | {
|
91 |
| - atomic_sub(i, &q->net->mem); |
| 101 | + __percpu_counter_add(&q->net->mem, -i, frag_percpu_counter_batch); |
92 | 102 | }
|
93 | 103 |
|
94 | 104 | static inline void add_frag_mem_limit(struct inet_frag_queue *q, int i)
|
95 | 105 | {
|
96 |
| - atomic_add(i, &q->net->mem); |
| 106 | + __percpu_counter_add(&q->net->mem, i, frag_percpu_counter_batch); |
97 | 107 | }
|
98 | 108 |
|
99 | 109 | static inline void init_frag_mem_limit(struct netns_frags *nf)
|
100 | 110 | {
|
101 |
| - atomic_set(&nf->mem, 0); |
| 111 | + percpu_counter_init(&nf->mem, 0); |
102 | 112 | }
|
103 | 113 |
|
104 | 114 | static inline int sum_frag_mem_limit(struct netns_frags *nf)
|
105 | 115 | {
|
106 |
| - return atomic_read(&nf->mem); |
| 116 | + return percpu_counter_sum_positive(&nf->mem); |
107 | 117 | }
|
108 | 118 |
|
109 | 119 | #endif
|
0 commit comments