@@ -129,6 +129,7 @@ struct bcm_op {
129129 struct sock * sk ;
130130 struct net_device * rx_reg_dev ;
131131 spinlock_t bcm_tx_lock ; /* protect currframe/count in runtime updates */
132+ spinlock_t bcm_rx_update_lock ; /* protect filter/timer data updates */
132133};
133134
134135struct bcm_sock {
@@ -293,22 +294,28 @@ static int bcm_proc_show(struct seq_file *m, void *v)
293294 * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
294295 * of the given bcm tx op
295296 */
296- static void bcm_can_tx (struct bcm_op * op )
297+ static void bcm_can_tx (struct bcm_op * op , struct canfd_frame * cf )
297298{
298299 struct sk_buff * skb ;
299300 struct can_skb_ext * csx ;
300301 struct net_device * dev ;
301- struct canfd_frame * cf ;
302+ struct canfd_frame cframe ;
303+ bool cyclic = !cf ;
304+ unsigned int idx = 0 ;
302305 int err ;
303306
304307 /* no target device? => exit */
305308 if (!op -> ifindex )
306309 return ;
307310
308- /* read currframe under lock protection */
309- spin_lock_bh (& op -> bcm_tx_lock );
310- cf = op -> frames + op -> cfsiz * op -> currframe ;
311- spin_unlock_bh (& op -> bcm_tx_lock );
311+ if (cyclic ) {
312+ /* read currframe under lock protection */
313+ spin_lock_bh (& op -> bcm_tx_lock );
314+ idx = op -> currframe ;
315+ memcpy (& cframe , op -> frames + op -> cfsiz * idx , op -> cfsiz );
316+ cf = & cframe ;
317+ spin_unlock_bh (& op -> bcm_tx_lock );
318+ }
312319
313320 dev = dev_get_by_index (sock_net (op -> sk ), op -> ifindex );
314321 if (!dev ) {
@@ -341,14 +348,20 @@ static void bcm_can_tx(struct bcm_op *op)
341348 if (!err )
342349 op -> frames_abs ++ ;
343350
344- op -> currframe ++ ;
351+ /* only advance the cyclic sequence if nothing reset currframe while
352+ * we were sending - a concurrent TX_RESET_MULTI_IDX means this
353+ * frame's bookkeeping belongs to a sequence that no longer exists
354+ */
355+ if (!cyclic || op -> currframe == idx ) {
356+ op -> currframe ++ ;
345357
346- /* reached last frame? */
347- if (op -> currframe >= op -> nframes )
348- op -> currframe = 0 ;
358+ /* reached last frame? */
359+ if (op -> currframe >= op -> nframes )
360+ op -> currframe = 0 ;
349361
350- if (op -> count > 0 )
351- op -> count -- ;
362+ if (op -> count > 0 )
363+ op -> count -- ;
364+ }
352365
353366 spin_unlock_bh (& op -> bcm_tx_lock );
354367out :
@@ -461,7 +474,7 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
461474 struct bcm_msg_head msg_head ;
462475
463476 if (op -> kt_ival1 && (op -> count > 0 )) {
464- bcm_can_tx (op );
477+ bcm_can_tx (op , NULL );
465478 if (!op -> count && (op -> flags & TX_COUNTEVT )) {
466479
467480 /* create notification to user */
@@ -478,7 +491,7 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
478491 }
479492
480493 } else if (op -> kt_ival2 ) {
481- bcm_can_tx (op );
494+ bcm_can_tx (op , NULL );
482495 }
483496
484497 return bcm_tx_set_expiry (op , & op -> timer ) ?
@@ -622,6 +635,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
622635 struct bcm_op * op = container_of (hrtimer , struct bcm_op , timer );
623636 struct bcm_msg_head msg_head ;
624637
638+ spin_lock_bh (& op -> bcm_rx_update_lock );
639+
625640 /* if user wants to be informed, when cyclic CAN-Messages come back */
626641 if ((op -> flags & RX_ANNOUNCE_RESUME ) && op -> last_frames ) {
627642 /* clear received CAN frames to indicate 'nothing received' */
@@ -638,6 +653,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
638653 msg_head .can_id = op -> can_id ;
639654 msg_head .nframes = 0 ;
640655
656+ spin_unlock_bh (& op -> bcm_rx_update_lock );
657+
641658 bcm_send_to_user (op , & msg_head , NULL , 0 );
642659
643660 return HRTIMER_NORESTART ;
@@ -686,15 +703,26 @@ static int bcm_rx_thr_flush(struct bcm_op *op)
686703static enum hrtimer_restart bcm_rx_thr_handler (struct hrtimer * hrtimer )
687704{
688705 struct bcm_op * op = container_of (hrtimer , struct bcm_op , thrtimer );
706+ enum hrtimer_restart ret ;
689707
690- if (bcm_rx_thr_flush (op )) {
708+ spin_lock_bh (& op -> bcm_rx_update_lock );
709+
710+ /* kt_ival2 may have been concurrently cleared by bcm_rx_setup()
711+ * before it cancels this timer - never forward with a zero
712+ * interval in that case.
713+ */
714+ if (bcm_rx_thr_flush (op ) && op -> kt_ival2 ) {
691715 hrtimer_forward_now (hrtimer , op -> kt_ival2 );
692- return HRTIMER_RESTART ;
716+ ret = HRTIMER_RESTART ;
693717 } else {
694718 /* rearm throttle handling */
695719 op -> kt_lastmsg = 0 ;
696- return HRTIMER_NORESTART ;
720+ ret = HRTIMER_NORESTART ;
697721 }
722+
723+ spin_unlock_bh (& op -> bcm_rx_update_lock );
724+
725+ return ret ;
698726}
699727
700728/*
@@ -704,8 +732,10 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
704732{
705733 struct bcm_op * op = (struct bcm_op * )data ;
706734 const struct canfd_frame * rxframe = (struct canfd_frame * )skb -> data ;
735+ struct canfd_frame rtrframe ;
707736 unsigned int i ;
708737 unsigned char traffic_flags ;
738+ bool rtr_frame ;
709739
710740 if (op -> can_id != rxframe -> can_id )
711741 return ;
@@ -729,9 +759,18 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
729759 /* update statistics */
730760 op -> frames_abs ++ ;
731761
732- if (op -> flags & RX_RTR_FRAME ) {
762+ /* snapshot the flag under lock: op->flags/op->frames may be updated
763+ * concurrently by bcm_rx_setup().
764+ */
765+ spin_lock_bh (& op -> bcm_rx_update_lock );
766+ rtr_frame = op -> flags & RX_RTR_FRAME ;
767+ if (rtr_frame )
768+ memcpy (& rtrframe , op -> frames , op -> cfsiz );
769+ spin_unlock_bh (& op -> bcm_rx_update_lock );
770+
771+ if (rtr_frame ) {
733772 /* send reply for RTR-request (placed in op->frames[0]) */
734- bcm_can_tx (op );
773+ bcm_can_tx (op , & rtrframe );
735774 return ;
736775 }
737776
@@ -743,6 +782,8 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
743782 traffic_flags |= RX_OWN ;
744783 }
745784
785+ spin_lock_bh (& op -> bcm_rx_update_lock );
786+
746787 if (op -> flags & RX_FILTER_ID ) {
747788 /* the easiest case */
748789 bcm_rx_update_and_send (op , op -> last_frames , rxframe ,
@@ -778,6 +819,8 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
778819
779820rx_starttimer :
780821 bcm_rx_starttimer (op );
822+
823+ spin_unlock_bh (& op -> bcm_rx_update_lock );
781824}
782825
783826/*
@@ -1116,7 +1159,7 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
11161159 }
11171160
11181161 if (op -> flags & TX_ANNOUNCE )
1119- bcm_can_tx (op );
1162+ bcm_can_tx (op , NULL );
11201163
11211164 if (op -> flags & STARTTIMER )
11221165 bcm_tx_start_timer (op );
@@ -1130,6 +1173,24 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
11301173 return err ;
11311174}
11321175
1176+ static void bcm_rx_setup_rtr_check (struct bcm_msg_head * msg_head ,
1177+ struct bcm_op * op , void * new_frames )
1178+ {
1179+ /* funny feature in RX(!)_SETUP only for RTR-mode:
1180+ * copy can_id into frame BUT without RTR-flag to
1181+ * prevent a full-load-loopback-test ... ;-]
1182+ * normalize this on the staged buffer, before it is
1183+ * ever installed into op->frames.
1184+ */
1185+ if (msg_head -> flags & RX_RTR_FRAME ) {
1186+ struct canfd_frame * frame0 = new_frames ;
1187+
1188+ if ((msg_head -> flags & TX_CP_CAN_ID ) ||
1189+ frame0 -> can_id == op -> can_id )
1190+ frame0 -> can_id = op -> can_id & ~CAN_RTR_FLAG ;
1191+ }
1192+ }
1193+
11331194/*
11341195 * bcm_rx_setup - create or update a bcm rx op (for bcm_sendmsg)
11351196 */
@@ -1164,6 +1225,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
11641225 /* check the given can_id */
11651226 op = bcm_find_op (& bo -> rx_ops , msg_head , ifindex );
11661227 if (op ) {
1228+ void * new_frames = NULL ;
1229+
11671230 /* update existing BCM operation */
11681231
11691232 /*
@@ -1175,19 +1238,48 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
11751238 return - E2BIG ;
11761239
11771240 if (msg_head -> nframes ) {
1178- /* update CAN frames content */
1179- err = memcpy_from_msg (op -> frames , msg ,
1241+ /* get new CAN frames content before locking */
1242+ new_frames = kmalloc (msg_head -> nframes * op -> cfsiz ,
1243+ GFP_KERNEL );
1244+ if (!new_frames )
1245+ return - ENOMEM ;
1246+
1247+ err = memcpy_from_msg (new_frames , msg ,
11801248 msg_head -> nframes * op -> cfsiz );
1181- if (err < 0 )
1249+ if (err < 0 ) {
1250+ kfree (new_frames );
11821251 return err ;
1252+ }
11831253
1184- /* clear last_frames to indicate 'nothing received' */
1185- memset (op -> last_frames , 0 , msg_head -> nframes * op -> cfsiz );
1254+ bcm_rx_setup_rtr_check (msg_head , op , new_frames );
11861255 }
11871256
1257+ spin_lock_bh (& op -> bcm_rx_update_lock );
11881258 op -> nframes = msg_head -> nframes ;
11891259 op -> flags = msg_head -> flags ;
11901260
1261+ if (msg_head -> nframes ) {
1262+ /* update CAN frames content */
1263+ memcpy (op -> frames , new_frames ,
1264+ msg_head -> nframes * op -> cfsiz );
1265+
1266+ /* clear last_frames to indicate 'nothing received' */
1267+ memset (op -> last_frames , 0 ,
1268+ msg_head -> nframes * op -> cfsiz );
1269+ }
1270+
1271+ if (msg_head -> flags & SETTIMER ) {
1272+ op -> ival1 = msg_head -> ival1 ;
1273+ op -> ival2 = msg_head -> ival2 ;
1274+ op -> kt_ival1 = bcm_timeval_to_ktime (msg_head -> ival1 );
1275+ op -> kt_ival2 = bcm_timeval_to_ktime (msg_head -> ival2 );
1276+ op -> kt_lastmsg = 0 ;
1277+ }
1278+ spin_unlock_bh (& op -> bcm_rx_update_lock );
1279+
1280+ /* free temporary frames / kfree(NULL) is safe */
1281+ kfree (new_frames );
1282+
11911283 /* Only an update -> do not call can_rx_register() */
11921284 do_rx_register = 0 ;
11931285
@@ -1198,6 +1290,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
11981290 return - ENOMEM ;
11991291
12001292 spin_lock_init (& op -> bcm_tx_lock );
1293+ spin_lock_init (& op -> bcm_rx_update_lock );
12011294 op -> can_id = msg_head -> can_id ;
12021295 op -> nframes = msg_head -> nframes ;
12031296 op -> cfsiz = CFSIZ (msg_head -> flags );
@@ -1239,6 +1332,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
12391332 kfree (op );
12401333 return err ;
12411334 }
1335+
1336+ bcm_rx_setup_rtr_check (msg_head , op , op -> frames );
12421337 }
12431338
12441339 /* bcm_can_tx / bcm_tx_timeout_handler needs this */
@@ -1266,29 +1361,22 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
12661361 /* check flags */
12671362
12681363 if (op -> flags & RX_RTR_FRAME ) {
1269- struct canfd_frame * frame0 = op -> frames ;
1270-
12711364 /* no timers in RTR-mode */
12721365 hrtimer_cancel (& op -> thrtimer );
12731366 hrtimer_cancel (& op -> timer );
1274-
1275- /*
1276- * funny feature in RX(!)_SETUP only for RTR-mode:
1277- * copy can_id into frame BUT without RTR-flag to
1278- * prevent a full-load-loopback-test ... ;-]
1279- */
1280- if ((op -> flags & TX_CP_CAN_ID ) ||
1281- (frame0 -> can_id == op -> can_id ))
1282- frame0 -> can_id = op -> can_id & ~CAN_RTR_FLAG ;
1283-
12841367 } else {
12851368 if (op -> flags & SETTIMER ) {
12861369
1287- /* set timer value */
1288- op -> ival1 = msg_head -> ival1 ;
1289- op -> ival2 = msg_head -> ival2 ;
1290- op -> kt_ival1 = bcm_timeval_to_ktime (msg_head -> ival1 );
1291- op -> kt_ival2 = bcm_timeval_to_ktime (msg_head -> ival2 );
1370+ /* set timers (locked) for newly created op */
1371+ if (do_rx_register ) {
1372+ spin_lock_bh (& op -> bcm_rx_update_lock );
1373+ op -> ival1 = msg_head -> ival1 ;
1374+ op -> ival2 = msg_head -> ival2 ;
1375+ op -> kt_ival1 = bcm_timeval_to_ktime (msg_head -> ival1 );
1376+ op -> kt_ival2 = bcm_timeval_to_ktime (msg_head -> ival2 );
1377+ op -> kt_lastmsg = 0 ;
1378+ spin_unlock_bh (& op -> bcm_rx_update_lock );
1379+ }
12921380
12931381 /* disable an active timer due to zero value? */
12941382 if (!op -> kt_ival1 )
@@ -1298,9 +1386,11 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
12981386 * In any case cancel the throttle timer, flush
12991387 * potentially blocked msgs and reset throttle handling
13001388 */
1301- op -> kt_lastmsg = 0 ;
13021389 hrtimer_cancel (& op -> thrtimer );
1390+
1391+ spin_lock_bh (& op -> bcm_rx_update_lock );
13031392 bcm_rx_thr_flush (op );
1393+ spin_unlock_bh (& op -> bcm_rx_update_lock );
13041394 }
13051395
13061396 if ((op -> flags & STARTTIMER ) && op -> kt_ival1 )
0 commit comments