Механизм синхронизации программного обеспечения через интерфейс PCIe - PullRequest
0 голосов
/ 03 мая 2019

У меня есть конечная точка PCI, на которой работает FreeRTOS. Эта конечная точка (EP) подключена к корневому комплексу (RC), на котором работает Linux.

Я реализовал программный механизм межпроцессорной связи (IPC), используя круговую решетку для связи между RC и EP. Структура кругового массива и память выделяются на 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 может получить к нему доступ. Этот экземпляр используется для выполнения связи IPC между RC и EP.

Теперь я хочу реализовать алгоритм, чтобы узнать, является ли круговой массив пустым или полным. Поскольку между RC и EP отсутствует аппаратный механизм блокировки, могут возникнуть условия гонки для обновления переменных с помощью программного обеспечения (хост производит и EP одновременно потребляет). Я думал о том, чтобы иметь переменную, которая используется для поддержания количества буферов, которое будет увеличиваться на RC и уменьшаться на EP, но из-за возможного состояния гонки я не удовлетворен этой идеей.

Может кто-нибудь предложить возможное решение? Я уверен, что это общая проблема, и у нее есть решение, но я не до нее.

...