sock_rps_record_flow(sk);
  
 -      down_read(¤t->mm->mmap_sem);
+       tp = tcp_sk(sk);
+ 
 +      mmap_read_lock(current->mm);
  
        vma = find_vma(current->mm, address);
        if (!vma || vma->vm_start > address || vma->vm_ops != &tcp_vm_ops) {
                        zc->recv_skip_hint -= remaining;
                        break;
                }
-               ret = vm_insert_page(vma, address + length,
-                                    skb_frag_page(frags));
-               if (ret)
-                       break;
+               pages[pg_idx] = skb_frag_page(frags);
+               pg_idx++;
                length += PAGE_SIZE;
-               seq += PAGE_SIZE;
                zc->recv_skip_hint -= PAGE_SIZE;
                frags++;
+               if (pg_idx == PAGE_BATCH_SIZE) {
+                       ret = tcp_zerocopy_vm_insert_batch(vma, pages, pg_idx,
+                                                          &curr_addr, &length,
+                                                          &seq, zc);
+                       if (ret)
+                               goto out;
+                       pg_idx = 0;
+               }
+       }
+       if (pg_idx) {
+               ret = tcp_zerocopy_vm_insert_batch(vma, pages, pg_idx,
+                                                  &curr_addr, &length, &seq,
+                                                  zc);
        }
  out:
 -      up_read(¤t->mm->mmap_sem);
 +      mmap_read_unlock(current->mm);
        if (length) {
                WRITE_ONCE(tp->copied_seq, seq);
                tcp_rcv_space_adjust(sk);