msm: rmnet: reschedule read tasklet in low memory conditions

If the read tasklet is unable to allocate a skb due to low memory
conditions, reschedule the tasklet to retry at some point in the future.

CRs-Fixed: 295596
Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org>
diff --git a/drivers/net/msm_rmnet.c b/drivers/net/msm_rmnet.c
index c9f5f43..6fa0ed6 100644
--- a/drivers/net/msm_rmnet.c
+++ b/drivers/net/msm_rmnet.c
@@ -256,6 +256,9 @@
 	return protocol;
 }
 
+static void smd_net_data_handler(unsigned long arg);
+static DECLARE_TASKLET(smd_net_data_tasklet, smd_net_data_handler, 0);
+
 /* Called in soft-irq context */
 static void smd_net_data_handler(unsigned long arg)
 {
@@ -276,6 +279,10 @@
 		if (skb == NULL) {
 			pr_err("[%s] rmnet_recv() cannot allocate skb\n",
 			       dev->name);
+			/* out of memory, reschedule a later attempt */
+			smd_net_data_tasklet.data = (unsigned long)dev;
+			tasklet_schedule(&smd_net_data_tasklet);
+			break;
 		} else {
 			skb->dev = dev;
 			skb_reserve(skb, NET_IP_ALIGN);
@@ -325,8 +332,6 @@
 	}
 }
 
-static DECLARE_TASKLET(smd_net_data_tasklet, smd_net_data_handler, 0);
-
 static int _rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct rmnet_private *p = netdev_priv(dev);