Re: removing the timer from cdc-ncm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Bjørn Mork <bjorn@xxxxxxx> writes:

> [48880.048494] BUG: unable to handle kernel NULL pointer dereference at 0000000000000068
> [48880.048573] IP: [<ffffffffa06ba879>] cdc_ncm_tx_bundle+0x168/0x43b [cdc_ncm]

This one is because you removed the "if (skb == NULL)" from the for
loop, but left the "skb = NULL;" at the end:


@@ -719,28 +707,15 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
                /* compute maximum buffer size */
                rem = ctx->tx_max - offset;
 
-               if (skb == NULL) {
-                       skb = ctx->tx_rem_skb;
-                       ctx->tx_rem_skb = NULL;
-
-                       /* check for end of skb */
-                       if (skb == NULL)
-                               break;
-               }
-
                if (skb->len > rem) {
                        if (n == 0) {
                                /* won't fit, MTU problem? */
                                dev_kfree_skb_any(skb);
                                skb = NULL;
                                ctx->netdev->stats.tx_dropped++;
+                               error = 1;
                        } else {
-                               /* no room for skb - store for later */
-                               if (ctx->tx_rem_skb != NULL) {
-                                       dev_kfree_skb_any(ctx->tx_rem_skb);
-                                       ctx->netdev->stats.tx_dropped++;
-                               }
-                               ctx->tx_rem_skb = skb;
+
                                skb = NULL;
                                ready2send = 1;
                        }
@@ -768,13 +743,6 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
                skb = NULL;
        }


If I understand your intentions with this code, then the for loop should
probably just go away completely?

Anyway, after avoiding that one, I ended up with

[  857.112692] cdc_ncm_fill_tx_frame: skb_out=ffff880218624cc0, length=2048
[  857.112696] cdc_ncm_tx_fixup: returning           (null)
[  857.112731] BUG: unable to handle kernel NULL pointer dereference at 0000000000000068
[  857.112807] IP: [<ffffffffa030e68b>] usbnet_start_xmit+0x128/0x4e9 [usbnet]

No need for the reset of the trace here. Removing the "goto not_drop"
makes usbnet_start_xmit continue after tx_fixup returns NULL:


-       if (info->tx_fixup) {
+       if (transmit_now && info->tx_fixup) {
                skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
                if (!skb) {
                        if (netif_msg_tx_err(dev)) {
                                netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
                                goto drop;
-                       } else {
-                               /* cdc_ncm collected packet; waits for more */
-                               goto not_drop;
                        }
                }
        }


	// some devices want funky USB-level framing, for
	// win32 driver (usually) and/or hardware quirks
	if (transmit_now && info->tx_fixup) {
		skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
		if (!skb) {
			if (netif_msg_tx_err(dev)) {
				netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n");
				goto drop;
			}
		}
	}
	length = skb->len;



I stopped there.  I am not exactly sure where you were going with this
anymore.  tx_fixup will return the tx_curr_skb being currently built
every time it is called, without anything resetting it at that point.
Then when finally cdc_ncm_fill_tx_frame has been called enough times to
fill it completely, you end up just dropping it on the floor.  The
result is that nothing is ever transmitted even after fixing the above
errors because the tx_curr_skb has an incomplete header every time
tx_fixup returns it.

I do like your idea, but if you don't mind I think we'll go ahead and
base the upcoming cdc_mbim driver on the current cdc_ncm *with* the
timer.  The plan is to reuse as much of cdc_ncm as possible, so in
theory it should be easy to update both drivers when the timer goes away
(there is no need for cdc_mbim be aware of the timer at all).  But
unfortunately it seems that cdc_ncm_fill_tx_frame must be changed a lot
to support the concept of multiple NDPs in a single NTB.  This means
that the timer removal patches will conflict heavily with the
preparations for MBIM support.  With some luck and acceptance from all
contributors, I hope to be able to post the first version of that as the
merge window closes.



Bjørn
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux