rwlock: add HTM lock elision for x86
This patch adds methods that use hardware memory transactions (HTM) on fast-path for rwlock (a.k.a. lock elision). Here the methods are implemented for x86 using Restricted Transactional Memory instructions (Intel(r) Transactional Synchronization Extensions). The implementation fall-backs to the normal rwlock if HTM is not available or memory transactions fail. This is not a replacement for all rwlock usages since not all critical sections protected by locks are friendly to HTM. For example, an attempt to perform a HW I/O operation inside a hardware memory transaction always aborts the transaction since the CPU is not able to roll-back should the transaction fail. Therefore, hardware transactional locks are not advised to be used around rte_eth_rx_burst() and rte_eth_tx_burst() calls. Signed-off-by: Roman Dementiev <roman.dementiev@intel.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
This commit is contained in:
parent
ba7468997e
commit
63af6fcfe1
@ -35,7 +35,7 @@ INC := rte_branch_prediction.h rte_common.h
|
||||
INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
|
||||
INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
|
||||
INC += rte_pci_dev_ids.h rte_per_lcore.h rte_random.h
|
||||
INC += rte_rwlock.h rte_tailq.h rte_interrupts.h rte_alarm.h
|
||||
INC += rte_tailq.h rte_interrupts.h rte_alarm.h
|
||||
INC += rte_string_fns.h rte_version.h
|
||||
INC += rte_eal_memconfig.h rte_malloc_heap.h
|
||||
INC += rte_hexdump.h rte_devargs.h rte_dev.h
|
||||
@ -46,7 +46,7 @@ INC += rte_warnings.h
|
||||
endif
|
||||
|
||||
GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h
|
||||
GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h
|
||||
GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h
|
||||
# defined in mk/arch/$(RTE_ARCH)/rte.vars.mk
|
||||
ARCH_DIR ?= $(RTE_ARCH)
|
||||
ARCH_INC := $(notdir $(wildcard $(RTE_SDK)/lib/librte_eal/common/include/arch/$(ARCH_DIR)/*.h))
|
||||
|
38
lib/librte_eal/common/include/arch/ppc_64/rte_rwlock.h
Normal file
38
lib/librte_eal/common/include/arch/ppc_64/rte_rwlock.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef _RTE_RWLOCK_PPC_64_H_
|
||||
#define _RTE_RWLOCK_PPC_64_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "generic/rte_rwlock.h"
|
||||
|
||||
static inline void
|
||||
rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
rte_rwlock_read_lock(rwl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
rte_rwlock_read_unlock(rwl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
rte_rwlock_write_lock(rwl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
rte_rwlock_write_unlock(rwl);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RTE_RWLOCK_PPC_64_H_ */
|
82
lib/librte_eal/common/include/arch/x86/rte_rwlock.h
Normal file
82
lib/librte_eal/common/include/arch/x86/rte_rwlock.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _RTE_RWLOCK_X86_64_H_
|
||||
#define _RTE_RWLOCK_X86_64_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "generic/rte_rwlock.h"
|
||||
#include "rte_spinlock.h"
|
||||
|
||||
static inline void
|
||||
rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
if (likely(rte_try_tm(&rwl->cnt)))
|
||||
return;
|
||||
rte_rwlock_read_lock(rwl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
if (unlikely(rwl->cnt))
|
||||
rte_rwlock_read_unlock(rwl);
|
||||
else
|
||||
rte_xend();
|
||||
}
|
||||
|
||||
static inline void
|
||||
rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
if (likely(rte_try_tm(&rwl->cnt)))
|
||||
return;
|
||||
rte_rwlock_write_lock(rwl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)
|
||||
{
|
||||
if (unlikely(rwl->cnt))
|
||||
rte_rwlock_write_unlock(rwl);
|
||||
else
|
||||
rte_xend();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RTE_RWLOCK_X86_64_H_ */
|
@ -151,6 +151,56 @@ rte_rwlock_write_unlock(rte_rwlock_t *rwl)
|
||||
rte_atomic32_inc((rte_atomic32_t *)(intptr_t)&rwl->cnt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to execute critical section in a hardware memory transaction, if it
|
||||
* fails or not available take a read lock
|
||||
*
|
||||
* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
|
||||
* transaction always aborts the transaction since the CPU is not able to
|
||||
* roll-back should the transaction fail. Therefore, hardware transactional
|
||||
* locks are not advised to be used around rte_eth_rx_burst() and
|
||||
* rte_eth_tx_burst() calls.
|
||||
*
|
||||
* @param rwl
|
||||
* A pointer to a rwlock structure.
|
||||
*/
|
||||
static inline void
|
||||
rte_rwlock_read_lock_tm(rte_rwlock_t *rwl);
|
||||
|
||||
/**
|
||||
* Commit hardware memory transaction or release the read lock if the lock is used as a fall-back
|
||||
*
|
||||
* @param rwl
|
||||
* A pointer to the rwlock structure.
|
||||
*/
|
||||
static inline void
|
||||
rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl);
|
||||
|
||||
/**
|
||||
* Try to execute critical section in a hardware memory transaction, if it
|
||||
* fails or not available take a write lock
|
||||
*
|
||||
* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
|
||||
* transaction always aborts the transaction since the CPU is not able to
|
||||
* roll-back should the transaction fail. Therefore, hardware transactional
|
||||
* locks are not advised to be used around rte_eth_rx_burst() and
|
||||
* rte_eth_tx_burst() calls.
|
||||
*
|
||||
* @param rwl
|
||||
* A pointer to a rwlock structure.
|
||||
*/
|
||||
static inline void
|
||||
rte_rwlock_write_lock_tm(rte_rwlock_t *rwl);
|
||||
|
||||
/**
|
||||
* Commit hardware memory transaction or release the write lock if the lock is used as a fall-back
|
||||
*
|
||||
* @param rwl
|
||||
* A pointer to a rwlock structure.
|
||||
*/
|
||||
static inline void
|
||||
rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user