PCIe接口上的软件同步机制

时间:2019-05-03 07:40:51

标签: c linux-kernel synchronization pci pci-e

我有一个在其上运行FreeRTOS的PCI端点。该端点(EP)连接到在其上运行Linux的Root Complex(RC)。

我已经实现了使用环形阵列在RC和EP之间进行通信的软件处理器间通信(IPC)机制。环形阵列结构和内存在EP上分配,并且该内存通过EP BAR暴露给主机。

有一个坐在主机上的生产者正在向环形阵列填充数据,而坐在EP上的消费者正在使用数据。反之亦然(EP的生产者和RC的消费者)也可以通信

圆形数组的实现如下所示,

/** buffer ring common metadata between RC and EP */
typedef struct ipc_bd_ring_md {
    uint32_t pi;        /**< Producer index */
    uint32_t ci;        /**< Consumer index */
    uint32_t queue_size;    /**< Used to roll-over pi/ci */
    uint32_t msg_size;  /**< max size of the each buffer */
} __attribute__((packed)) ipc_br_md_t;

/** IPC buffer descriptor */
typedef struct ipc_buffer_desc {
    uint64_t rc_addr;   /**< msg's rc address */
    uint32_t ep_addr;   /**< msg's ep address */
    uint32_t len;       /**< msg len */
    uint64_t crc;       /**< crc */
} __attribute__((packed)) ipc_bd_t;

/** ipc msg bd ring */
typedef struct ipc_bd_ring_msg {
    ipc_br_md_t md;
    ipc_bd_t bd[IPC_MAX_DEPTH]; /** Max number of buffers possible in queue */
} __attribute__((packed)) ipc_bd_ring_msg_t;

ipc_bd_ring_msg_t的实例已在EP上分配,并且RC也可以访问它。该实例用于执行RC和EP之间的IPC通信。

现在,我想实现算法以了解圆形数组是空还是满。由于RC和EP之间没有硬件锁定机制,因此可能存在争用条件,可以通过软件更新变量(主机在生产,而EP在同时消耗)。 我当时在考虑使用一个变量来保持缓冲区计数,该变量将由RC递增,而由EP递减,但是由于可能的竞争条件,我对此想法不满意。

有人可以提出可能的解决方案吗?我确信这是通用问题,并且可以解决,但我不满意。

0 个答案:

没有答案