使用dpdk的hash流表增删查

在处理tcp流的时候,处理线程cpu总是很高,导致丢包,主要是流表的添加查找时候耗资源,改用了dpdk的hash表试试效果
streamtable.h
class CRteStreamTable
{
public:
CRteStreamTable();
~CRteStreamTable();
int init(unsigned int keySize, unsigned int tableSize, int index);
RteStreamNode *add(CTuple4 *key, int &dir);
RteStreamNode *search(CTuple4 *key, int &dir);
int remove(CTuple4 *key, RteStreamNode *val);
void periodProcess();

private:
struct rte_hash_parameters hs_params;
struct rte_hash *handle;
u_int32_t totalCount;
u_int32_t freeCount;

public:
RteStreamNode* rteStreamNodes;
CPcapTcpAssemble *tcpAccessble;
char hsStreamTabName[16];
};

streamtable.cpp
CRteStreamTable::CRteStreamTable()
{
handle = NULL;
}

CRteStreamTable::~CRteStreamTable()
{
rte_hash_free(handle);
if(rteStreamNodes)
delete rteStreamNodes;
}

int CRteStreamTable::init(unsigned int keySize, unsigned int tableSize, int index)
{
totalCount = freeCount = tableSize;
snprintf(hsStreamTabName,16,”%s%d”,”hsStreamTable”,index);
hs_params.name = hsStreamTabName;//多线程,每个线程流表的名称
hs_params.entries = tableSize;
hs_params.key_len = keySize;
hs_params.hash_func = rte_jhash;
hs_params.hash_func_init_val = 0;
hs_params.socket_id = 0;
handle = rte_hash_create(&hs_params);
RTE_LOG(ERR, HASH, “rte_hash_create :%s\n”,rte_strerror(rte_errno));
if(handle)
{
rteStreamNodes = new RteStreamNode[tableSize];
if(rteStreamNodes)
{
return 0;
}
}

return -1;

}

RteStreamNode* CRteStreamTable::add(CTuple4 *key, int& dir)
{
if(!freeCount)
return NULL;
int pos = 0;
RteStreamNode* val = NULL;
if(key->isUplink())
{
pos = rte_hash_add_key(handle,key);
if(pos < 0)
{
printf(“CRteStreamTable::add fail!\n”);
return NULL;
}
val = &rteStreamNodes[pos];
val->dir = dir;
}
else
{
key->reverse2();
pos = rte_hash_add_key(handle,key);
if(pos < 0)
{
printf(“CRteStreamTable::add fail!\n”);
return NULL;
}
key->reverse2();
val = &rteStreamNodes[pos];
val->dir = !dir;
}
freeCount–;
return val;
}

RteStreamNode* CRteStreamTable::search(CTuple4 *key, int& dir)
{
int pos;
RteStreamNode* val = NULL;
if(key->isUplink())
{
pos = rte_hash_lookup(handle, (const void *)key);
if(0 <= pos)
{
val = &rteStreamNodes[pos];
dir = val->dir;
}
}
else
{
key->reverse2();
pos = rte_hash_lookup(handle, (const void *)key);
if(0 <= pos)
{
val = &rteStreamNodes[pos];
dir = !val->dir;
}
key->reverse2();
}

return val;

}

int CRteStreamTable::remove(CTuple4 key, RteStreamNode val)
{
int pos = -1;
if(key->isUplink())
pos = rte_hash_del_key(handle, key);
else
{
key->reverse2();
pos = rte_hash_del_key(handle, key);
key->reverse2();
}
if(pos < 0)
{
printf(“CRteStreamTable::remove fail!\n”);
return pos;
}
freeCount++;
return pos;
}

void CRteStreamTable::periodProcess()
{
double rate = (double)(totalCount - freeCount)/(double)totalCount;
struct timeval nowtime;
if(rate > 0.90)
{
LOGGER_WARN(formatStr(“%s CRteStreamTable::hashlist used rate %.4f”, obj->getObjectName().c_str(), rate));
}

int tcpTimeout = obj->tcpTimeout/1000;
gettimeofday(&nowtime, NULL); //获取当前时间
uint32_t iter = 0;
const void *next_key;
void *next_data;

int pos = 0;
while ((pos = rte_hash_iterate(handle, &next_key, &next_data, &iter)) >= 0)
{
    RteStreamNode* val = &rteStreamNodes[pos];
    unsigned int time = nowtime.tv_sec - val->lasttm;
    if(time > tcpTimeout)
    {
        obj->tablesLock.enter();
        remove((CTuple4*)next_key, val);
        obj->tablesLock.leave();

        if(val->state == STATE_SUPPORT)
        {
            obj->delStream(obj->streams[val->index]);

        }
    }
    else
    {
        if(val->state==STATE_SUPPORT && obj->streams[val->index]->bFailed)
        {
            obj->tablesLock.enter();
            remove((CTuple4*)next_key, val);
            obj->tablesLock.leave();
            obj->delStream(obj->streams[val->index]);            }
    }
}

}

加锁是因为老化线程和处理线程都要对流表操作,修改以前的流表就存在的,dpdk hash表有multi的用法不过没看到想要用的接口,性能ok就没试用,value可以一起插入到hash表里,也不知道我用的对不对,因为添加的时候也不知道添加的pos值,不想在添加的时候总是new,所以就用数组来放流表的value值了,hash表单独存流的key关系。

猜你喜欢

转载自blog.csdn.net/weixin_42651205/article/details/81948241
今日推荐