Skip to content

Commit

Permalink
net: hns: Optimize hns_nic_common_poll for better performance
Browse files Browse the repository at this point in the history
After polling less than buget packages, we need check again. If
there are still some packages, we call napi_schedule add softirq
queue, this is not better way. So we return buget value instead
of napi_schedule.

Signed-off-by: lipeng <lipeng321@huawei.com>
reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
lipeng authored and David S. Miller committed Apr 3, 2017
1 parent 4b7cdec commit 36eedfd
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 21 deletions.
50 changes: 30 additions & 20 deletions drivers/net/ethernet/hisilicon/hns/hns_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ static int hns_nic_rx_poll_one(struct hns_nic_ring_data *ring_data,
return recv_pkts;
}

static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
static bool hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
{
struct hnae_ring *ring = ring_data->ring;
int num = 0;
Expand All @@ -873,22 +873,23 @@ static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring_data->ring, 1);

napi_schedule(&ring_data->napi);
return false;
} else {
return true;
}
}

static void hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
static bool hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
{
struct hnae_ring *ring = ring_data->ring;
int num = 0;
int num;

num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);

if (num == 0)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring, 0);
if (!num)
return true;
else
napi_schedule(&ring_data->napi);
return false;
}

static inline void hns_nic_reclaim_one_desc(struct hnae_ring *ring,
Expand Down Expand Up @@ -989,7 +990,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data,
return 0;
}

static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
static bool hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
{
struct hnae_ring *ring = ring_data->ring;
int head;
Expand All @@ -1002,20 +1003,21 @@ static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring_data->ring, 1);

napi_schedule(&ring_data->napi);
return false;
} else {
return true;
}
}

static void hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
static bool hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
{
struct hnae_ring *ring = ring_data->ring;
int head = readl_relaxed(ring->io_base + RCB_REG_HEAD);

if (head == ring->next_to_clean)
ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
ring, 0);
return true;
else
napi_schedule(&ring_data->napi);
return false;
}

static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
Expand All @@ -1042,15 +1044,23 @@ static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)

static int hns_nic_common_poll(struct napi_struct *napi, int budget)
{
int clean_complete = 0;
struct hns_nic_ring_data *ring_data =
container_of(napi, struct hns_nic_ring_data, napi);
int clean_complete = ring_data->poll_one(
ring_data, budget, ring_data->ex_process);
struct hnae_ring *ring = ring_data->ring;

if (clean_complete >= 0 && clean_complete < budget) {
napi_complete(napi);
ring_data->fini_process(ring_data);
return 0;
try_again:
clean_complete += ring_data->poll_one(
ring_data, budget - clean_complete,
ring_data->ex_process);

if (clean_complete < budget) {
if (ring_data->fini_process(ring_data)) {
napi_complete(napi);
ring->q->handle->dev->ops->toggle_ring_irq(ring, 0);
} else {
goto try_again;
}
}

return clean_complete;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/hisilicon/hns/hns_enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct hns_nic_ring_data {
int queue_index;
int (*poll_one)(struct hns_nic_ring_data *, int, void *);
void (*ex_process)(struct hns_nic_ring_data *, struct sk_buff *);
void (*fini_process)(struct hns_nic_ring_data *);
bool (*fini_process)(struct hns_nic_ring_data *);
};

/* compatible the difference between two versions */
Expand Down

0 comments on commit 36eedfd

Please sign in to comment.