lkml.org 
[lkml]   [2020]   [Jul]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC 07/11] hv_netvsc: Use HV_HYP_PAGE_SIZE for Hyper-V communication
    Date
    When communicating with Hyper-V, HV_HYP_PAGE_SIZE should be used since
    that's the page size used by Hyper-V and Hyper-V expects all
    page-related data using the unit of HY_HYP_PAGE_SIZE, for example, the
    "pfn" in hv_page_buffer is actually the HV_HYP_PAGE (i.e. the Hyper-V
    page) number.

    In order to support guest whose page size is not 4k, we need to make
    hv_netvsc always use HV_HYP_PAGE_SIZE for Hyper-V communication.

    Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
    ---
    drivers/net/hyperv/netvsc.c | 2 +-
    drivers/net/hyperv/netvsc_drv.c | 46 +++++++++++++++----------------
    drivers/net/hyperv/rndis_filter.c | 12 ++++----
    3 files changed, 30 insertions(+), 30 deletions(-)

    diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
    index ca68aa1df801..02877b560e4d 100644
    --- a/drivers/net/hyperv/netvsc.c
    +++ b/drivers/net/hyperv/netvsc.c
    @@ -791,7 +791,7 @@ static void netvsc_copy_to_send_buf(struct netvsc_device *net_device,
    }

    for (i = 0; i < page_count; i++) {
    - char *src = phys_to_virt(pb[i].pfn << PAGE_SHIFT);
    + char *src = phys_to_virt(pb[i].pfn << HV_HYP_PAGE_SHIFT);
    u32 offset = pb[i].offset;
    u32 len = pb[i].len;

    diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
    index ebcfbae05690..9d9cbaed5441 100644
    --- a/drivers/net/hyperv/netvsc_drv.c
    +++ b/drivers/net/hyperv/netvsc_drv.c
    @@ -373,32 +373,29 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
    return txq;
    }

    -static u32 fill_pg_buf(struct page *page, u32 offset, u32 len,
    +static u32 fill_pg_buf(unsigned long hvpfn, u32 offset, u32 len,
    struct hv_page_buffer *pb)
    {
    int j = 0;

    - /* Deal with compound pages by ignoring unused part
    - * of the page.
    - */
    - page += (offset >> PAGE_SHIFT);
    - offset &= ~PAGE_MASK;
    + hvpfn += offset >> HV_HYP_PAGE_SHIFT;
    + offset = offset & ~HV_HYP_PAGE_MASK;

    while (len > 0) {
    unsigned long bytes;

    - bytes = PAGE_SIZE - offset;
    + bytes = HV_HYP_PAGE_SIZE - offset;
    if (bytes > len)
    bytes = len;
    - pb[j].pfn = page_to_pfn(page);
    + pb[j].pfn = hvpfn;
    pb[j].offset = offset;
    pb[j].len = bytes;

    offset += bytes;
    len -= bytes;

    - if (offset == PAGE_SIZE && len) {
    - page++;
    + if (offset == HV_HYP_PAGE_SIZE && len) {
    + hvpfn++;
    offset = 0;
    j++;
    }
    @@ -421,23 +418,26 @@ static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
    * 2. skb linear data
    * 3. skb fragment data
    */
    - slots_used += fill_pg_buf(virt_to_page(hdr),
    - offset_in_page(hdr),
    - len, &pb[slots_used]);
    + slots_used += fill_pg_buf(virt_to_hvpfn(hdr),
    + offset_in_hvpage(hdr),
    + len,
    + &pb[slots_used]);

    packet->rmsg_size = len;
    packet->rmsg_pgcnt = slots_used;

    - slots_used += fill_pg_buf(virt_to_page(data),
    - offset_in_page(data),
    - skb_headlen(skb), &pb[slots_used]);
    + slots_used += fill_pg_buf(virt_to_hvpfn(data),
    + offset_in_hvpage(data),
    + skb_headlen(skb),
    + &pb[slots_used]);

    for (i = 0; i < frags; i++) {
    skb_frag_t *frag = skb_shinfo(skb)->frags + i;

    - slots_used += fill_pg_buf(skb_frag_page(frag),
    - skb_frag_off(frag),
    - skb_frag_size(frag), &pb[slots_used]);
    + slots_used += fill_pg_buf(page_to_hvpfn(skb_frag_page(frag)),
    + skb_frag_off(frag),
    + skb_frag_size(frag),
    + &pb[slots_used]);
    }
    return slots_used;
    }
    @@ -453,8 +453,8 @@ static int count_skb_frag_slots(struct sk_buff *skb)
    unsigned long offset = skb_frag_off(frag);

    /* Skip unused frames from start of page */
    - offset &= ~PAGE_MASK;
    - pages += PFN_UP(offset + size);
    + offset &= ~HV_HYP_PAGE_MASK;
    + pages += HVPFN_UP(offset + size);
    }
    return pages;
    }
    @@ -462,12 +462,12 @@ static int count_skb_frag_slots(struct sk_buff *skb)
    static int netvsc_get_slots(struct sk_buff *skb)
    {
    char *data = skb->data;
    - unsigned int offset = offset_in_page(data);
    + unsigned int offset = offset_in_hvpage(data);
    unsigned int len = skb_headlen(skb);
    int slots;
    int frag_slots;

    - slots = DIV_ROUND_UP(offset + len, PAGE_SIZE);
    + slots = DIV_ROUND_UP(offset + len, HV_HYP_PAGE_SIZE);
    frag_slots = count_skb_frag_slots(skb);
    return slots + frag_slots;
    }
    diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
    index b81ceba38218..acc8d957bbfc 100644
    --- a/drivers/net/hyperv/rndis_filter.c
    +++ b/drivers/net/hyperv/rndis_filter.c
    @@ -25,7 +25,7 @@

    static void rndis_set_multicast(struct work_struct *w);

    -#define RNDIS_EXT_LEN PAGE_SIZE
    +#define RNDIS_EXT_LEN HV_HYP_PAGE_SIZE
    struct rndis_request {
    struct list_head list_ent;
    struct completion wait_event;
    @@ -215,18 +215,18 @@ static int rndis_filter_send_request(struct rndis_device *dev,
    packet->page_buf_cnt = 1;

    pb[0].pfn = virt_to_phys(&req->request_msg) >>
    - PAGE_SHIFT;
    + HV_HYP_PAGE_SHIFT;
    pb[0].len = req->request_msg.msg_len;
    pb[0].offset =
    - (unsigned long)&req->request_msg & (PAGE_SIZE - 1);
    + (unsigned long)&req->request_msg & (HV_HYP_PAGE_SIZE - 1);

    /* Add one page_buf when request_msg crossing page boundary */
    - if (pb[0].offset + pb[0].len > PAGE_SIZE) {
    + if (pb[0].offset + pb[0].len > HV_HYP_PAGE_SIZE) {
    packet->page_buf_cnt++;
    - pb[0].len = PAGE_SIZE -
    + pb[0].len = HV_HYP_PAGE_SIZE -
    pb[0].offset;
    pb[1].pfn = virt_to_phys((void *)&req->request_msg
    - + pb[0].len) >> PAGE_SHIFT;
    + + pb[0].len) >> HV_HYP_PAGE_SHIFT;
    pb[1].offset = 0;
    pb[1].len = req->request_msg.msg_len -
    pb[0].len;
    --
    2.27.0
    \
     
     \ /
      Last update: 2020-07-21 03:42    [W:4.727 / U:0.384 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site