diff options
Diffstat (limited to 'net')
44 files changed, 265 insertions, 171 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 5f27f8e30254..f1f2f7bb6661 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
| @@ -167,6 +167,8 @@ struct sk_buff *vlan_untag(struct sk_buff *skb) | |||
| 167 | if (unlikely(!skb)) | 167 | if (unlikely(!skb)) |
| 168 | goto err_free; | 168 | goto err_free; |
| 169 | 169 | ||
| 170 | skb_reset_network_header(skb); | ||
| 171 | skb_reset_transport_header(skb); | ||
| 170 | return skb; | 172 | return skb; |
| 171 | 173 | ||
| 172 | err_free: | 174 | err_free: |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 175b5135bdcf..e317583fcc73 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -263,7 +263,6 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) | |||
| 263 | { | 263 | { |
| 264 | int in, out, inp, outp; | 264 | int in, out, inp, outp; |
| 265 | struct virtio_chan *chan = client->trans; | 265 | struct virtio_chan *chan = client->trans; |
| 266 | char *rdata = (char *)req->rc+sizeof(struct p9_fcall); | ||
| 267 | unsigned long flags; | 266 | unsigned long flags; |
| 268 | size_t pdata_off = 0; | 267 | size_t pdata_off = 0; |
| 269 | struct trans_rpage_info *rpinfo = NULL; | 268 | struct trans_rpage_info *rpinfo = NULL; |
| @@ -346,7 +345,8 @@ req_retry_pinned: | |||
| 346 | * Arrange in such a way that server places header in the | 345 | * Arrange in such a way that server places header in the |
| 347 | * alloced memory and payload onto the user buffer. | 346 | * alloced memory and payload onto the user buffer. |
| 348 | */ | 347 | */ |
| 349 | inp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, 11); | 348 | inp = pack_sg_list(chan->sg, out, |
| 349 | VIRTQUEUE_NUM, req->rc->sdata, 11); | ||
| 350 | /* | 350 | /* |
| 351 | * Running executables in the filesystem may result in | 351 | * Running executables in the filesystem may result in |
| 352 | * a read request with kernel buffer as opposed to user buffer. | 352 | * a read request with kernel buffer as opposed to user buffer. |
| @@ -366,8 +366,8 @@ req_retry_pinned: | |||
| 366 | } | 366 | } |
| 367 | in += inp; | 367 | in += inp; |
| 368 | } else { | 368 | } else { |
| 369 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, | 369 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, |
| 370 | req->rc->capacity); | 370 | req->rc->sdata, req->rc->capacity); |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc); | 373 | err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc); |
| @@ -592,7 +592,14 @@ static struct p9_trans_module p9_virtio_trans = { | |||
| 592 | .close = p9_virtio_close, | 592 | .close = p9_virtio_close, |
| 593 | .request = p9_virtio_request, | 593 | .request = p9_virtio_request, |
| 594 | .cancel = p9_virtio_cancel, | 594 | .cancel = p9_virtio_cancel, |
| 595 | .maxsize = PAGE_SIZE*VIRTQUEUE_NUM, | 595 | |
| 596 | /* | ||
| 597 | * We leave one entry for input and one entry for response | ||
| 598 | * headers. We also skip one more entry to accomodate, address | ||
| 599 | * that are not at page boundary, that can result in an extra | ||
| 600 | * page in zero copy. | ||
| 601 | */ | ||
| 602 | .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3), | ||
| 596 | .pref = P9_TRANS_PREF_PAYLOAD_SEP, | 603 | .pref = P9_TRANS_PREF_PAYLOAD_SEP, |
| 597 | .def = 0, | 604 | .def = 0, |
| 598 | .owner = THIS_MODULE, | 605 | .owner = THIS_MODULE, |
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 52cfd0c3ea71..d07223c834af 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
| @@ -558,12 +558,13 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) | |||
| 558 | spin_unlock_irqrestore(&rq->lock, flags); | 558 | spin_unlock_irqrestore(&rq->lock, flags); |
| 559 | 559 | ||
| 560 | skb_queue_walk_safe(&queue, skb, tmp) { | 560 | skb_queue_walk_safe(&queue, skb, tmp) { |
| 561 | struct net_device *dev = skb->dev; | 561 | struct net_device *dev; |
| 562 | |||
| 563 | br2684_push(atmvcc, skb); | ||
| 564 | dev = skb->dev; | ||
| 562 | 565 | ||
| 563 | dev->stats.rx_bytes -= skb->len; | 566 | dev->stats.rx_bytes -= skb->len; |
| 564 | dev->stats.rx_packets--; | 567 | dev->stats.rx_packets--; |
| 565 | |||
| 566 | br2684_push(atmvcc, skb); | ||
| 567 | } | 568 | } |
| 568 | 569 | ||
| 569 | /* initialize netdev carrier state */ | 570 | /* initialize netdev carrier state */ |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8add9b499912..117e0d161780 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
| @@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
| 494 | BT_DBG("sk %p", sk); | 494 | BT_DBG("sk %p", sk); |
| 495 | 495 | ||
| 496 | add_wait_queue(sk_sleep(sk), &wait); | 496 | add_wait_queue(sk_sleep(sk), &wait); |
| 497 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 497 | while (sk->sk_state != state) { | 498 | while (sk->sk_state != state) { |
| 498 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 499 | |||
| 500 | if (!timeo) { | 499 | if (!timeo) { |
| 501 | err = -EINPROGRESS; | 500 | err = -EINPROGRESS; |
| 502 | break; | 501 | break; |
| @@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
| 510 | release_sock(sk); | 509 | release_sock(sk); |
| 511 | timeo = schedule_timeout(timeo); | 510 | timeo = schedule_timeout(timeo); |
| 512 | lock_sock(sk); | 511 | lock_sock(sk); |
| 512 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 513 | 513 | ||
| 514 | err = sock_error(sk); | 514 | err = sock_error(sk); |
| 515 | if (err) | 515 | if (err) |
| 516 | break; | 516 | break; |
| 517 | } | 517 | } |
| 518 | set_current_state(TASK_RUNNING); | 518 | __set_current_state(TASK_RUNNING); |
| 519 | remove_wait_queue(sk_sleep(sk), &wait); | 519 | remove_wait_queue(sk_sleep(sk), &wait); |
| 520 | return err; | 520 | return err; |
| 521 | } | 521 | } |
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index 8e6c06158f8e..e7ee5314f39a 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h | |||
| @@ -155,6 +155,7 @@ struct bnep_session { | |||
| 155 | unsigned int role; | 155 | unsigned int role; |
| 156 | unsigned long state; | 156 | unsigned long state; |
| 157 | unsigned long flags; | 157 | unsigned long flags; |
| 158 | atomic_t terminate; | ||
| 158 | struct task_struct *task; | 159 | struct task_struct *task; |
| 159 | 160 | ||
| 160 | struct ethhdr eh; | 161 | struct ethhdr eh; |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index ca39fcf010ce..d9edfe8bf9d6 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
| @@ -484,9 +484,11 @@ static int bnep_session(void *arg) | |||
| 484 | 484 | ||
| 485 | init_waitqueue_entry(&wait, current); | 485 | init_waitqueue_entry(&wait, current); |
| 486 | add_wait_queue(sk_sleep(sk), &wait); | 486 | add_wait_queue(sk_sleep(sk), &wait); |
| 487 | while (!kthread_should_stop()) { | 487 | while (1) { |
| 488 | set_current_state(TASK_INTERRUPTIBLE); | 488 | set_current_state(TASK_INTERRUPTIBLE); |
| 489 | 489 | ||
| 490 | if (atomic_read(&s->terminate)) | ||
| 491 | break; | ||
| 490 | /* RX */ | 492 | /* RX */ |
| 491 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { | 493 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { |
| 492 | skb_orphan(skb); | 494 | skb_orphan(skb); |
| @@ -504,7 +506,7 @@ static int bnep_session(void *arg) | |||
| 504 | 506 | ||
| 505 | schedule(); | 507 | schedule(); |
| 506 | } | 508 | } |
| 507 | set_current_state(TASK_RUNNING); | 509 | __set_current_state(TASK_RUNNING); |
| 508 | remove_wait_queue(sk_sleep(sk), &wait); | 510 | remove_wait_queue(sk_sleep(sk), &wait); |
| 509 | 511 | ||
| 510 | /* Cleanup session */ | 512 | /* Cleanup session */ |
| @@ -640,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req) | |||
| 640 | down_read(&bnep_session_sem); | 642 | down_read(&bnep_session_sem); |
| 641 | 643 | ||
| 642 | s = __bnep_get_session(req->dst); | 644 | s = __bnep_get_session(req->dst); |
| 643 | if (s) | 645 | if (s) { |
| 644 | kthread_stop(s->task); | 646 | atomic_inc(&s->terminate); |
| 645 | else | 647 | wake_up_process(s->task); |
| 648 | } else | ||
| 646 | err = -ENOENT; | 649 | err = -ENOENT; |
| 647 | 650 | ||
| 648 | up_read(&bnep_session_sem); | 651 | up_read(&bnep_session_sem); |
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 040f67b12978..50f0d135eb8f 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
| @@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) | |||
| 386 | 386 | ||
| 387 | capi_ctr_down(ctrl); | 387 | capi_ctr_down(ctrl); |
| 388 | 388 | ||
| 389 | kthread_stop(session->task); | 389 | atomic_inc(&session->terminate); |
| 390 | wake_up_process(session->task); | ||
| 390 | } | 391 | } |
| 391 | 392 | ||
| 392 | static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) | 393 | static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) |
diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index db43b54ac9af..c32638dddbf9 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h | |||
| @@ -81,6 +81,7 @@ struct cmtp_session { | |||
| 81 | 81 | ||
| 82 | char name[BTNAMSIZ]; | 82 | char name[BTNAMSIZ]; |
| 83 | 83 | ||
| 84 | atomic_t terminate; | ||
| 84 | struct task_struct *task; | 85 | struct task_struct *task; |
| 85 | 86 | ||
| 86 | wait_queue_head_t wait; | 87 | wait_queue_head_t wait; |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index c5b11af908be..521baa4fe835 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
| @@ -292,9 +292,11 @@ static int cmtp_session(void *arg) | |||
| 292 | 292 | ||
| 293 | init_waitqueue_entry(&wait, current); | 293 | init_waitqueue_entry(&wait, current); |
| 294 | add_wait_queue(sk_sleep(sk), &wait); | 294 | add_wait_queue(sk_sleep(sk), &wait); |
| 295 | while (!kthread_should_stop()) { | 295 | while (1) { |
| 296 | set_current_state(TASK_INTERRUPTIBLE); | 296 | set_current_state(TASK_INTERRUPTIBLE); |
| 297 | 297 | ||
| 298 | if (atomic_read(&session->terminate)) | ||
| 299 | break; | ||
| 298 | if (sk->sk_state != BT_CONNECTED) | 300 | if (sk->sk_state != BT_CONNECTED) |
| 299 | break; | 301 | break; |
| 300 | 302 | ||
| @@ -307,7 +309,7 @@ static int cmtp_session(void *arg) | |||
| 307 | 309 | ||
| 308 | schedule(); | 310 | schedule(); |
| 309 | } | 311 | } |
| 310 | set_current_state(TASK_RUNNING); | 312 | __set_current_state(TASK_RUNNING); |
| 311 | remove_wait_queue(sk_sleep(sk), &wait); | 313 | remove_wait_queue(sk_sleep(sk), &wait); |
| 312 | 314 | ||
| 313 | down_write(&cmtp_session_sem); | 315 | down_write(&cmtp_session_sem); |
| @@ -380,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) | |||
| 380 | 382 | ||
| 381 | if (!(session->flags & (1 << CMTP_LOOPBACK))) { | 383 | if (!(session->flags & (1 << CMTP_LOOPBACK))) { |
| 382 | err = cmtp_attach_device(session); | 384 | err = cmtp_attach_device(session); |
| 383 | if (err < 0) | 385 | if (err < 0) { |
| 384 | goto detach; | 386 | atomic_inc(&session->terminate); |
| 387 | wake_up_process(session->task); | ||
| 388 | up_write(&cmtp_session_sem); | ||
| 389 | return err; | ||
| 390 | } | ||
| 385 | } | 391 | } |
| 386 | 392 | ||
| 387 | up_write(&cmtp_session_sem); | 393 | up_write(&cmtp_session_sem); |
| 388 | return 0; | 394 | return 0; |
| 389 | 395 | ||
| 390 | detach: | ||
| 391 | cmtp_detach_device(session); | ||
| 392 | |||
| 393 | unlink: | 396 | unlink: |
| 394 | __cmtp_unlink_session(session); | 397 | __cmtp_unlink_session(session); |
| 395 | 398 | ||
| @@ -414,7 +417,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) | |||
| 414 | skb_queue_purge(&session->transmit); | 417 | skb_queue_purge(&session->transmit); |
| 415 | 418 | ||
| 416 | /* Stop session thread */ | 419 | /* Stop session thread */ |
| 417 | kthread_stop(session->task); | 420 | atomic_inc(&session->terminate); |
| 421 | wake_up_process(session->task); | ||
| 418 | } else | 422 | } else |
| 419 | err = -ENOENT; | 423 | err = -ENOENT; |
| 420 | 424 | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ec0bc3f60f2e..56943add45cc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg) | |||
| 1209 | 1209 | ||
| 1210 | BT_ERR("%s command tx timeout", hdev->name); | 1210 | BT_ERR("%s command tx timeout", hdev->name); |
| 1211 | atomic_set(&hdev->cmd_cnt, 1); | 1211 | atomic_set(&hdev->cmd_cnt, 1); |
| 1212 | clear_bit(HCI_RESET, &hdev->flags); | ||
| 1213 | tasklet_schedule(&hdev->cmd_task); | 1212 | tasklet_schedule(&hdev->cmd_task); |
| 1214 | } | 1213 | } |
| 1215 | 1214 | ||
| @@ -1327,7 +1326,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
| 1327 | 1326 | ||
| 1328 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); | 1327 | entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); |
| 1329 | if (!entry) { | 1328 | if (!entry) { |
| 1330 | return -ENOMEM; | 1329 | err = -ENOMEM; |
| 1331 | goto err; | 1330 | goto err; |
| 1332 | } | 1331 | } |
| 1333 | 1332 | ||
| @@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg) | |||
| 2408 | if (hdev->sent_cmd) { | 2407 | if (hdev->sent_cmd) { |
| 2409 | atomic_dec(&hdev->cmd_cnt); | 2408 | atomic_dec(&hdev->cmd_cnt); |
| 2410 | hci_send_frame(skb); | 2409 | hci_send_frame(skb); |
| 2411 | mod_timer(&hdev->cmd_timer, | 2410 | if (test_bit(HCI_RESET, &hdev->flags)) |
| 2411 | del_timer(&hdev->cmd_timer); | ||
| 2412 | else | ||
| 2413 | mod_timer(&hdev->cmd_timer, | ||
| 2412 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); | 2414 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); |
| 2413 | } else { | 2415 | } else { |
| 2414 | skb_queue_head(&hdev->cmd_q, skb); | 2416 | skb_queue_head(&hdev->cmd_q, skb); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 43b4c2deb7cc..fb68f344c34a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
| @@ -764,6 +764,7 @@ static int hidp_session(void *arg) | |||
| 764 | 764 | ||
| 765 | up_write(&hidp_session_sem); | 765 | up_write(&hidp_session_sem); |
| 766 | 766 | ||
| 767 | kfree(session->rd_data); | ||
| 767 | kfree(session); | 768 | kfree(session); |
| 768 | return 0; | 769 | return 0; |
| 769 | } | 770 | } |
| @@ -841,7 +842,8 @@ static int hidp_setup_input(struct hidp_session *session, | |||
| 841 | 842 | ||
| 842 | err = input_register_device(input); | 843 | err = input_register_device(input); |
| 843 | if (err < 0) { | 844 | if (err < 0) { |
| 844 | hci_conn_put_device(session->conn); | 845 | input_free_device(input); |
| 846 | session->input = NULL; | ||
| 845 | return err; | 847 | return err; |
| 846 | } | 848 | } |
| 847 | 849 | ||
| @@ -1044,8 +1046,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
| 1044 | } | 1046 | } |
| 1045 | 1047 | ||
| 1046 | err = hid_add_device(session->hid); | 1048 | err = hid_add_device(session->hid); |
| 1047 | if (err < 0) | 1049 | if (err < 0) { |
| 1048 | goto err_add_device; | 1050 | atomic_inc(&session->terminate); |
| 1051 | wake_up_process(session->task); | ||
| 1052 | up_write(&hidp_session_sem); | ||
| 1053 | return err; | ||
| 1054 | } | ||
| 1049 | 1055 | ||
| 1050 | if (session->input) { | 1056 | if (session->input) { |
| 1051 | hidp_send_ctrl_message(session, | 1057 | hidp_send_ctrl_message(session, |
| @@ -1059,12 +1065,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
| 1059 | up_write(&hidp_session_sem); | 1065 | up_write(&hidp_session_sem); |
| 1060 | return 0; | 1066 | return 0; |
| 1061 | 1067 | ||
| 1062 | err_add_device: | ||
| 1063 | hid_destroy_device(session->hid); | ||
| 1064 | session->hid = NULL; | ||
| 1065 | atomic_inc(&session->terminate); | ||
| 1066 | wake_up_process(session->task); | ||
| 1067 | |||
| 1068 | unlink: | 1068 | unlink: |
| 1069 | hidp_del_timer(session); | 1069 | hidp_del_timer(session); |
| 1070 | 1070 | ||
| @@ -1090,7 +1090,6 @@ purge: | |||
| 1090 | failed: | 1090 | failed: |
| 1091 | up_write(&hidp_session_sem); | 1091 | up_write(&hidp_session_sem); |
| 1092 | 1092 | ||
| 1093 | input_free_device(session->input); | ||
| 1094 | kfree(session); | 1093 | kfree(session); |
| 1095 | return err; | 1094 | return err; |
| 1096 | } | 1095 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3204ba8a701c..b3bdb482bbe6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk) | |||
| 1159 | int timeo = HZ/5; | 1159 | int timeo = HZ/5; |
| 1160 | 1160 | ||
| 1161 | add_wait_queue(sk_sleep(sk), &wait); | 1161 | add_wait_queue(sk_sleep(sk), &wait); |
| 1162 | while ((chan->unacked_frames > 0 && chan->conn)) { | 1162 | set_current_state(TASK_INTERRUPTIBLE); |
| 1163 | set_current_state(TASK_INTERRUPTIBLE); | 1163 | while (chan->unacked_frames > 0 && chan->conn) { |
| 1164 | |||
| 1165 | if (!timeo) | 1164 | if (!timeo) |
| 1166 | timeo = HZ/5; | 1165 | timeo = HZ/5; |
| 1167 | 1166 | ||
| @@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk) | |||
| 1173 | release_sock(sk); | 1172 | release_sock(sk); |
| 1174 | timeo = schedule_timeout(timeo); | 1173 | timeo = schedule_timeout(timeo); |
| 1175 | lock_sock(sk); | 1174 | lock_sock(sk); |
| 1175 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1176 | 1176 | ||
| 1177 | err = sock_error(sk); | 1177 | err = sock_error(sk); |
| 1178 | if (err) | 1178 | if (err) |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5c36b3e8739c..61f1f623091d 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
| @@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
| 235 | 235 | ||
| 236 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | 236 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); |
| 237 | 237 | ||
| 238 | if (sk->sk_state != BT_LISTEN) { | ||
| 239 | err = -EBADFD; | ||
| 240 | goto done; | ||
| 241 | } | ||
| 242 | |||
| 243 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 238 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
| 244 | 239 | ||
| 245 | BT_DBG("sk %p timeo %ld", sk, timeo); | 240 | BT_DBG("sk %p timeo %ld", sk, timeo); |
| 246 | 241 | ||
| 247 | /* Wait for an incoming connection. (wake-one). */ | 242 | /* Wait for an incoming connection. (wake-one). */ |
| 248 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 243 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
| 249 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 244 | while (1) { |
| 250 | set_current_state(TASK_INTERRUPTIBLE); | 245 | set_current_state(TASK_INTERRUPTIBLE); |
| 251 | if (!timeo) { | 246 | |
| 252 | err = -EAGAIN; | 247 | if (sk->sk_state != BT_LISTEN) { |
| 248 | err = -EBADFD; | ||
| 253 | break; | 249 | break; |
| 254 | } | 250 | } |
| 255 | 251 | ||
| 256 | release_sock(sk); | 252 | nsk = bt_accept_dequeue(sk, newsock); |
| 257 | timeo = schedule_timeout(timeo); | 253 | if (nsk) |
| 258 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | 254 | break; |
| 259 | 255 | ||
| 260 | if (sk->sk_state != BT_LISTEN) { | 256 | if (!timeo) { |
| 261 | err = -EBADFD; | 257 | err = -EAGAIN; |
| 262 | break; | 258 | break; |
| 263 | } | 259 | } |
| 264 | 260 | ||
| @@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl | |||
| 266 | err = sock_intr_errno(timeo); | 262 | err = sock_intr_errno(timeo); |
| 267 | break; | 263 | break; |
| 268 | } | 264 | } |
| 265 | |||
| 266 | release_sock(sk); | ||
| 267 | timeo = schedule_timeout(timeo); | ||
| 268 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
| 269 | } | 269 | } |
| 270 | set_current_state(TASK_RUNNING); | 270 | __set_current_state(TASK_RUNNING); |
| 271 | remove_wait_queue(sk_sleep(sk), &wait); | 271 | remove_wait_queue(sk_sleep(sk), &wait); |
| 272 | 272 | ||
| 273 | if (err) | 273 | if (err) |
| @@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
| 993 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); | 993 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); |
| 994 | 994 | ||
| 995 | sk->sk_destruct = l2cap_sock_destruct; | 995 | sk->sk_destruct = l2cap_sock_destruct; |
| 996 | sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); | 996 | sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT; |
| 997 | 997 | ||
| 998 | sock_reset_flag(sk, SOCK_ZAPPED); | 998 | sock_reset_flag(sk, SOCK_ZAPPED); |
| 999 | 999 | ||
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 5759bb7054f7..5ba3f6df665c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
| @@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
| 62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) | 62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) |
| 63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) | 63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) |
| 64 | 64 | ||
| 65 | static unsigned long rfcomm_event; | ||
| 66 | 65 | ||
| 67 | static LIST_HEAD(session_list); | 66 | static LIST_HEAD(session_list); |
| 68 | 67 | ||
| @@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void) | |||
| 120 | { | 119 | { |
| 121 | if (!rfcomm_thread) | 120 | if (!rfcomm_thread) |
| 122 | return; | 121 | return; |
| 123 | set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
| 124 | wake_up_process(rfcomm_thread); | 122 | wake_up_process(rfcomm_thread); |
| 125 | } | 123 | } |
| 126 | 124 | ||
| @@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused) | |||
| 2038 | 2036 | ||
| 2039 | rfcomm_add_listener(BDADDR_ANY); | 2037 | rfcomm_add_listener(BDADDR_ANY); |
| 2040 | 2038 | ||
| 2041 | while (!kthread_should_stop()) { | 2039 | while (1) { |
| 2042 | set_current_state(TASK_INTERRUPTIBLE); | 2040 | set_current_state(TASK_INTERRUPTIBLE); |
| 2043 | if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { | 2041 | |
| 2044 | /* No pending events. Let's sleep. | 2042 | if (kthread_should_stop()) |
| 2045 | * Incoming connections and data will wake us up. */ | 2043 | break; |
| 2046 | schedule(); | ||
| 2047 | } | ||
| 2048 | set_current_state(TASK_RUNNING); | ||
| 2049 | 2044 | ||
| 2050 | /* Process stuff */ | 2045 | /* Process stuff */ |
| 2051 | clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
| 2052 | rfcomm_process_sessions(); | 2046 | rfcomm_process_sessions(); |
| 2047 | |||
| 2048 | schedule(); | ||
| 2053 | } | 2049 | } |
| 2050 | __set_current_state(TASK_RUNNING); | ||
| 2054 | 2051 | ||
| 2055 | rfcomm_kill_listener(); | 2052 | rfcomm_kill_listener(); |
| 2056 | 2053 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8f01e6b11a70..482722bbc7a0 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
| @@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
| 485 | 485 | ||
| 486 | lock_sock(sk); | 486 | lock_sock(sk); |
| 487 | 487 | ||
| 488 | if (sk->sk_state != BT_LISTEN) { | ||
| 489 | err = -EBADFD; | ||
| 490 | goto done; | ||
| 491 | } | ||
| 492 | |||
| 493 | if (sk->sk_type != SOCK_STREAM) { | 488 | if (sk->sk_type != SOCK_STREAM) { |
| 494 | err = -EINVAL; | 489 | err = -EINVAL; |
| 495 | goto done; | 490 | goto done; |
| @@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
| 501 | 496 | ||
| 502 | /* Wait for an incoming connection. (wake-one). */ | 497 | /* Wait for an incoming connection. (wake-one). */ |
| 503 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 498 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
| 504 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 499 | while (1) { |
| 505 | set_current_state(TASK_INTERRUPTIBLE); | 500 | set_current_state(TASK_INTERRUPTIBLE); |
| 506 | if (!timeo) { | 501 | |
| 507 | err = -EAGAIN; | 502 | if (sk->sk_state != BT_LISTEN) { |
| 503 | err = -EBADFD; | ||
| 508 | break; | 504 | break; |
| 509 | } | 505 | } |
| 510 | 506 | ||
| 511 | release_sock(sk); | 507 | nsk = bt_accept_dequeue(sk, newsock); |
| 512 | timeo = schedule_timeout(timeo); | 508 | if (nsk) |
| 513 | lock_sock(sk); | 509 | break; |
| 514 | 510 | ||
| 515 | if (sk->sk_state != BT_LISTEN) { | 511 | if (!timeo) { |
| 516 | err = -EBADFD; | 512 | err = -EAGAIN; |
| 517 | break; | 513 | break; |
| 518 | } | 514 | } |
| 519 | 515 | ||
| @@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
| 521 | err = sock_intr_errno(timeo); | 517 | err = sock_intr_errno(timeo); |
| 522 | break; | 518 | break; |
| 523 | } | 519 | } |
| 520 | |||
| 521 | release_sock(sk); | ||
| 522 | timeo = schedule_timeout(timeo); | ||
| 523 | lock_sock(sk); | ||
| 524 | } | 524 | } |
| 525 | set_current_state(TASK_RUNNING); | 525 | __set_current_state(TASK_RUNNING); |
| 526 | remove_wait_queue(sk_sleep(sk), &wait); | 526 | remove_wait_queue(sk_sleep(sk), &wait); |
| 527 | 527 | ||
| 528 | if (err) | 528 | if (err) |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 4c3621b5e0aa..8270f05e3f1f 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
| 564 | 564 | ||
| 565 | lock_sock(sk); | 565 | lock_sock(sk); |
| 566 | 566 | ||
| 567 | if (sk->sk_state != BT_LISTEN) { | ||
| 568 | err = -EBADFD; | ||
| 569 | goto done; | ||
| 570 | } | ||
| 571 | |||
| 572 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 567 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
| 573 | 568 | ||
| 574 | BT_DBG("sk %p timeo %ld", sk, timeo); | 569 | BT_DBG("sk %p timeo %ld", sk, timeo); |
| 575 | 570 | ||
| 576 | /* Wait for an incoming connection. (wake-one). */ | 571 | /* Wait for an incoming connection. (wake-one). */ |
| 577 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 572 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
| 578 | while (!(ch = bt_accept_dequeue(sk, newsock))) { | 573 | while (1) { |
| 579 | set_current_state(TASK_INTERRUPTIBLE); | 574 | set_current_state(TASK_INTERRUPTIBLE); |
| 580 | if (!timeo) { | 575 | |
| 581 | err = -EAGAIN; | 576 | if (sk->sk_state != BT_LISTEN) { |
| 577 | err = -EBADFD; | ||
| 582 | break; | 578 | break; |
| 583 | } | 579 | } |
| 584 | 580 | ||
| 585 | release_sock(sk); | 581 | ch = bt_accept_dequeue(sk, newsock); |
| 586 | timeo = schedule_timeout(timeo); | 582 | if (ch) |
| 587 | lock_sock(sk); | 583 | break; |
| 588 | 584 | ||
| 589 | if (sk->sk_state != BT_LISTEN) { | 585 | if (!timeo) { |
| 590 | err = -EBADFD; | 586 | err = -EAGAIN; |
| 591 | break; | 587 | break; |
| 592 | } | 588 | } |
| 593 | 589 | ||
| @@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag | |||
| 595 | err = sock_intr_errno(timeo); | 591 | err = sock_intr_errno(timeo); |
| 596 | break; | 592 | break; |
| 597 | } | 593 | } |
| 594 | |||
| 595 | release_sock(sk); | ||
| 596 | timeo = schedule_timeout(timeo); | ||
| 597 | lock_sock(sk); | ||
| 598 | } | 598 | } |
| 599 | set_current_state(TASK_RUNNING); | 599 | __set_current_state(TASK_RUNNING); |
| 600 | remove_wait_queue(sk_sleep(sk), &wait); | 600 | remove_wait_queue(sk_sleep(sk), &wait); |
| 601 | 601 | ||
| 602 | if (err) | 602 | if (err) |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 3176e2e13d9b..e73815456adf 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -231,6 +231,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, | |||
| 231 | int br_add_bridge(struct net *net, const char *name) | 231 | int br_add_bridge(struct net *net, const char *name) |
| 232 | { | 232 | { |
| 233 | struct net_device *dev; | 233 | struct net_device *dev; |
| 234 | int res; | ||
| 234 | 235 | ||
| 235 | dev = alloc_netdev(sizeof(struct net_bridge), name, | 236 | dev = alloc_netdev(sizeof(struct net_bridge), name, |
| 236 | br_dev_setup); | 237 | br_dev_setup); |
| @@ -240,7 +241,10 @@ int br_add_bridge(struct net *net, const char *name) | |||
| 240 | 241 | ||
| 241 | dev_net_set(dev, net); | 242 | dev_net_set(dev, net); |
| 242 | 243 | ||
| 243 | return register_netdev(dev); | 244 | res = register_netdev(dev); |
| 245 | if (res) | ||
| 246 | free_netdev(dev); | ||
| 247 | return res; | ||
| 244 | } | 248 | } |
| 245 | 249 | ||
| 246 | int br_del_bridge(struct net *net, const char *name) | 250 | int br_del_bridge(struct net *net, const char *name) |
| @@ -417,6 +421,7 @@ put_back: | |||
| 417 | int br_del_if(struct net_bridge *br, struct net_device *dev) | 421 | int br_del_if(struct net_bridge *br, struct net_device *dev) |
| 418 | { | 422 | { |
| 419 | struct net_bridge_port *p; | 423 | struct net_bridge_port *p; |
| 424 | bool changed_addr; | ||
| 420 | 425 | ||
| 421 | p = br_port_get_rtnl(dev); | 426 | p = br_port_get_rtnl(dev); |
| 422 | if (!p || p->br != br) | 427 | if (!p || p->br != br) |
| @@ -425,9 +430,12 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
| 425 | del_nbp(p); | 430 | del_nbp(p); |
| 426 | 431 | ||
| 427 | spin_lock_bh(&br->lock); | 432 | spin_lock_bh(&br->lock); |
| 428 | br_stp_recalculate_bridge_id(br); | 433 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 429 | spin_unlock_bh(&br->lock); | 434 | spin_unlock_bh(&br->lock); |
| 430 | 435 | ||
| 436 | if (changed_addr) | ||
| 437 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
| 438 | |||
| 431 | netdev_update_features(br->dev); | 439 | netdev_update_features(br->dev); |
| 432 | 440 | ||
| 433 | return 0; | 441 | return 0; |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 2d85ca7111d3..995cbe0ac0b2 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -1456,7 +1456,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
| 1456 | { | 1456 | { |
| 1457 | struct sk_buff *skb2; | 1457 | struct sk_buff *skb2; |
| 1458 | const struct ipv6hdr *ip6h; | 1458 | const struct ipv6hdr *ip6h; |
| 1459 | struct icmp6hdr *icmp6h; | 1459 | u8 icmp6_type; |
| 1460 | u8 nexthdr; | 1460 | u8 nexthdr; |
| 1461 | unsigned len; | 1461 | unsigned len; |
| 1462 | int offset; | 1462 | int offset; |
| @@ -1502,9 +1502,9 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
| 1502 | __skb_pull(skb2, offset); | 1502 | __skb_pull(skb2, offset); |
| 1503 | skb_reset_transport_header(skb2); | 1503 | skb_reset_transport_header(skb2); |
| 1504 | 1504 | ||
| 1505 | icmp6h = icmp6_hdr(skb2); | 1505 | icmp6_type = icmp6_hdr(skb2)->icmp6_type; |
| 1506 | 1506 | ||
| 1507 | switch (icmp6h->icmp6_type) { | 1507 | switch (icmp6_type) { |
| 1508 | case ICMPV6_MGM_QUERY: | 1508 | case ICMPV6_MGM_QUERY: |
| 1509 | case ICMPV6_MGM_REPORT: | 1509 | case ICMPV6_MGM_REPORT: |
| 1510 | case ICMPV6_MGM_REDUCTION: | 1510 | case ICMPV6_MGM_REDUCTION: |
| @@ -1520,16 +1520,23 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
| 1520 | err = pskb_trim_rcsum(skb2, len); | 1520 | err = pskb_trim_rcsum(skb2, len); |
| 1521 | if (err) | 1521 | if (err) |
| 1522 | goto out; | 1522 | goto out; |
| 1523 | err = -EINVAL; | ||
| 1523 | } | 1524 | } |
| 1524 | 1525 | ||
| 1526 | ip6h = ipv6_hdr(skb2); | ||
| 1527 | |||
| 1525 | switch (skb2->ip_summed) { | 1528 | switch (skb2->ip_summed) { |
| 1526 | case CHECKSUM_COMPLETE: | 1529 | case CHECKSUM_COMPLETE: |
| 1527 | if (!csum_fold(skb2->csum)) | 1530 | if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len, |
| 1531 | IPPROTO_ICMPV6, skb2->csum)) | ||
| 1528 | break; | 1532 | break; |
| 1529 | /*FALLTHROUGH*/ | 1533 | /*FALLTHROUGH*/ |
| 1530 | case CHECKSUM_NONE: | 1534 | case CHECKSUM_NONE: |
| 1531 | skb2->csum = 0; | 1535 | skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr, |
| 1532 | if (skb_checksum_complete(skb2)) | 1536 | &ip6h->daddr, |
| 1537 | skb2->len, | ||
| 1538 | IPPROTO_ICMPV6, 0)); | ||
| 1539 | if (__skb_checksum_complete(skb2)) | ||
| 1533 | goto out; | 1540 | goto out; |
| 1534 | } | 1541 | } |
| 1535 | 1542 | ||
| @@ -1537,7 +1544,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
| 1537 | 1544 | ||
| 1538 | BR_INPUT_SKB_CB(skb)->igmp = 1; | 1545 | BR_INPUT_SKB_CB(skb)->igmp = 1; |
| 1539 | 1546 | ||
| 1540 | switch (icmp6h->icmp6_type) { | 1547 | switch (icmp6_type) { |
| 1541 | case ICMPV6_MGM_REPORT: | 1548 | case ICMPV6_MGM_REPORT: |
| 1542 | { | 1549 | { |
| 1543 | struct mld_msg *mld; | 1550 | struct mld_msg *mld; |
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 6545ee9591d1..a76b62135558 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
| @@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
| 34 | struct net_device *dev = ptr; | 34 | struct net_device *dev = ptr; |
| 35 | struct net_bridge_port *p; | 35 | struct net_bridge_port *p; |
| 36 | struct net_bridge *br; | 36 | struct net_bridge *br; |
| 37 | bool changed_addr; | ||
| 37 | int err; | 38 | int err; |
| 38 | 39 | ||
| 39 | /* register of bridge completed, add sysfs entries */ | 40 | /* register of bridge completed, add sysfs entries */ |
| @@ -57,8 +58,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
| 57 | case NETDEV_CHANGEADDR: | 58 | case NETDEV_CHANGEADDR: |
| 58 | spin_lock_bh(&br->lock); | 59 | spin_lock_bh(&br->lock); |
| 59 | br_fdb_changeaddr(p, dev->dev_addr); | 60 | br_fdb_changeaddr(p, dev->dev_addr); |
| 60 | br_stp_recalculate_bridge_id(br); | 61 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 61 | spin_unlock_bh(&br->lock); | 62 | spin_unlock_bh(&br->lock); |
| 63 | |||
| 64 | if (changed_addr) | ||
| 65 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
| 66 | |||
| 62 | break; | 67 | break; |
| 63 | 68 | ||
| 64 | case NETDEV_CHANGE: | 69 | case NETDEV_CHANGE: |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 2b5ca1a0054d..5864cc491369 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
| @@ -1198,7 +1198,8 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table) | |||
| 1198 | 1198 | ||
| 1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { | 1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { |
| 1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); | 1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); |
| 1201 | return ERR_PTR(-EINVAL); | 1201 | ret = -EINVAL; |
| 1202 | goto free_chainstack; | ||
| 1202 | } | 1203 | } |
| 1203 | 1204 | ||
| 1204 | table->private = newinfo; | 1205 | table->private = newinfo; |
diff --git a/net/ceph/msgpool.c b/net/ceph/msgpool.c index d5f2d97ac05c..1f4cb30a42c5 100644 --- a/net/ceph/msgpool.c +++ b/net/ceph/msgpool.c | |||
| @@ -7,27 +7,37 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/ceph/msgpool.h> | 8 | #include <linux/ceph/msgpool.h> |
| 9 | 9 | ||
| 10 | static void *alloc_fn(gfp_t gfp_mask, void *arg) | 10 | static void *msgpool_alloc(gfp_t gfp_mask, void *arg) |
| 11 | { | 11 | { |
| 12 | struct ceph_msgpool *pool = arg; | 12 | struct ceph_msgpool *pool = arg; |
| 13 | void *p; | 13 | struct ceph_msg *msg; |
| 14 | 14 | ||
| 15 | p = ceph_msg_new(0, pool->front_len, gfp_mask); | 15 | msg = ceph_msg_new(0, pool->front_len, gfp_mask); |
| 16 | if (!p) | 16 | if (!msg) { |
| 17 | pr_err("msgpool %s alloc failed\n", pool->name); | 17 | dout("msgpool_alloc %s failed\n", pool->name); |
| 18 | return p; | 18 | } else { |
| 19 | dout("msgpool_alloc %s %p\n", pool->name, msg); | ||
| 20 | msg->pool = pool; | ||
| 21 | } | ||
| 22 | return msg; | ||
| 19 | } | 23 | } |
| 20 | 24 | ||
| 21 | static void free_fn(void *element, void *arg) | 25 | static void msgpool_free(void *element, void *arg) |
| 22 | { | 26 | { |
| 23 | ceph_msg_put(element); | 27 | struct ceph_msgpool *pool = arg; |
| 28 | struct ceph_msg *msg = element; | ||
| 29 | |||
| 30 | dout("msgpool_release %s %p\n", pool->name, msg); | ||
| 31 | msg->pool = NULL; | ||
| 32 | ceph_msg_put(msg); | ||
| 24 | } | 33 | } |
| 25 | 34 | ||
| 26 | int ceph_msgpool_init(struct ceph_msgpool *pool, | 35 | int ceph_msgpool_init(struct ceph_msgpool *pool, |
| 27 | int front_len, int size, bool blocking, const char *name) | 36 | int front_len, int size, bool blocking, const char *name) |
| 28 | { | 37 | { |
| 38 | dout("msgpool %s init\n", name); | ||
| 29 | pool->front_len = front_len; | 39 | pool->front_len = front_len; |
| 30 | pool->pool = mempool_create(size, alloc_fn, free_fn, pool); | 40 | pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool); |
| 31 | if (!pool->pool) | 41 | if (!pool->pool) |
| 32 | return -ENOMEM; | 42 | return -ENOMEM; |
| 33 | pool->name = name; | 43 | pool->name = name; |
| @@ -36,14 +46,17 @@ int ceph_msgpool_init(struct ceph_msgpool *pool, | |||
| 36 | 46 | ||
| 37 | void ceph_msgpool_destroy(struct ceph_msgpool *pool) | 47 | void ceph_msgpool_destroy(struct ceph_msgpool *pool) |
| 38 | { | 48 | { |
| 49 | dout("msgpool %s destroy\n", pool->name); | ||
| 39 | mempool_destroy(pool->pool); | 50 | mempool_destroy(pool->pool); |
| 40 | } | 51 | } |
| 41 | 52 | ||
| 42 | struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, | 53 | struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, |
| 43 | int front_len) | 54 | int front_len) |
| 44 | { | 55 | { |
| 56 | struct ceph_msg *msg; | ||
| 57 | |||
| 45 | if (front_len > pool->front_len) { | 58 | if (front_len > pool->front_len) { |
| 46 | pr_err("msgpool_get pool %s need front %d, pool size is %d\n", | 59 | dout("msgpool_get %s need front %d, pool size is %d\n", |
| 47 | pool->name, front_len, pool->front_len); | 60 | pool->name, front_len, pool->front_len); |
| 48 | WARN_ON(1); | 61 | WARN_ON(1); |
| 49 | 62 | ||
| @@ -51,14 +64,19 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, | |||
| 51 | return ceph_msg_new(0, front_len, GFP_NOFS); | 64 | return ceph_msg_new(0, front_len, GFP_NOFS); |
| 52 | } | 65 | } |
| 53 | 66 | ||
| 54 | return mempool_alloc(pool->pool, GFP_NOFS); | 67 | msg = mempool_alloc(pool->pool, GFP_NOFS); |
| 68 | dout("msgpool_get %s %p\n", pool->name, msg); | ||
| 69 | return msg; | ||
| 55 | } | 70 | } |
| 56 | 71 | ||
| 57 | void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) | 72 | void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) |
| 58 | { | 73 | { |
| 74 | dout("msgpool_put %s %p\n", pool->name, msg); | ||
| 75 | |||
| 59 | /* reset msg front_len; user may have changed it */ | 76 | /* reset msg front_len; user may have changed it */ |
| 60 | msg->front.iov_len = pool->front_len; | 77 | msg->front.iov_len = pool->front_len; |
| 61 | msg->hdr.front_len = cpu_to_le32(pool->front_len); | 78 | msg->hdr.front_len = cpu_to_le32(pool->front_len); |
| 62 | 79 | ||
| 63 | kref_init(&msg->kref); /* retake single ref */ | 80 | kref_init(&msg->kref); /* retake single ref */ |
| 81 | mempool_free(msg, pool->pool); | ||
| 64 | } | 82 | } |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index ce310eee708d..16836a7df7a6 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
| @@ -685,6 +685,18 @@ static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) | |||
| 685 | put_osd(osd); | 685 | put_osd(osd); |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | static void remove_all_osds(struct ceph_osd_client *osdc) | ||
| 689 | { | ||
| 690 | dout("__remove_old_osds %p\n", osdc); | ||
| 691 | mutex_lock(&osdc->request_mutex); | ||
| 692 | while (!RB_EMPTY_ROOT(&osdc->osds)) { | ||
| 693 | struct ceph_osd *osd = rb_entry(rb_first(&osdc->osds), | ||
| 694 | struct ceph_osd, o_node); | ||
| 695 | __remove_osd(osdc, osd); | ||
| 696 | } | ||
| 697 | mutex_unlock(&osdc->request_mutex); | ||
| 698 | } | ||
| 699 | |||
| 688 | static void __move_osd_to_lru(struct ceph_osd_client *osdc, | 700 | static void __move_osd_to_lru(struct ceph_osd_client *osdc, |
| 689 | struct ceph_osd *osd) | 701 | struct ceph_osd *osd) |
| 690 | { | 702 | { |
| @@ -701,14 +713,14 @@ static void __remove_osd_from_lru(struct ceph_osd *osd) | |||
| 701 | list_del_init(&osd->o_osd_lru); | 713 | list_del_init(&osd->o_osd_lru); |
| 702 | } | 714 | } |
| 703 | 715 | ||
| 704 | static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all) | 716 | static void remove_old_osds(struct ceph_osd_client *osdc) |
| 705 | { | 717 | { |
| 706 | struct ceph_osd *osd, *nosd; | 718 | struct ceph_osd *osd, *nosd; |
| 707 | 719 | ||
| 708 | dout("__remove_old_osds %p\n", osdc); | 720 | dout("__remove_old_osds %p\n", osdc); |
| 709 | mutex_lock(&osdc->request_mutex); | 721 | mutex_lock(&osdc->request_mutex); |
| 710 | list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { | 722 | list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { |
| 711 | if (!remove_all && time_before(jiffies, osd->lru_ttl)) | 723 | if (time_before(jiffies, osd->lru_ttl)) |
| 712 | break; | 724 | break; |
| 713 | __remove_osd(osdc, osd); | 725 | __remove_osd(osdc, osd); |
| 714 | } | 726 | } |
| @@ -751,6 +763,7 @@ static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new) | |||
| 751 | struct rb_node *parent = NULL; | 763 | struct rb_node *parent = NULL; |
| 752 | struct ceph_osd *osd = NULL; | 764 | struct ceph_osd *osd = NULL; |
| 753 | 765 | ||
| 766 | dout("__insert_osd %p osd%d\n", new, new->o_osd); | ||
| 754 | while (*p) { | 767 | while (*p) { |
| 755 | parent = *p; | 768 | parent = *p; |
| 756 | osd = rb_entry(parent, struct ceph_osd, o_node); | 769 | osd = rb_entry(parent, struct ceph_osd, o_node); |
| @@ -1144,7 +1157,7 @@ static void handle_osds_timeout(struct work_struct *work) | |||
| 1144 | 1157 | ||
| 1145 | dout("osds timeout\n"); | 1158 | dout("osds timeout\n"); |
| 1146 | down_read(&osdc->map_sem); | 1159 | down_read(&osdc->map_sem); |
| 1147 | remove_old_osds(osdc, 0); | 1160 | remove_old_osds(osdc); |
| 1148 | up_read(&osdc->map_sem); | 1161 | up_read(&osdc->map_sem); |
| 1149 | 1162 | ||
| 1150 | schedule_delayed_work(&osdc->osds_timeout_work, | 1163 | schedule_delayed_work(&osdc->osds_timeout_work, |
| @@ -1862,8 +1875,7 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc) | |||
| 1862 | ceph_osdmap_destroy(osdc->osdmap); | 1875 | ceph_osdmap_destroy(osdc->osdmap); |
| 1863 | osdc->osdmap = NULL; | 1876 | osdc->osdmap = NULL; |
| 1864 | } | 1877 | } |
| 1865 | remove_old_osds(osdc, 1); | 1878 | remove_all_osds(osdc); |
| 1866 | WARN_ON(!RB_EMPTY_ROOT(&osdc->osds)); | ||
| 1867 | mempool_destroy(osdc->req_mempool); | 1879 | mempool_destroy(osdc->req_mempool); |
| 1868 | ceph_msgpool_destroy(&osdc->msgpool_op); | 1880 | ceph_msgpool_destroy(&osdc->msgpool_op); |
| 1869 | ceph_msgpool_destroy(&osdc->msgpool_op_reply); | 1881 | ceph_msgpool_destroy(&osdc->msgpool_op_reply); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8fab9b0bb203..1334d7e56f02 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -1319,11 +1319,15 @@ static void neigh_proxy_process(unsigned long arg) | |||
| 1319 | 1319 | ||
| 1320 | if (tdif <= 0) { | 1320 | if (tdif <= 0) { |
| 1321 | struct net_device *dev = skb->dev; | 1321 | struct net_device *dev = skb->dev; |
| 1322 | |||
| 1322 | __skb_unlink(skb, &tbl->proxy_queue); | 1323 | __skb_unlink(skb, &tbl->proxy_queue); |
| 1323 | if (tbl->proxy_redo && netif_running(dev)) | 1324 | if (tbl->proxy_redo && netif_running(dev)) { |
| 1325 | rcu_read_lock(); | ||
| 1324 | tbl->proxy_redo(skb); | 1326 | tbl->proxy_redo(skb); |
| 1325 | else | 1327 | rcu_read_unlock(); |
| 1328 | } else { | ||
| 1326 | kfree_skb(skb); | 1329 | kfree_skb(skb); |
| 1330 | } | ||
| 1327 | 1331 | ||
| 1328 | dev_put(dev); | 1332 | dev_put(dev); |
| 1329 | } else if (!sched_next || tdif < sched_next) | 1333 | } else if (!sched_next || tdif < sched_next) |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index adf84dd8c7b5..52622517e0d8 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -558,13 +558,14 @@ int __netpoll_rx(struct sk_buff *skb) | |||
| 558 | if (skb_shared(skb)) | 558 | if (skb_shared(skb)) |
| 559 | goto out; | 559 | goto out; |
| 560 | 560 | ||
| 561 | iph = (struct iphdr *)skb->data; | ||
| 562 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 561 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
| 563 | goto out; | 562 | goto out; |
| 563 | iph = (struct iphdr *)skb->data; | ||
| 564 | if (iph->ihl < 5 || iph->version != 4) | 564 | if (iph->ihl < 5 || iph->version != 4) |
| 565 | goto out; | 565 | goto out; |
| 566 | if (!pskb_may_pull(skb, iph->ihl*4)) | 566 | if (!pskb_may_pull(skb, iph->ihl*4)) |
| 567 | goto out; | 567 | goto out; |
| 568 | iph = (struct iphdr *)skb->data; | ||
| 568 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) | 569 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) |
| 569 | goto out; | 570 | goto out; |
| 570 | 571 | ||
| @@ -579,6 +580,7 @@ int __netpoll_rx(struct sk_buff *skb) | |||
| 579 | if (pskb_trim_rcsum(skb, len)) | 580 | if (pskb_trim_rcsum(skb, len)) |
| 580 | goto out; | 581 | goto out; |
| 581 | 582 | ||
| 583 | iph = (struct iphdr *)skb->data; | ||
| 582 | if (iph->protocol != IPPROTO_UDP) | 584 | if (iph->protocol != IPPROTO_UDP) |
| 583 | goto out; | 585 | goto out; |
| 584 | 586 | ||
diff --git a/net/core/scm.c b/net/core/scm.c index 4c1ef026d695..811b53fb330e 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
| @@ -192,7 +192,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
| 192 | goto error; | 192 | goto error; |
| 193 | 193 | ||
| 194 | cred->uid = cred->euid = p->creds.uid; | 194 | cred->uid = cred->euid = p->creds.uid; |
| 195 | cred->gid = cred->egid = p->creds.uid; | 195 | cred->gid = cred->egid = p->creds.gid; |
| 196 | put_cred(p->cred); | 196 | put_cred(p->cred); |
| 197 | p->cred = cred; | 197 | p->cred = cred; |
| 198 | } | 198 | } |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 283c0a26e03f..d577199eabd5 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -767,7 +767,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs) | |||
| 767 | break; | 767 | break; |
| 768 | for (i=0; i<nsrcs; i++) { | 768 | for (i=0; i<nsrcs; i++) { |
| 769 | /* skip inactive filters */ | 769 | /* skip inactive filters */ |
| 770 | if (pmc->sfcount[MCAST_INCLUDE] || | 770 | if (psf->sf_count[MCAST_INCLUDE] || |
| 771 | pmc->sfcount[MCAST_EXCLUDE] != | 771 | pmc->sfcount[MCAST_EXCLUDE] != |
| 772 | psf->sf_count[MCAST_EXCLUDE]) | 772 | psf->sf_count[MCAST_EXCLUDE]) |
| 773 | continue; | 773 | continue; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 77d3eded665a..8c6563361ab5 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -122,6 +122,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
| 122 | newskb->pkt_type = PACKET_LOOPBACK; | 122 | newskb->pkt_type = PACKET_LOOPBACK; |
| 123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
| 124 | WARN_ON(!skb_dst(newskb)); | 124 | WARN_ON(!skb_dst(newskb)); |
| 125 | skb_dst_force(newskb); | ||
| 125 | netif_rx_ni(newskb); | 126 | netif_rx_ni(newskb); |
| 126 | return 0; | 127 | return 0; |
| 127 | } | 128 | } |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ab0c9efd1efa..8905e92f896a 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt); | |||
| 1067 | */ | 1067 | */ |
| 1068 | 1068 | ||
| 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, | 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, |
| 1070 | char __user *optval, int __user *optlen) | 1070 | char __user *optval, int __user *optlen, unsigned flags) |
| 1071 | { | 1071 | { |
| 1072 | struct inet_sock *inet = inet_sk(sk); | 1072 | struct inet_sock *inet = inet_sk(sk); |
| 1073 | int val; | 1073 | int val; |
| @@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
| 1240 | 1240 | ||
| 1241 | msg.msg_control = optval; | 1241 | msg.msg_control = optval; |
| 1242 | msg.msg_controllen = len; | 1242 | msg.msg_controllen = len; |
| 1243 | msg.msg_flags = 0; | 1243 | msg.msg_flags = flags; |
| 1244 | 1244 | ||
| 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { | 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { |
| 1246 | struct in_pktinfo info; | 1246 | struct in_pktinfo info; |
| @@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level, | |||
| 1294 | { | 1294 | { |
| 1295 | int err; | 1295 | int err; |
| 1296 | 1296 | ||
| 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0); |
| 1298 | #ifdef CONFIG_NETFILTER | 1298 | #ifdef CONFIG_NETFILTER |
| 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
| 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && | 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && |
| @@ -1327,7 +1327,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, | |||
| 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
| 1328 | ip_getsockopt); | 1328 | ip_getsockopt); |
| 1329 | 1329 | ||
| 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, |
| 1331 | MSG_CMSG_COMPAT); | ||
| 1331 | 1332 | ||
| 1332 | #ifdef CONFIG_NETFILTER | 1333 | #ifdef CONFIG_NETFILTER |
| 1333 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1334 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 2e97e3ec1eb7..929b27bdeb79 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
| @@ -18,17 +18,15 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
| 18 | struct rtable *rt; | 18 | struct rtable *rt; |
| 19 | struct flowi4 fl4 = {}; | 19 | struct flowi4 fl4 = {}; |
| 20 | __be32 saddr = iph->saddr; | 20 | __be32 saddr = iph->saddr; |
| 21 | __u8 flags = 0; | 21 | __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; |
| 22 | unsigned int hh_len; | 22 | unsigned int hh_len; |
| 23 | 23 | ||
| 24 | if (!skb->sk && addr_type != RTN_LOCAL) { | 24 | if (addr_type == RTN_UNSPEC) |
| 25 | if (addr_type == RTN_UNSPEC) | 25 | addr_type = inet_addr_type(net, saddr); |
| 26 | addr_type = inet_addr_type(net, saddr); | 26 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) |
| 27 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) | 27 | flags |= FLOWI_FLAG_ANYSRC; |
| 28 | flags |= FLOWI_FLAG_ANYSRC; | 28 | else |
| 29 | else | 29 | saddr = 0; |
| 30 | saddr = 0; | ||
| 31 | } | ||
| 32 | 30 | ||
| 33 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause | 31 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause |
| 34 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. | 32 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. |
| @@ -38,7 +36,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
| 38 | fl4.flowi4_tos = RT_TOS(iph->tos); | 36 | fl4.flowi4_tos = RT_TOS(iph->tos); |
| 39 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 37 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
| 40 | fl4.flowi4_mark = skb->mark; | 38 | fl4.flowi4_mark = skb->mark; |
| 41 | fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; | 39 | fl4.flowi4_flags = flags; |
| 42 | rt = ip_route_output_key(net, &fl4); | 40 | rt = ip_route_output_key(net, &fl4); |
| 43 | if (IS_ERR(rt)) | 41 | if (IS_ERR(rt)) |
| 44 | return -1; | 42 | return -1; |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 1457acb39cec..61714bd52925 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -563,7 +563,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, | 563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, |
| 564 | RT_SCOPE_UNIVERSE, | 564 | RT_SCOPE_UNIVERSE, |
| 565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, | 565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, |
| 566 | FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0); | 566 | inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP, |
| 567 | daddr, saddr, 0, 0); | ||
| 567 | 568 | ||
| 568 | if (!inet->hdrincl) { | 569 | if (!inet->hdrincl) { |
| 569 | err = raw_probe_proto_opt(&fl4, msg); | 570 | err = raw_probe_proto_opt(&fl4, msg); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index e3dec1c9f09d..075212e41b83 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -722,7 +722,7 @@ static inline bool compare_hash_inputs(const struct rtable *rt1, | |||
| 722 | { | 722 | { |
| 723 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | | 723 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | |
| 724 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 724 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
| 725 | (rt1->rt_iif ^ rt2->rt_iif)) == 0); | 725 | (rt1->rt_route_iif ^ rt2->rt_route_iif)) == 0); |
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | 728 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) |
| @@ -731,8 +731,8 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | |||
| 731 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 731 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
| 732 | (rt1->rt_mark ^ rt2->rt_mark) | | 732 | (rt1->rt_mark ^ rt2->rt_mark) | |
| 733 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | | 733 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | |
| 734 | (rt1->rt_oif ^ rt2->rt_oif) | | 734 | (rt1->rt_route_iif ^ rt2->rt_route_iif) | |
| 735 | (rt1->rt_iif ^ rt2->rt_iif)) == 0; | 735 | (rt1->rt_oif ^ rt2->rt_oif)) == 0; |
| 736 | } | 736 | } |
| 737 | 737 | ||
| 738 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) | 738 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) |
| @@ -2320,8 +2320,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 2320 | rth = rcu_dereference(rth->dst.rt_next)) { | 2320 | rth = rcu_dereference(rth->dst.rt_next)) { |
| 2321 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | | 2321 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | |
| 2322 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | | 2322 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | |
| 2323 | (rth->rt_iif ^ iif) | | 2323 | (rth->rt_route_iif ^ iif) | |
| 2324 | rth->rt_oif | | ||
| 2325 | (rth->rt_key_tos ^ tos)) == 0 && | 2324 | (rth->rt_key_tos ^ tos)) == 0 && |
| 2326 | rth->rt_mark == skb->mark && | 2325 | rth->rt_mark == skb->mark && |
| 2327 | net_eq(dev_net(rth->dst.dev), net) && | 2326 | net_eq(dev_net(rth->dst.dev), net) && |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 92bb9434b338..3bc5c8f7c71b 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
| @@ -276,7 +276,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
| 276 | int mss; | 276 | int mss; |
| 277 | struct rtable *rt; | 277 | struct rtable *rt; |
| 278 | __u8 rcv_wscale; | 278 | __u8 rcv_wscale; |
| 279 | bool ecn_ok; | 279 | bool ecn_ok = false; |
| 280 | 280 | ||
| 281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
| 282 | goto out; | 282 | goto out; |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 9cb191ecaba8..147ede38ab48 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -913,7 +913,7 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt, | |||
| 913 | } | 913 | } |
| 914 | 914 | ||
| 915 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | 915 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, |
| 916 | char __user *optval, int __user *optlen) | 916 | char __user *optval, int __user *optlen, unsigned flags) |
| 917 | { | 917 | { |
| 918 | struct ipv6_pinfo *np = inet6_sk(sk); | 918 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 919 | int len; | 919 | int len; |
| @@ -962,7 +962,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
| 962 | 962 | ||
| 963 | msg.msg_control = optval; | 963 | msg.msg_control = optval; |
| 964 | msg.msg_controllen = len; | 964 | msg.msg_controllen = len; |
| 965 | msg.msg_flags = 0; | 965 | msg.msg_flags = flags; |
| 966 | 966 | ||
| 967 | lock_sock(sk); | 967 | lock_sock(sk); |
| 968 | skb = np->pktoptions; | 968 | skb = np->pktoptions; |
| @@ -1222,7 +1222,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
| 1222 | if(level != SOL_IPV6) | 1222 | if(level != SOL_IPV6) |
| 1223 | return -ENOPROTOOPT; | 1223 | return -ENOPROTOOPT; |
| 1224 | 1224 | ||
| 1225 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | 1225 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0); |
| 1226 | #ifdef CONFIG_NETFILTER | 1226 | #ifdef CONFIG_NETFILTER |
| 1227 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1227 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
| 1228 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { | 1228 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { |
| @@ -1264,7 +1264,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
| 1264 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1264 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
| 1265 | ipv6_getsockopt); | 1265 | ipv6_getsockopt); |
| 1266 | 1266 | ||
| 1267 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | 1267 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, |
| 1268 | MSG_CMSG_COMPAT); | ||
| 1268 | #ifdef CONFIG_NETFILTER | 1269 | #ifdef CONFIG_NETFILTER |
| 1269 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1270 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
| 1270 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { | 1271 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 3e6ebcdb4779..ee7839f4d6e3 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -1059,7 +1059,7 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, | |||
| 1059 | break; | 1059 | break; |
| 1060 | for (i=0; i<nsrcs; i++) { | 1060 | for (i=0; i<nsrcs; i++) { |
| 1061 | /* skip inactive filters */ | 1061 | /* skip inactive filters */ |
| 1062 | if (pmc->mca_sfcount[MCAST_INCLUDE] || | 1062 | if (psf->sf_count[MCAST_INCLUDE] || |
| 1063 | pmc->mca_sfcount[MCAST_EXCLUDE] != | 1063 | pmc->mca_sfcount[MCAST_EXCLUDE] != |
| 1064 | psf->sf_count[MCAST_EXCLUDE]) | 1064 | psf->sf_count[MCAST_EXCLUDE]) |
| 1065 | continue; | 1065 | continue; |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 07bf1085458f..00b15ac7a702 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -672,6 +672,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 672 | if (skb->protocol != htons(ETH_P_IPV6)) | 672 | if (skb->protocol != htons(ETH_P_IPV6)) |
| 673 | goto tx_error; | 673 | goto tx_error; |
| 674 | 674 | ||
| 675 | if (tos == 1) | ||
| 676 | tos = ipv6_get_dsfield(iph6); | ||
| 677 | |||
| 675 | /* ISATAP (RFC4214) - must come before 6to4 */ | 678 | /* ISATAP (RFC4214) - must come before 6to4 */ |
| 676 | if (dev->priv_flags & IFF_ISATAP) { | 679 | if (dev->priv_flags & IFF_ISATAP) { |
| 677 | struct neighbour *neigh = NULL; | 680 | struct neighbour *neigh = NULL; |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 89d5bf806222..ac838965ff34 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
| @@ -165,7 +165,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
| 165 | int mss; | 165 | int mss; |
| 166 | struct dst_entry *dst; | 166 | struct dst_entry *dst; |
| 167 | __u8 rcv_wscale; | 167 | __u8 rcv_wscale; |
| 168 | bool ecn_ok; | 168 | bool ecn_ok = false; |
| 169 | 169 | ||
| 170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
| 171 | goto out; | 171 | goto out; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 866f269183cf..acb44230b251 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -1012,7 +1012,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
| 1012 | cancel_work_sync(&local->reconfig_filter); | 1012 | cancel_work_sync(&local->reconfig_filter); |
| 1013 | 1013 | ||
| 1014 | ieee80211_clear_tx_pending(local); | 1014 | ieee80211_clear_tx_pending(local); |
| 1015 | sta_info_stop(local); | ||
| 1016 | rate_control_deinitialize(local); | 1015 | rate_control_deinitialize(local); |
| 1017 | 1016 | ||
| 1018 | if (skb_queue_len(&local->skb_queue) || | 1017 | if (skb_queue_len(&local->skb_queue) || |
| @@ -1024,6 +1023,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
| 1024 | 1023 | ||
| 1025 | destroy_workqueue(local->workqueue); | 1024 | destroy_workqueue(local->workqueue); |
| 1026 | wiphy_unregister(local->hw.wiphy); | 1025 | wiphy_unregister(local->hw.wiphy); |
| 1026 | sta_info_stop(local); | ||
| 1027 | ieee80211_wep_free(local); | 1027 | ieee80211_wep_free(local); |
| 1028 | ieee80211_led_exit(local); | 1028 | ieee80211_led_exit(local); |
| 1029 | kfree(local->int_scan_req); | 1029 | kfree(local->int_scan_req); |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 5b466cd1272f..84d0fd47636a 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
| @@ -312,6 +312,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | |||
| 312 | } | 312 | } |
| 313 | break; | 313 | break; |
| 314 | case NF_STOLEN: | 314 | case NF_STOLEN: |
| 315 | break; | ||
| 315 | default: | 316 | default: |
| 316 | kfree_skb(skb); | 317 | kfree_skb(skb); |
| 317 | } | 318 | } |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 58107d060846..9c24de10a657 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
| @@ -341,11 +341,11 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 341 | 341 | ||
| 342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | 342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); |
| 343 | if (entry == NULL) | 343 | if (entry == NULL) |
| 344 | return -ENOMEM; | 344 | goto out_entry; |
| 345 | if (domain != NULL) { | 345 | if (domain != NULL) { |
| 346 | entry->domain = kstrdup(domain, GFP_ATOMIC); | 346 | entry->domain = kstrdup(domain, GFP_ATOMIC); |
| 347 | if (entry->domain == NULL) | 347 | if (entry->domain == NULL) |
| 348 | goto cfg_cipsov4_map_add_failure; | 348 | goto out_domain; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | if (addr == NULL && mask == NULL) { | 351 | if (addr == NULL && mask == NULL) { |
| @@ -354,13 +354,13 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 354 | } else if (addr != NULL && mask != NULL) { | 354 | } else if (addr != NULL && mask != NULL) { |
| 355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); | 355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); |
| 356 | if (addrmap == NULL) | 356 | if (addrmap == NULL) |
| 357 | goto cfg_cipsov4_map_add_failure; | 357 | goto out_addrmap; |
| 358 | INIT_LIST_HEAD(&addrmap->list4); | 358 | INIT_LIST_HEAD(&addrmap->list4); |
| 359 | INIT_LIST_HEAD(&addrmap->list6); | 359 | INIT_LIST_HEAD(&addrmap->list6); |
| 360 | 360 | ||
| 361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); | 361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); |
| 362 | if (addrinfo == NULL) | 362 | if (addrinfo == NULL) |
| 363 | goto cfg_cipsov4_map_add_failure; | 363 | goto out_addrinfo; |
| 364 | addrinfo->type_def.cipsov4 = doi_def; | 364 | addrinfo->type_def.cipsov4 = doi_def; |
| 365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; | 365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; |
| 366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; | 366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; |
| @@ -374,7 +374,7 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; | 374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; |
| 375 | } else { | 375 | } else { |
| 376 | ret_val = -EINVAL; | 376 | ret_val = -EINVAL; |
| 377 | goto cfg_cipsov4_map_add_failure; | 377 | goto out_addrmap; |
| 378 | } | 378 | } |
| 379 | 379 | ||
| 380 | ret_val = netlbl_domhsh_add(entry, audit_info); | 380 | ret_val = netlbl_domhsh_add(entry, audit_info); |
| @@ -384,11 +384,15 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
| 384 | return 0; | 384 | return 0; |
| 385 | 385 | ||
| 386 | cfg_cipsov4_map_add_failure: | 386 | cfg_cipsov4_map_add_failure: |
| 387 | cipso_v4_doi_putdef(doi_def); | 387 | kfree(addrinfo); |
| 388 | out_addrinfo: | ||
| 389 | kfree(addrmap); | ||
| 390 | out_addrmap: | ||
| 388 | kfree(entry->domain); | 391 | kfree(entry->domain); |
| 392 | out_domain: | ||
| 389 | kfree(entry); | 393 | kfree(entry); |
| 390 | kfree(addrmap); | 394 | out_entry: |
| 391 | kfree(addrinfo); | 395 | cipso_v4_doi_putdef(doi_def); |
| 392 | return ret_val; | 396 | return ret_val; |
| 393 | } | 397 | } |
| 394 | 398 | ||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 102fc212cd64..e051398fdf6b 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
| @@ -196,8 +196,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | |||
| 196 | 196 | ||
| 197 | skb2->skb_iif = skb->dev->ifindex; | 197 | skb2->skb_iif = skb->dev->ifindex; |
| 198 | skb2->dev = dev; | 198 | skb2->dev = dev; |
| 199 | dev_queue_xmit(skb2); | 199 | err = dev_queue_xmit(skb2); |
| 200 | err = 0; | ||
| 201 | 200 | ||
| 202 | out: | 201 | out: |
| 203 | if (err) { | 202 | if (err) { |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 2a318f2dc3e5..b5d56a22b1d2 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
| @@ -112,7 +112,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc *sch) | |||
| 112 | 112 | ||
| 113 | for (prio = 0; prio < q->bands; prio++) { | 113 | for (prio = 0; prio < q->bands; prio++) { |
| 114 | struct Qdisc *qdisc = q->queues[prio]; | 114 | struct Qdisc *qdisc = q->queues[prio]; |
| 115 | struct sk_buff *skb = qdisc->dequeue(qdisc); | 115 | struct sk_buff *skb = qdisc_dequeue_peeked(qdisc); |
| 116 | if (skb) { | 116 | if (skb) { |
| 117 | qdisc_bstats_update(sch, skb); | 117 | qdisc_bstats_update(sch, skb); |
| 118 | sch->q.qlen--; | 118 | sch->q.qlen--; |
diff --git a/net/socket.c b/net/socket.c index 24a77400b65e..ffe92ca32f2a 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -1965,8 +1965,9 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
| 1965 | * used_address->name_len is initialized to UINT_MAX so that the first | 1965 | * used_address->name_len is initialized to UINT_MAX so that the first |
| 1966 | * destination address never matches. | 1966 | * destination address never matches. |
| 1967 | */ | 1967 | */ |
| 1968 | if (used_address && used_address->name_len == msg_sys->msg_namelen && | 1968 | if (used_address && msg_sys->msg_name && |
| 1969 | !memcmp(&used_address->name, msg->msg_name, | 1969 | used_address->name_len == msg_sys->msg_namelen && |
| 1970 | !memcmp(&used_address->name, msg_sys->msg_name, | ||
| 1970 | used_address->name_len)) { | 1971 | used_address->name_len)) { |
| 1971 | err = sock_sendmsg_nosec(sock, msg_sys, total_len); | 1972 | err = sock_sendmsg_nosec(sock, msg_sys, total_len); |
| 1972 | goto out_freectl; | 1973 | goto out_freectl; |
| @@ -1978,8 +1979,9 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
| 1978 | */ | 1979 | */ |
| 1979 | if (used_address && err >= 0) { | 1980 | if (used_address && err >= 0) { |
| 1980 | used_address->name_len = msg_sys->msg_namelen; | 1981 | used_address->name_len = msg_sys->msg_namelen; |
| 1981 | memcpy(&used_address->name, msg->msg_name, | 1982 | if (msg_sys->msg_name) |
| 1982 | used_address->name_len); | 1983 | memcpy(&used_address->name, msg_sys->msg_name, |
| 1984 | used_address->name_len); | ||
| 1983 | } | 1985 | } |
| 1984 | 1986 | ||
| 1985 | out_freectl: | 1987 | out_freectl: |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 645437cfc464..c14865172da7 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -616,6 +616,9 @@ int wiphy_register(struct wiphy *wiphy) | |||
| 616 | if (res) | 616 | if (res) |
| 617 | goto out_rm_dev; | 617 | goto out_rm_dev; |
| 618 | 618 | ||
| 619 | rtnl_lock(); | ||
| 620 | rdev->wiphy.registered = true; | ||
| 621 | rtnl_unlock(); | ||
| 619 | return 0; | 622 | return 0; |
| 620 | 623 | ||
| 621 | out_rm_dev: | 624 | out_rm_dev: |
| @@ -647,6 +650,10 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
| 647 | { | 650 | { |
| 648 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 651 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
| 649 | 652 | ||
| 653 | rtnl_lock(); | ||
| 654 | rdev->wiphy.registered = false; | ||
| 655 | rtnl_unlock(); | ||
| 656 | |||
| 650 | rfkill_unregister(rdev->rfkill); | 657 | rfkill_unregister(rdev->rfkill); |
| 651 | 658 | ||
| 652 | /* protect the device list */ | 659 | /* protect the device list */ |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index c6e4ca6a7d2e..ff574597a854 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
| @@ -93,7 +93,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) | |||
| 93 | 93 | ||
| 94 | if (rdev->ops->suspend) { | 94 | if (rdev->ops->suspend) { |
| 95 | rtnl_lock(); | 95 | rtnl_lock(); |
| 96 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | 96 | if (rdev->wiphy.registered) |
| 97 | ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); | ||
| 97 | rtnl_unlock(); | 98 | rtnl_unlock(); |
| 98 | } | 99 | } |
| 99 | 100 | ||
| @@ -112,7 +113,8 @@ static int wiphy_resume(struct device *dev) | |||
| 112 | 113 | ||
| 113 | if (rdev->ops->resume) { | 114 | if (rdev->ops->resume) { |
| 114 | rtnl_lock(); | 115 | rtnl_lock(); |
| 115 | ret = rdev->ops->resume(&rdev->wiphy); | 116 | if (rdev->wiphy.registered) |
| 117 | ret = rdev->ops->resume(&rdev->wiphy); | ||
| 116 | rtnl_unlock(); | 118 | rtnl_unlock(); |
| 117 | } | 119 | } |
| 118 | 120 | ||
