diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-02-26 15:34:42 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-02-26 15:34:42 -0500 |
commit | 8e22e1b3499a446df48c2b26667ca36c55bf864c (patch) | |
tree | 5329f98b3eb3c95a9dcbab0fa4f9b6e62f0e788d /net/can | |
parent | 00d3c14f14d51babd8aeafd5fa734ccf04f5ca3d (diff) | |
parent | 64a577196d66b44e37384bc5c4d78c61f59d5b2a (diff) |
Merge airlied/drm-next into drm-misc-next
Backmerge the main pull request to sync up with all the newly landed
drivers. Otherwise we'll have chaos even before 4.12 started in
earnest.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'net/can')
-rw-r--r-- | net/can/af_can.c | 12 | ||||
-rw-r--r-- | net/can/af_can.h | 3 | ||||
-rw-r--r-- | net/can/bcm.c | 27 | ||||
-rw-r--r-- | net/can/gw.c | 2 | ||||
-rw-r--r-- | net/can/raw.c | 4 |
5 files changed, 33 insertions, 15 deletions
diff --git a/net/can/af_can.c b/net/can/af_can.c index 1108079d934f..5488e4a6ccd0 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -445,6 +445,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, | |||
445 | * @func: callback function on filter match | 445 | * @func: callback function on filter match |
446 | * @data: returned parameter for callback function | 446 | * @data: returned parameter for callback function |
447 | * @ident: string for calling module identification | 447 | * @ident: string for calling module identification |
448 | * @sk: socket pointer (might be NULL) | ||
448 | * | 449 | * |
449 | * Description: | 450 | * Description: |
450 | * Invokes the callback function with the received sk_buff and the given | 451 | * Invokes the callback function with the received sk_buff and the given |
@@ -468,7 +469,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask, | |||
468 | */ | 469 | */ |
469 | int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | 470 | int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, |
470 | void (*func)(struct sk_buff *, void *), void *data, | 471 | void (*func)(struct sk_buff *, void *), void *data, |
471 | char *ident) | 472 | char *ident, struct sock *sk) |
472 | { | 473 | { |
473 | struct receiver *r; | 474 | struct receiver *r; |
474 | struct hlist_head *rl; | 475 | struct hlist_head *rl; |
@@ -496,6 +497,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, | |||
496 | r->func = func; | 497 | r->func = func; |
497 | r->data = data; | 498 | r->data = data; |
498 | r->ident = ident; | 499 | r->ident = ident; |
500 | r->sk = sk; | ||
499 | 501 | ||
500 | hlist_add_head_rcu(&r->list, rl); | 502 | hlist_add_head_rcu(&r->list, rl); |
501 | d->entries++; | 503 | d->entries++; |
@@ -520,8 +522,11 @@ EXPORT_SYMBOL(can_rx_register); | |||
520 | static void can_rx_delete_receiver(struct rcu_head *rp) | 522 | static void can_rx_delete_receiver(struct rcu_head *rp) |
521 | { | 523 | { |
522 | struct receiver *r = container_of(rp, struct receiver, rcu); | 524 | struct receiver *r = container_of(rp, struct receiver, rcu); |
525 | struct sock *sk = r->sk; | ||
523 | 526 | ||
524 | kmem_cache_free(rcv_cache, r); | 527 | kmem_cache_free(rcv_cache, r); |
528 | if (sk) | ||
529 | sock_put(sk); | ||
525 | } | 530 | } |
526 | 531 | ||
527 | /** | 532 | /** |
@@ -596,8 +601,11 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, | |||
596 | spin_unlock(&can_rcvlists_lock); | 601 | spin_unlock(&can_rcvlists_lock); |
597 | 602 | ||
598 | /* schedule the receiver item for deletion */ | 603 | /* schedule the receiver item for deletion */ |
599 | if (r) | 604 | if (r) { |
605 | if (r->sk) | ||
606 | sock_hold(r->sk); | ||
600 | call_rcu(&r->rcu, can_rx_delete_receiver); | 607 | call_rcu(&r->rcu, can_rx_delete_receiver); |
608 | } | ||
601 | } | 609 | } |
602 | EXPORT_SYMBOL(can_rx_unregister); | 610 | EXPORT_SYMBOL(can_rx_unregister); |
603 | 611 | ||
diff --git a/net/can/af_can.h b/net/can/af_can.h index fca0fe9fc45a..b86f5129e838 100644 --- a/net/can/af_can.h +++ b/net/can/af_can.h | |||
@@ -50,13 +50,14 @@ | |||
50 | 50 | ||
51 | struct receiver { | 51 | struct receiver { |
52 | struct hlist_node list; | 52 | struct hlist_node list; |
53 | struct rcu_head rcu; | ||
54 | canid_t can_id; | 53 | canid_t can_id; |
55 | canid_t mask; | 54 | canid_t mask; |
56 | unsigned long matches; | 55 | unsigned long matches; |
57 | void (*func)(struct sk_buff *, void *); | 56 | void (*func)(struct sk_buff *, void *); |
58 | void *data; | 57 | void *data; |
59 | char *ident; | 58 | char *ident; |
59 | struct sock *sk; | ||
60 | struct rcu_head rcu; | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS) | 63 | #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS) |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 21ac75390e3d..95d13b233c65 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -734,14 +734,23 @@ static struct bcm_op *bcm_find_op(struct list_head *ops, | |||
734 | 734 | ||
735 | static void bcm_remove_op(struct bcm_op *op) | 735 | static void bcm_remove_op(struct bcm_op *op) |
736 | { | 736 | { |
737 | hrtimer_cancel(&op->timer); | 737 | if (op->tsklet.func) { |
738 | hrtimer_cancel(&op->thrtimer); | 738 | while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) || |
739 | 739 | test_bit(TASKLET_STATE_RUN, &op->tsklet.state) || | |
740 | if (op->tsklet.func) | 740 | hrtimer_active(&op->timer)) { |
741 | tasklet_kill(&op->tsklet); | 741 | hrtimer_cancel(&op->timer); |
742 | tasklet_kill(&op->tsklet); | ||
743 | } | ||
744 | } | ||
742 | 745 | ||
743 | if (op->thrtsklet.func) | 746 | if (op->thrtsklet.func) { |
744 | tasklet_kill(&op->thrtsklet); | 747 | while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) || |
748 | test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) || | ||
749 | hrtimer_active(&op->thrtimer)) { | ||
750 | hrtimer_cancel(&op->thrtimer); | ||
751 | tasklet_kill(&op->thrtsklet); | ||
752 | } | ||
753 | } | ||
745 | 754 | ||
746 | if ((op->frames) && (op->frames != &op->sframe)) | 755 | if ((op->frames) && (op->frames != &op->sframe)) |
747 | kfree(op->frames); | 756 | kfree(op->frames); |
@@ -1216,7 +1225,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
1216 | err = can_rx_register(dev, op->can_id, | 1225 | err = can_rx_register(dev, op->can_id, |
1217 | REGMASK(op->can_id), | 1226 | REGMASK(op->can_id), |
1218 | bcm_rx_handler, op, | 1227 | bcm_rx_handler, op, |
1219 | "bcm"); | 1228 | "bcm", sk); |
1220 | 1229 | ||
1221 | op->rx_reg_dev = dev; | 1230 | op->rx_reg_dev = dev; |
1222 | dev_put(dev); | 1231 | dev_put(dev); |
@@ -1225,7 +1234,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
1225 | } else | 1234 | } else |
1226 | err = can_rx_register(NULL, op->can_id, | 1235 | err = can_rx_register(NULL, op->can_id, |
1227 | REGMASK(op->can_id), | 1236 | REGMASK(op->can_id), |
1228 | bcm_rx_handler, op, "bcm"); | 1237 | bcm_rx_handler, op, "bcm", sk); |
1229 | if (err) { | 1238 | if (err) { |
1230 | /* this bcm rx op is broken -> remove it */ | 1239 | /* this bcm rx op is broken -> remove it */ |
1231 | list_del(&op->list); | 1240 | list_del(&op->list); |
diff --git a/net/can/gw.c b/net/can/gw.c index a54ab0c82104..7056a1a2bb70 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -442,7 +442,7 @@ static inline int cgw_register_filter(struct cgw_job *gwj) | |||
442 | { | 442 | { |
443 | return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id, | 443 | return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id, |
444 | gwj->ccgw.filter.can_mask, can_can_gw_rcv, | 444 | gwj->ccgw.filter.can_mask, can_can_gw_rcv, |
445 | gwj, "gw"); | 445 | gwj, "gw", NULL); |
446 | } | 446 | } |
447 | 447 | ||
448 | static inline void cgw_unregister_filter(struct cgw_job *gwj) | 448 | static inline void cgw_unregister_filter(struct cgw_job *gwj) |
diff --git a/net/can/raw.c b/net/can/raw.c index b075f028d7e2..6dc546a06673 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -190,7 +190,7 @@ static int raw_enable_filters(struct net_device *dev, struct sock *sk, | |||
190 | for (i = 0; i < count; i++) { | 190 | for (i = 0; i < count; i++) { |
191 | err = can_rx_register(dev, filter[i].can_id, | 191 | err = can_rx_register(dev, filter[i].can_id, |
192 | filter[i].can_mask, | 192 | filter[i].can_mask, |
193 | raw_rcv, sk, "raw"); | 193 | raw_rcv, sk, "raw", sk); |
194 | if (err) { | 194 | if (err) { |
195 | /* clean up successfully registered filters */ | 195 | /* clean up successfully registered filters */ |
196 | while (--i >= 0) | 196 | while (--i >= 0) |
@@ -211,7 +211,7 @@ static int raw_enable_errfilter(struct net_device *dev, struct sock *sk, | |||
211 | 211 | ||
212 | if (err_mask) | 212 | if (err_mask) |
213 | err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG, | 213 | err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG, |
214 | raw_rcv, sk, "raw"); | 214 | raw_rcv, sk, "raw", sk); |
215 | 215 | ||
216 | return err; | 216 | return err; |
217 | } | 217 | } |