diff options
author | Li RongQing <lirongqing@baidu.com> | 2018-08-12 22:42:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-13 12:21:05 -0400 |
commit | 71e41286203c017d24f041a7cd71abea7ca7b1e0 (patch) | |
tree | a0b91dc171133fc0ecbe5c192f6793a6d3f913f8 | |
parent | 0192e7d46c776f7f735560bfa4d40eac3fd700f9 (diff) |
packet: switch kvzalloc to allocate memory
The patches includes following change:
*Use modern kvzalloc()/kvfree() instead of custom allocations.
*Remove order argument for alloc_pg_vec, it can get from req.
*Remove order argument for free_pg_vec, free_pg_vec now uses
kvfree which does not need order argument.
*Remove pg_vec_order from struct packet_ring_buffer, no longer
need to save/restore 'order'
*Remove variable 'order' for packet_set_ring, it is now unused
Signed-off-by: Zhang Yu <zhangyu31@baidu.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/packet/af_packet.c | 44 | ||||
-rw-r--r-- | net/packet/internal.h | 1 |
2 files changed, 13 insertions, 32 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 75c92a87e7b2..5610061e7f2e 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -4137,52 +4137,36 @@ static const struct vm_operations_struct packet_mmap_ops = { | |||
4137 | .close = packet_mm_close, | 4137 | .close = packet_mm_close, |
4138 | }; | 4138 | }; |
4139 | 4139 | ||
4140 | static void free_pg_vec(struct pgv *pg_vec, unsigned int order, | 4140 | static void free_pg_vec(struct pgv *pg_vec, unsigned int len) |
4141 | unsigned int len) | ||
4142 | { | 4141 | { |
4143 | int i; | 4142 | int i; |
4144 | 4143 | ||
4145 | for (i = 0; i < len; i++) { | 4144 | for (i = 0; i < len; i++) { |
4146 | if (likely(pg_vec[i].buffer)) { | 4145 | if (likely(pg_vec[i].buffer)) { |
4147 | if (is_vmalloc_addr(pg_vec[i].buffer)) | 4146 | kvfree(pg_vec[i].buffer); |
4148 | vfree(pg_vec[i].buffer); | ||
4149 | else | ||
4150 | free_pages((unsigned long)pg_vec[i].buffer, | ||
4151 | order); | ||
4152 | pg_vec[i].buffer = NULL; | 4147 | pg_vec[i].buffer = NULL; |
4153 | } | 4148 | } |
4154 | } | 4149 | } |
4155 | kfree(pg_vec); | 4150 | kfree(pg_vec); |
4156 | } | 4151 | } |
4157 | 4152 | ||
4158 | static char *alloc_one_pg_vec_page(unsigned long order) | 4153 | static char *alloc_one_pg_vec_page(unsigned long size) |
4159 | { | 4154 | { |
4160 | char *buffer; | 4155 | char *buffer; |
4161 | gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | | ||
4162 | __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY; | ||
4163 | 4156 | ||
4164 | buffer = (char *) __get_free_pages(gfp_flags, order); | 4157 | buffer = kvzalloc(size, GFP_KERNEL); |
4165 | if (buffer) | 4158 | if (buffer) |
4166 | return buffer; | 4159 | return buffer; |
4167 | 4160 | ||
4168 | /* __get_free_pages failed, fall back to vmalloc */ | 4161 | buffer = kvzalloc(size, GFP_KERNEL | __GFP_RETRY_MAYFAIL); |
4169 | buffer = vzalloc(array_size((1 << order), PAGE_SIZE)); | ||
4170 | if (buffer) | ||
4171 | return buffer; | ||
4172 | 4162 | ||
4173 | /* vmalloc failed, lets dig into swap here */ | 4163 | return buffer; |
4174 | gfp_flags &= ~__GFP_NORETRY; | ||
4175 | buffer = (char *) __get_free_pages(gfp_flags, order); | ||
4176 | if (buffer) | ||
4177 | return buffer; | ||
4178 | |||
4179 | /* complete and utter failure */ | ||
4180 | return NULL; | ||
4181 | } | 4164 | } |
4182 | 4165 | ||
4183 | static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) | 4166 | static struct pgv *alloc_pg_vec(struct tpacket_req *req) |
4184 | { | 4167 | { |
4185 | unsigned int block_nr = req->tp_block_nr; | 4168 | unsigned int block_nr = req->tp_block_nr; |
4169 | unsigned long size = req->tp_block_size; | ||
4186 | struct pgv *pg_vec; | 4170 | struct pgv *pg_vec; |
4187 | int i; | 4171 | int i; |
4188 | 4172 | ||
@@ -4191,7 +4175,7 @@ static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) | |||
4191 | goto out; | 4175 | goto out; |
4192 | 4176 | ||
4193 | for (i = 0; i < block_nr; i++) { | 4177 | for (i = 0; i < block_nr; i++) { |
4194 | pg_vec[i].buffer = alloc_one_pg_vec_page(order); | 4178 | pg_vec[i].buffer = alloc_one_pg_vec_page(size); |
4195 | if (unlikely(!pg_vec[i].buffer)) | 4179 | if (unlikely(!pg_vec[i].buffer)) |
4196 | goto out_free_pgvec; | 4180 | goto out_free_pgvec; |
4197 | } | 4181 | } |
@@ -4200,7 +4184,7 @@ out: | |||
4200 | return pg_vec; | 4184 | return pg_vec; |
4201 | 4185 | ||
4202 | out_free_pgvec: | 4186 | out_free_pgvec: |
4203 | free_pg_vec(pg_vec, order, block_nr); | 4187 | free_pg_vec(pg_vec, block_nr); |
4204 | pg_vec = NULL; | 4188 | pg_vec = NULL; |
4205 | goto out; | 4189 | goto out; |
4206 | } | 4190 | } |
@@ -4210,9 +4194,9 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
4210 | { | 4194 | { |
4211 | struct pgv *pg_vec = NULL; | 4195 | struct pgv *pg_vec = NULL; |
4212 | struct packet_sock *po = pkt_sk(sk); | 4196 | struct packet_sock *po = pkt_sk(sk); |
4213 | int was_running, order = 0; | ||
4214 | struct packet_ring_buffer *rb; | 4197 | struct packet_ring_buffer *rb; |
4215 | struct sk_buff_head *rb_queue; | 4198 | struct sk_buff_head *rb_queue; |
4199 | int was_running; | ||
4216 | __be16 num; | 4200 | __be16 num; |
4217 | int err = -EINVAL; | 4201 | int err = -EINVAL; |
4218 | /* Added to avoid minimal code churn */ | 4202 | /* Added to avoid minimal code churn */ |
@@ -4274,8 +4258,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
4274 | goto out; | 4258 | goto out; |
4275 | 4259 | ||
4276 | err = -ENOMEM; | 4260 | err = -ENOMEM; |
4277 | order = get_order(req->tp_block_size); | 4261 | pg_vec = alloc_pg_vec(req); |
4278 | pg_vec = alloc_pg_vec(req, order); | ||
4279 | if (unlikely(!pg_vec)) | 4262 | if (unlikely(!pg_vec)) |
4280 | goto out; | 4263 | goto out; |
4281 | switch (po->tp_version) { | 4264 | switch (po->tp_version) { |
@@ -4329,7 +4312,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
4329 | rb->frame_size = req->tp_frame_size; | 4312 | rb->frame_size = req->tp_frame_size; |
4330 | spin_unlock_bh(&rb_queue->lock); | 4313 | spin_unlock_bh(&rb_queue->lock); |
4331 | 4314 | ||
4332 | swap(rb->pg_vec_order, order); | ||
4333 | swap(rb->pg_vec_len, req->tp_block_nr); | 4315 | swap(rb->pg_vec_len, req->tp_block_nr); |
4334 | 4316 | ||
4335 | rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE; | 4317 | rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE; |
@@ -4355,7 +4337,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
4355 | } | 4337 | } |
4356 | 4338 | ||
4357 | if (pg_vec) | 4339 | if (pg_vec) |
4358 | free_pg_vec(pg_vec, order, req->tp_block_nr); | 4340 | free_pg_vec(pg_vec, req->tp_block_nr); |
4359 | out: | 4341 | out: |
4360 | return err; | 4342 | return err; |
4361 | } | 4343 | } |
diff --git a/net/packet/internal.h b/net/packet/internal.h index 3bb7c5fb3bff..8f50036f62f0 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h | |||
@@ -64,7 +64,6 @@ struct packet_ring_buffer { | |||
64 | unsigned int frame_size; | 64 | unsigned int frame_size; |
65 | unsigned int frame_max; | 65 | unsigned int frame_max; |
66 | 66 | ||
67 | unsigned int pg_vec_order; | ||
68 | unsigned int pg_vec_pages; | 67 | unsigned int pg_vec_pages; |
69 | unsigned int pg_vec_len; | 68 | unsigned int pg_vec_len; |
70 | 69 | ||