diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-11 06:22:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-12 15:35:25 -0400 |
commit | 29b4433d991c88d86ca48a4c1cc33c671475be4b (patch) | |
tree | 2ad21b86aab8193c4533820c40cd31af97a7377f /drivers/infiniband/hw | |
parent | f0b9f4725180ea58c8da78b3de0b4e0ad180fc2c (diff) |
net: percpu net_device refcount
We tried very hard to remove all possible dev_hold()/dev_put() pairs in
network stack, using RCU conversions.
There is still an unavoidable device refcount change for every dst we
create/destroy, and this can slow down some workloads (routers or some
app servers, mmap af_packet)
We can switch to a percpu refcount implementation, now dynamic per_cpu
infrastructure is mature. On a 64 cpus machine, this consumes 256 bytes
per device.
On x86, dev_hold(dev) code :
before
lock incl 0x280(%ebx)
after:
movl 0x260(%ebx),%eax
incl fs:(%eax)
Stress bench :
(Sending 160.000.000 UDP frames,
IP route cache disabled, dual E5540 @2.53GHz,
32bit kernel, FIB_TRIE)
Before:
real 1m1.662s
user 0m14.373s
sys 12m55.960s
After:
real 0m51.179s
user 0m15.329s
sys 10m15.942s
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 4 |
2 files changed, 4 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 61e0efd4ccfb..6220d9d75b58 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -2701,7 +2701,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt) | |||
2701 | nesibdev = nesvnic->nesibdev; | 2701 | nesibdev = nesvnic->nesibdev; |
2702 | 2702 | ||
2703 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", | 2703 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", |
2704 | atomic_read(&nesvnic->netdev->refcnt)); | 2704 | netdev_refcnt_read(nesvnic->netdev)); |
2705 | 2705 | ||
2706 | if (nesqp->active_conn) { | 2706 | if (nesqp->active_conn) { |
2707 | 2707 | ||
@@ -2791,7 +2791,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2791 | atomic_inc(&cm_accepts); | 2791 | atomic_inc(&cm_accepts); |
2792 | 2792 | ||
2793 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", | 2793 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", |
2794 | atomic_read(&nesvnic->netdev->refcnt)); | 2794 | netdev_refcnt_read(nesvnic->netdev)); |
2795 | 2795 | ||
2796 | /* allocate the ietf frame and space for private data */ | 2796 | /* allocate the ietf frame and space for private data */ |
2797 | nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, | 2797 | nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 9046e6675686..546fc22405fe 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -785,7 +785,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, | |||
785 | 785 | ||
786 | nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n", | 786 | nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n", |
787 | nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context, | 787 | nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context, |
788 | atomic_read(&nesvnic->netdev->refcnt)); | 788 | netdev_refcnt_read(nesvnic->netdev)); |
789 | 789 | ||
790 | err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds, | 790 | err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds, |
791 | nesadapter->max_pd, &pd_num, &nesadapter->next_pd); | 791 | nesadapter->max_pd, &pd_num, &nesadapter->next_pd); |
@@ -1416,7 +1416,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1416 | /* update the QP table */ | 1416 | /* update the QP table */ |
1417 | nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; | 1417 | nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; |
1418 | nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", | 1418 | nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", |
1419 | atomic_read(&nesvnic->netdev->refcnt)); | 1419 | netdev_refcnt_read(nesvnic->netdev)); |
1420 | 1420 | ||
1421 | return &nesqp->ibqp; | 1421 | return &nesqp->ibqp; |
1422 | } | 1422 | } |