}
 }
 
+static void netvsc_process_raw_pkt(struct hv_device *device,
+                                  struct vmbus_channel *channel,
+                                  struct netvsc_device *net_device,
+                                  struct net_device *ndev,
+                                  u64 request_id,
+                                  struct vmpacket_descriptor *desc)
+{
+       struct nvsp_message *nvmsg;
+
+       nvmsg = (struct nvsp_message *)((unsigned long)
+               desc + (desc->offset8 << 3));
+
+       switch (desc->type) {
+       case VM_PKT_COMP:
+               netvsc_send_completion(net_device, channel, device, desc);
+               break;
+
+       case VM_PKT_DATA_USING_XFER_PAGES:
+               netvsc_receive(net_device, channel, device, desc);
+               break;
+
+       case VM_PKT_DATA_INBAND:
+               netvsc_receive_inband(device, net_device, nvmsg);
+               break;
+
+       default:
+               netdev_err(ndev, "unhandled packet type %d, tid %llx\n",
+                          desc->type, request_id);
+               break;
+       }
+}
+
+
 void netvsc_channel_cb(void *context)
 {
        int ret;
        unsigned char *buffer;
        int bufferlen = NETVSC_PACKET_SIZE;
        struct net_device *ndev;
-       struct nvsp_message *nvmsg;
+       bool need_to_commit = false;
 
        if (channel->primary_channel != NULL)
                device = channel->primary_channel->device_obj;
        buffer = get_per_channel_state(channel);
 
        do {
+               desc = get_next_pkt_raw(channel);
+               if (desc != NULL) {
+                       netvsc_process_raw_pkt(device,
+                                              channel,
+                                              net_device,
+                                              ndev,
+                                              desc->trans_id,
+                                              desc);
+
+                       put_pkt_raw(channel, desc);
+                       need_to_commit = true;
+                       continue;
+               }
+               if (need_to_commit) {
+                       need_to_commit = false;
+                       commit_rd_index(channel);
+               }
+
                ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
                                           &bytes_recvd, &request_id);
                if (ret == 0) {
                        if (bytes_recvd > 0) {
                                desc = (struct vmpacket_descriptor *)buffer;
-                               nvmsg = (struct nvsp_message *)((unsigned long)
-                                        desc + (desc->offset8 << 3));
-                               switch (desc->type) {
-                               case VM_PKT_COMP:
-                                       netvsc_send_completion(net_device,
-                                                               channel,
-                                                               device, desc);
-                                       break;
-
-                               case VM_PKT_DATA_USING_XFER_PAGES:
-                                       netvsc_receive(net_device, channel,
-                                                      device, desc);
-                                       break;
-
-                               case VM_PKT_DATA_INBAND:
-                                       netvsc_receive_inband(device,
-                                                             net_device,
-                                                             nvmsg);
-                                       break;
-
-                               default:
-                                       netdev_err(ndev,
-                                                  "unhandled packet type %d, "
-                                                  "tid %llx len %d\n",
-                                                  desc->type, request_id,
-                                                  bytes_recvd);
-                                       break;
-                               }
+                               netvsc_process_raw_pkt(device,
+                                                      channel,
+                                                      net_device,
+                                                      ndev,
+                                                      request_id,
+                                                      desc);
+
 
                        } else {
                                /*