mirror of https://github.com/F-Stack/f-stack.git
1. Reduce the number of locks with dirty read first, and then try to lock sc and real read. QPS:360k -> 380k.
2. memory alignment. QPS:380k -> 400k.
This commit is contained in:
parent
4af5a643fb
commit
3cd0ab86b6
|
@ -81,14 +81,17 @@ static __thread struct ff_kevent_args *kevent_args = NULL;
|
|||
} \
|
||||
args = name##_args;
|
||||
|
||||
/* Dirty read first, and then try to lock sc and real read. */
|
||||
#define ACQUIRE_ZONE_LOCK(exp) do { \
|
||||
while (1) { \
|
||||
while (sc->status != exp) { \
|
||||
rte_pause(); \
|
||||
} \
|
||||
rte_spinlock_lock(&sc->lock); \
|
||||
if (sc->status == exp) { \
|
||||
break; \
|
||||
} \
|
||||
rte_spinlock_unlock(&sc->lock); \
|
||||
rte_pause(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -1545,7 +1548,8 @@ kevent(int kq, const struct kevent *changelist, int nchanges,
|
|||
args->kq = kq;
|
||||
args->timeout = (struct timespec *)timeout;
|
||||
|
||||
rte_spinlock_lock(&sc->lock);
|
||||
ACQUIRE_ZONE_LOCK(FF_SC_IDLE);
|
||||
//rte_spinlock_lock(&sc->lock);
|
||||
|
||||
sc->ops = FF_SO_KEVENT;
|
||||
sc->args = args;
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
|
||||
#define SOCKET_OPS_ZONE_NAME "ff_socket_ops_zone_%d"
|
||||
|
||||
/* Must be power of 2 */
|
||||
#define SOCKET_OPS_CONTEXT_MAX_NUM (2 << 5)
|
||||
|
||||
#define SOCKET_OPS_CONTEXT_NAME_SIZE 32
|
||||
#define SOCKET_OPS_CONTEXT_NAME "ff_so_context_"
|
||||
|
||||
|
@ -43,6 +40,10 @@ ff_set_max_so_context(uint16_t count)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (count > SOCKET_OPS_CONTEXT_MAX_NUM) {
|
||||
count = SOCKET_OPS_CONTEXT_MAX_NUM;
|
||||
}
|
||||
|
||||
ff_max_so_context = count;
|
||||
|
||||
return 0;
|
||||
|
@ -82,6 +83,7 @@ ff_create_so_memzone()
|
|||
so_zone_tmp->mask = so_zone_tmp->count - 1;
|
||||
so_zone_tmp->free = so_zone_tmp->count;
|
||||
so_zone_tmp->idx = 0;
|
||||
memset(so_zone_tmp->inuse, 0, SOCKET_OPS_CONTEXT_MAX_NUM);
|
||||
so_zone_tmp->sc = (struct ff_so_context *)(so_zone_tmp + 1);
|
||||
|
||||
for (i = 0; i < ff_max_so_context; i++) {
|
||||
|
@ -89,7 +91,7 @@ ff_create_so_memzone()
|
|||
rte_spinlock_init(&sc->lock);
|
||||
sc->status = FF_SC_IDLE;
|
||||
sc->idx = i;
|
||||
sc->inuse = 0;
|
||||
//so_zone_tmp->inuse[i] = 0;
|
||||
|
||||
if (sem_init(&sc->wait_sem, 1, 0) == -1) {
|
||||
ERR_LOG("Initialize semaphore failed:%d\n", errno);
|
||||
|
@ -155,8 +157,8 @@ ff_attach_so_context(int proc_id)
|
|||
for (i = 0; i < ff_so_zone->count; i++) {
|
||||
uint16_t idx = (ff_so_zone->idx + i) & ff_so_zone->mask;
|
||||
sc = &ff_so_zone->sc[idx];
|
||||
if (sc->inuse == 0) {
|
||||
sc->inuse = 1;
|
||||
if (ff_so_zone->inuse[idx] == 0) {
|
||||
ff_so_zone->inuse[idx] = 1;
|
||||
rte_spinlock_init(&sc->lock);
|
||||
sc->status = FF_SC_IDLE;
|
||||
ff_so_zone->free--;
|
||||
|
@ -190,19 +192,19 @@ ff_detach_so_context(struct ff_so_context *sc)
|
|||
}
|
||||
|
||||
ERR_LOG("detach sc:%p, ops:%d, status:%d, idx:%d, inuse:%d, so free:%u, idx:%u\n",
|
||||
sc, sc->ops, sc->status, sc->idx, sc->inuse, ff_so_zone->free, ff_so_zone->idx);
|
||||
sc, sc->ops, sc->status, sc->idx, ff_so_zone->inuse[sc->idx], ff_so_zone->free, ff_so_zone->idx);
|
||||
|
||||
rte_spinlock_lock(&ff_so_zone->lock);
|
||||
|
||||
if (sc->inuse == 1) {
|
||||
sc->inuse = 0;
|
||||
if (ff_so_zone->inuse[sc->idx] == 1) {
|
||||
ff_so_zone->inuse[sc->idx] = 0;
|
||||
|
||||
ff_so_zone->free++;
|
||||
ff_so_zone->idx = sc->idx;
|
||||
}
|
||||
|
||||
ERR_LOG("detach sc:%p, ops:%d, status:%d, idx:%d, inuse:%d, so free:%u, idx:%u\n",
|
||||
sc, sc->ops, sc->status, sc->idx, sc->inuse, ff_so_zone->free, ff_so_zone->idx);
|
||||
sc, sc->ops, sc->status, sc->idx, ff_so_zone->inuse[sc->idx], ff_so_zone->free, ff_so_zone->idx);
|
||||
|
||||
rte_spinlock_unlock(&ff_so_zone->lock);
|
||||
}
|
||||
|
|
|
@ -450,6 +450,8 @@ ff_handle_socket_ops(struct ff_so_context *sc)
|
|||
sc->error = errno;
|
||||
|
||||
if (sc->ops == FF_SO_EPOLL_WAIT || sc->ops == FF_SO_KEVENT) {
|
||||
DEBUG_LOG("ff_event_loop_nb:%d/%d, ff_next_event_flag:%d\n",
|
||||
ff_event_loop_nb, ff_next_event_flag);
|
||||
if (ff_event_loop_nb > 0) {
|
||||
ff_next_event_flag = 1;
|
||||
} else {
|
||||
|
@ -478,22 +480,33 @@ ff_handle_socket_ops(struct ff_so_context *sc)
|
|||
void
|
||||
ff_handle_each_context()
|
||||
{
|
||||
uint16_t i, nb_handled;
|
||||
uint16_t i, nb_handled, tmp;
|
||||
|
||||
ff_event_loop_nb = 0;
|
||||
|
||||
rte_spinlock_lock(&ff_so_zone->lock);
|
||||
|
||||
assert(ff_so_zone->count >= ff_so_zone->free);
|
||||
tmp = nb_handled = ff_so_zone->count - ff_so_zone->free;
|
||||
|
||||
while(1) {
|
||||
rte_spinlock_lock(&ff_so_zone->lock);
|
||||
|
||||
assert(ff_so_zone->count >= ff_so_zone->free);
|
||||
nb_handled = ff_so_zone->count - ff_so_zone->free;
|
||||
nb_handled = tmp;
|
||||
if (nb_handled) {
|
||||
for (i = 0; i < ff_so_zone->count; i++) {
|
||||
struct ff_so_context *sc = &ff_so_zone->sc[i];
|
||||
|
||||
if (sc->inuse == 0) {
|
||||
DEBUG_LOG("so:%p, so->count:%d,%p, sc:%p, sc->inuse:%d,%p, i:%d, nb:%d, all_nb:%d\n",
|
||||
ff_so_zone, ff_so_zone->count, &ff_so_zone->count,
|
||||
sc, ff_so_zone->inuse[i], &ff_so_zone->inuse[i], i, nb_handled, tmp);
|
||||
|
||||
if (ff_so_zone->inuse[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ff_handle_socket_ops(sc);
|
||||
/* Dirty read first, and then try to lock sc and real read. */
|
||||
if (sc->status == FF_SC_REQ) {
|
||||
ff_handle_socket_ops(sc);
|
||||
}
|
||||
|
||||
nb_handled--;
|
||||
if (!nb_handled) {
|
||||
|
@ -502,13 +515,13 @@ ff_handle_each_context()
|
|||
}
|
||||
}
|
||||
|
||||
rte_spinlock_unlock(&ff_so_zone->lock);
|
||||
|
||||
if (--ff_event_loop_nb <= 0 || ff_next_event_flag == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
rte_pause();
|
||||
}
|
||||
|
||||
rte_spinlock_unlock(&ff_so_zone->lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#define DEBUG_LOG ERR_LOG
|
||||
#endif
|
||||
|
||||
/* Must be power of 2 */
|
||||
#define SOCKET_OPS_CONTEXT_MAX_NUM (1 << 5)
|
||||
|
||||
enum FF_SOCKET_OPS {
|
||||
FF_SO_SOCKET,
|
||||
FF_SO_LISTEN,
|
||||
|
@ -71,36 +74,38 @@ struct ff_socket_ops_zone {
|
|||
rte_spinlock_t lock;
|
||||
|
||||
/* total number of so_contex, must be power of 2 */
|
||||
uint16_t count;
|
||||
uint16_t mask;
|
||||
uint8_t count;
|
||||
uint8_t mask;
|
||||
|
||||
/* free number of so_context */
|
||||
uint16_t free;
|
||||
uint8_t free;
|
||||
|
||||
uint16_t idx;
|
||||
uint8_t idx;
|
||||
|
||||
/* 1 if used, else 0, most access */
|
||||
uint8_t inuse[SOCKET_OPS_CONTEXT_MAX_NUM];
|
||||
struct ff_so_context *sc;
|
||||
} __attribute__((packed));
|
||||
|
||||
uint8_t padding[16];
|
||||
} __attribute__((aligned(RTE_CACHE_LINE_SIZE)));
|
||||
|
||||
struct ff_so_context {
|
||||
rte_spinlock_t lock;
|
||||
sem_t wait_sem;
|
||||
enum FF_SOCKET_OPS ops;
|
||||
enum FF_SO_CONTEXT_STATUS status;
|
||||
void *args;
|
||||
|
||||
enum FF_SOCKET_OPS ops;
|
||||
int status;
|
||||
int idx;
|
||||
rte_spinlock_t lock;
|
||||
|
||||
/* result of ops processing */
|
||||
ssize_t result;
|
||||
/* errno if failed */
|
||||
int error;
|
||||
/* result of ops processing */
|
||||
int result;
|
||||
int idx;
|
||||
|
||||
/* 1 if used, else 0 */
|
||||
int inuse;
|
||||
sem_t wait_sem; /* 32 bytes */
|
||||
|
||||
// listen fd, refcount..
|
||||
} __attribute__((packed));
|
||||
} __attribute__((aligned(RTE_CACHE_LINE_SIZE)));
|
||||
|
||||
extern __FF_THREAD struct ff_socket_ops_zone *ff_so_zone;
|
||||
|
||||
|
|
Loading…
Reference in New Issue