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:
Roman Dementiev 2015-06-19 13:08:22 +02:00 committed by Thomas Monjalon
parent ba7468997e
commit 63af6fcfe1
4 changed files with 172 additions and 2 deletions

View File

@ -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))

View 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_ */

View 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_ */

View File

@ -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