From: Atul Raut <araut@codeaurora.org>
To: linux-ntb@googlegroups.com
Cc: Atul Raut <araut@codeaurora.org>
Subject: [PATCH v2 3/4] NTB : Modification to ntb_perf module
Date: Sun, 6 May 2018 12:20:19 -0700 [thread overview]
Message-ID: <1525634420-19370-4-git-send-email-araut@codeaurora.org> (raw)
In-Reply-To: <1525634420-19370-1-git-send-email-araut@codeaurora.org>
Refactor ntb_perf module to get library code
so that other client can make use of it.
Signed-off-by: Atul Raut <araut@codeaurora.org>
---
drivers/ntb/test/ntb_perf.c | 347 +++++---------------------------------------
1 file changed, 40 insertions(+), 307 deletions(-)
diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
index 2a9d6b0..c65f81e 100644
--- a/drivers/ntb/test/ntb_perf.c
+++ b/drivers/ntb/test/ntb_perf.c
@@ -100,10 +100,6 @@
#define DMA_TRIES 100
#define DMA_MDELAY 10
-#define MSG_TRIES 500
-#define MSG_UDELAY_LOW 1000
-#define MSG_UDELAY_HIGH 2000
-
#define PERF_BUF_LEN 1024
static unsigned long max_mw_size;
@@ -127,17 +123,6 @@
*==============================================================================
*/
-enum perf_cmd {
- PERF_CMD_INVAL = -1,/* invalid spad command */
- PERF_CMD_SSIZE = 0, /* send out buffer size */
- PERF_CMD_RSIZE = 1, /* recv in buffer size */
- PERF_CMD_SXLAT = 2, /* send in buffer xlat */
- PERF_CMD_RXLAT = 3, /* recv out buffer xlat */
- PERF_CMD_CLEAR = 4, /* clear allocated memory */
- PERF_STS_DONE = 5, /* init is done */
- PERF_STS_LNKUP = 6, /* link up state flag */
-};
-
struct perf_ctx;
struct perf_peer {
@@ -197,36 +182,11 @@ struct perf_ctx {
struct perf_peer *test_peer;
struct perf_thread threads[MAX_THREADS_CNT];
- /* Scratchpad/Message IO operations */
- int (*cmd_send)(struct perf_peer *peer, enum perf_cmd cmd, u64 data);
- int (*cmd_recv)(struct perf_ctx *perf, int *pidx, enum perf_cmd *cmd,
- u64 *data);
+ struct msg_type handle;
struct dentry *dbgfs_dir;
};
-/*
- * Scratchpads-base commands interface
- */
-#define PERF_SPAD_CNT(_pcnt) \
- (3*((_pcnt) + 1))
-#define PERF_SPAD_CMD(_gidx) \
- (3*(_gidx))
-#define PERF_SPAD_LDATA(_gidx) \
- (3*(_gidx) + 1)
-#define PERF_SPAD_HDATA(_gidx) \
- (3*(_gidx) + 2)
-#define PERF_SPAD_NOTIFY(_gidx) \
- (BIT_ULL(_gidx))
-
-/*
- * Messages-base commands interface
- */
-#define PERF_MSG_CNT 3
-#define PERF_MSG_CMD 0
-#define PERF_MSG_LDATA 1
-#define PERF_MSG_HDATA 2
-
/*==============================================================================
* Static data declarations
*==============================================================================
@@ -251,192 +211,27 @@ static inline bool perf_link_is_up(struct perf_peer *peer)
return !!(link & BIT_ULL_MASK(peer->pidx));
}
-static int perf_spad_cmd_send(struct perf_peer *peer, enum perf_cmd cmd,
- u64 data)
-{
- struct perf_ctx *perf = peer->perf;
- int try;
- u32 sts;
-
- dev_dbg(&perf->ntb->dev, "CMD send: %d 0x%llx\n", cmd, data);
-
- /*
- * Perform predefined number of attempts before give up.
- * We are sending the data to the port specific scratchpad, so
- * to prevent a multi-port access race-condition. Additionally
- * there is no need in local locking since only thread-safe
- * service work is using this method.
- */
- for (try = 0; try < MSG_TRIES; try++) {
- if (!perf_link_is_up(peer))
- return -ENOLINK;
-
- sts = ntb_peer_spad_read(perf->ntb, peer->pidx,
- PERF_SPAD_CMD(perf->gidx));
- if (sts != PERF_CMD_INVAL) {
- usleep_range(MSG_UDELAY_LOW, MSG_UDELAY_HIGH);
- continue;
- }
-
- ntb_peer_spad_write(perf->ntb, peer->pidx,
- PERF_SPAD_LDATA(perf->gidx),
- lower_32_bits(data));
- ntb_peer_spad_write(perf->ntb, peer->pidx,
- PERF_SPAD_HDATA(perf->gidx),
- upper_32_bits(data));
- mmiowb();
- ntb_peer_spad_write(perf->ntb, peer->pidx,
- PERF_SPAD_CMD(perf->gidx),
- cmd);
- mmiowb();
- ntb_peer_db_set(perf->ntb, PERF_SPAD_NOTIFY(peer->gidx));
-
- dev_dbg(&perf->ntb->dev, "DB ring peer %#llx\n",
- PERF_SPAD_NOTIFY(peer->gidx));
-
- break;
- }
-
- return try < MSG_TRIES ? 0 : -EAGAIN;
-}
-
-static int perf_spad_cmd_recv(struct perf_ctx *perf, int *pidx,
- enum perf_cmd *cmd, u64 *data)
-{
- struct perf_peer *peer;
- u32 val;
-
- ntb_db_clear(perf->ntb, PERF_SPAD_NOTIFY(perf->gidx));
-
- /*
- * We start scanning all over, since cleared DB may have been set
- * by any peer. Yes, it makes peer with smaller index being
- * serviced with greater priority, but it's convenient for spad
- * and message code unification and simplicity.
- */
- for (*pidx = 0; *pidx < perf->pcnt; (*pidx)++) {
- peer = &perf->peers[*pidx];
-
- if (!perf_link_is_up(peer))
- continue;
-
- val = ntb_spad_read(perf->ntb, PERF_SPAD_CMD(peer->gidx));
- if (val == PERF_CMD_INVAL)
- continue;
-
- *cmd = val;
-
- val = ntb_spad_read(perf->ntb, PERF_SPAD_LDATA(peer->gidx));
- *data = val;
-
- val = ntb_spad_read(perf->ntb, PERF_SPAD_HDATA(peer->gidx));
- *data |= (u64)val << 32;
-
- /* Next command can be retrieved from now */
- ntb_spad_write(perf->ntb, PERF_SPAD_CMD(peer->gidx),
- PERF_CMD_INVAL);
-
- dev_dbg(&perf->ntb->dev, "CMD recv: %d 0x%llx\n", *cmd, *data);
-
- return 0;
- }
-
- return -ENODATA;
-}
-
-static int perf_msg_cmd_send(struct perf_peer *peer, enum perf_cmd cmd,
- u64 data)
-{
- struct perf_ctx *perf = peer->perf;
- int try, ret;
- u64 outbits;
-
- dev_dbg(&perf->ntb->dev, "CMD send: %d 0x%llx\n", cmd, data);
-
- /*
- * Perform predefined number of attempts before give up. Message
- * registers are free of race-condition problem when accessed
- * from different ports, so we don't need splitting registers
- * by global device index. We also won't have local locking,
- * since the method is used from service work only.
- */
- outbits = ntb_msg_outbits(perf->ntb);
- for (try = 0; try < MSG_TRIES; try++) {
- if (!perf_link_is_up(peer))
- return -ENOLINK;
-
- ret = ntb_msg_clear_sts(perf->ntb, outbits);
- if (ret)
- return ret;
-
- ntb_peer_msg_write(perf->ntb, peer->pidx, PERF_MSG_LDATA,
- lower_32_bits(data));
-
- if (ntb_msg_read_sts(perf->ntb) & outbits) {
- usleep_range(MSG_UDELAY_LOW, MSG_UDELAY_HIGH);
- continue;
- }
-
- ntb_peer_msg_write(perf->ntb, peer->pidx, PERF_MSG_HDATA,
- upper_32_bits(data));
- mmiowb();
-
- /* This call shall trigger peer message event */
- ntb_peer_msg_write(perf->ntb, peer->pidx, PERF_MSG_CMD, cmd);
-
- break;
- }
-
- return try < MSG_TRIES ? 0 : -EAGAIN;
-}
-
-static int perf_msg_cmd_recv(struct perf_ctx *perf, int *pidx,
- enum perf_cmd *cmd, u64 *data)
-{
- u64 inbits;
- u32 val;
-
- inbits = ntb_msg_inbits(perf->ntb);
-
- if (hweight64(ntb_msg_read_sts(perf->ntb) & inbits) < 3)
- return -ENODATA;
-
- val = ntb_msg_read(perf->ntb, pidx, PERF_MSG_CMD);
- *cmd = val;
-
- val = ntb_msg_read(perf->ntb, pidx, PERF_MSG_LDATA);
- *data = val;
-
- val = ntb_msg_read(perf->ntb, pidx, PERF_MSG_HDATA);
- *data |= (u64)val << 32;
-
- /* Next command can be retrieved from now */
- ntb_msg_clear_sts(perf->ntb, inbits);
-
- dev_dbg(&perf->ntb->dev, "CMD recv: %d 0x%llx\n", *cmd, *data);
-
- return 0;
-}
-
-static int perf_cmd_send(struct perf_peer *peer, enum perf_cmd cmd, u64 data)
+static int perf_cmd_send(struct perf_peer *peer, enum nt_cmd cmd,
+ int cmd_wid, u64 data)
{
struct perf_ctx *perf = peer->perf;
- if (cmd == PERF_CMD_SSIZE || cmd == PERF_CMD_SXLAT)
- return perf->cmd_send(peer, cmd, data);
+ if (cmd == NT_CMD_SSIZE || cmd == NT_CMD_SXLAT)
+ return perf->handle.cmd_send(perf->ntb, peer->pidx,
+ cmd, cmd_wid, data);
dev_err(&perf->ntb->dev, "Send invalid command\n");
return -EINVAL;
}
-static int perf_cmd_exec(struct perf_peer *peer, enum perf_cmd cmd)
+static int perf_cmd_exec(struct perf_peer *peer, enum nt_cmd cmd)
{
switch (cmd) {
- case PERF_CMD_SSIZE:
- case PERF_CMD_RSIZE:
- case PERF_CMD_SXLAT:
- case PERF_CMD_RXLAT:
- case PERF_CMD_CLEAR:
+ case NT_CMD_SSIZE:
+ case NT_CMD_RSIZE:
+ case NT_CMD_SXLAT:
+ case NT_CMD_RXLAT:
+ case NT_CMD_CLEAR:
break;
default:
dev_err(&peer->perf->ntb->dev, "Exec invalid command\n");
@@ -456,19 +251,20 @@ static int perf_cmd_exec(struct perf_peer *peer, enum perf_cmd cmd)
static int perf_cmd_recv(struct perf_ctx *perf)
{
struct perf_peer *peer;
- int ret, pidx, cmd;
+ int ret, pidx, cmd, cmd_wid;
u64 data;
- while (!(ret = perf->cmd_recv(perf, &pidx, &cmd, &data))) {
+ while (!(ret = perf->handle.cmd_recv(perf->ntb, &pidx, &cmd,
+ &cmd_wid, &data))) {
peer = &perf->peers[pidx];
switch (cmd) {
- case PERF_CMD_SSIZE:
+ case NT_CMD_SSIZE:
peer->inbuf_size = data;
- return perf_cmd_exec(peer, PERF_CMD_RSIZE);
- case PERF_CMD_SXLAT:
+ return perf_cmd_exec(peer, NT_CMD_RSIZE);
+ case NT_CMD_SXLAT:
peer->outbuf_xlat = data;
- return perf_cmd_exec(peer, PERF_CMD_RXLAT);
+ return perf_cmd_exec(peer, NT_CMD_RXLAT);
default:
dev_err(&perf->ntb->dev, "Recv invalid command\n");
return -EINVAL;
@@ -492,11 +288,11 @@ static void perf_link_event(void *ctx)
lnk_up = perf_link_is_up(peer);
if (lnk_up &&
- !test_and_set_bit(PERF_STS_LNKUP, &peer->sts)) {
- perf_cmd_exec(peer, PERF_CMD_SSIZE);
+ !test_and_set_bit(NT_STS_LNKUP, &peer->sts)) {
+ perf_cmd_exec(peer, NT_CMD_SSIZE);
} else if (!lnk_up &&
- test_and_clear_bit(PERF_STS_LNKUP, &peer->sts)) {
- perf_cmd_exec(peer, PERF_CMD_CLEAR);
+ test_and_clear_bit(NT_STS_LNKUP, &peer->sts)) {
+ perf_cmd_exec(peer, NT_CMD_CLEAR);
}
}
}
@@ -548,7 +344,7 @@ static int perf_setup_outbuf(struct perf_peer *peer)
}
/* Initialization is finally done */
- set_bit(PERF_STS_DONE, &peer->sts);
+ set_bit(NT_STS_DONE, &peer->sts);
return 0;
}
@@ -612,7 +408,7 @@ static int perf_setup_inbuf(struct perf_peer *peer)
* the code architecture, even though this method is called from service
* work itself so the command will be executed right after it returns.
*/
- (void)perf_cmd_exec(peer, PERF_CMD_SXLAT);
+ (void)perf_cmd_exec(peer, NT_CMD_SXLAT);
return 0;
@@ -626,20 +422,21 @@ static void perf_service_work(struct work_struct *work)
{
struct perf_peer *peer = to_peer_service(work);
- if (test_and_clear_bit(PERF_CMD_SSIZE, &peer->sts))
- perf_cmd_send(peer, PERF_CMD_SSIZE, peer->outbuf_size);
+ if (test_and_clear_bit(NT_CMD_SSIZE, &peer->sts))
+ perf_cmd_send(peer, NT_CMD_SSIZE, peer->gidx,
+ peer->outbuf_size);
- if (test_and_clear_bit(PERF_CMD_RSIZE, &peer->sts))
+ if (test_and_clear_bit(NT_CMD_RSIZE, &peer->sts))
perf_setup_inbuf(peer);
- if (test_and_clear_bit(PERF_CMD_SXLAT, &peer->sts))
- perf_cmd_send(peer, PERF_CMD_SXLAT, peer->inbuf_xlat);
+ if (test_and_clear_bit(NT_CMD_SXLAT, &peer->sts))
+ perf_cmd_send(peer, NT_CMD_SXLAT, peer->gidx, peer->inbuf_xlat);
- if (test_and_clear_bit(PERF_CMD_RXLAT, &peer->sts))
+ if (test_and_clear_bit(NT_CMD_RXLAT, &peer->sts))
perf_setup_outbuf(peer);
- if (test_and_clear_bit(PERF_CMD_CLEAR, &peer->sts)) {
- clear_bit(PERF_STS_DONE, &peer->sts);
+ if (test_and_clear_bit(NT_CMD_CLEAR, &peer->sts)) {
+ clear_bit(NT_STS_DONE, &peer->sts);
if (test_bit(0, &peer->perf->busy_flag) &&
peer == peer->perf->test_peer) {
dev_warn(&peer->perf->ntb->dev,
@@ -651,44 +448,6 @@ static void perf_service_work(struct work_struct *work)
}
}
-static int perf_init_service(struct perf_ctx *perf)
-{
- u64 mask;
-
- if (ntb_peer_mw_count(perf->ntb) < perf->pcnt + 1) {
- dev_err(&perf->ntb->dev, "Not enough memory windows\n");
- return -EINVAL;
- }
-
- if (ntb_msg_count(perf->ntb) >= PERF_MSG_CNT) {
- perf->cmd_send = perf_msg_cmd_send;
- perf->cmd_recv = perf_msg_cmd_recv;
-
- dev_dbg(&perf->ntb->dev, "Message service initialized\n");
-
- return 0;
- }
-
- dev_dbg(&perf->ntb->dev, "Message service unsupported\n");
-
- mask = GENMASK_ULL(perf->pcnt, 0);
- if (ntb_spad_count(perf->ntb) >= PERF_SPAD_CNT(perf->pcnt) &&
- (ntb_db_valid_mask(perf->ntb) & mask) == mask) {
- perf->cmd_send = perf_spad_cmd_send;
- perf->cmd_recv = perf_spad_cmd_recv;
-
- dev_dbg(&perf->ntb->dev, "Scratchpad service initialized\n");
-
- return 0;
- }
-
- dev_dbg(&perf->ntb->dev, "Scratchpad service unsupported\n");
-
- dev_err(&perf->ntb->dev, "Command services unsupported\n");
-
- return -EINVAL;
-}
-
static int perf_enable_service(struct perf_ctx *perf)
{
u64 mask, incmd_bit;
@@ -701,26 +460,7 @@ static int perf_enable_service(struct perf_ctx *perf)
if (ret)
return ret;
- if (perf->cmd_send == perf_msg_cmd_send) {
- u64 inbits, outbits;
-
- inbits = ntb_msg_inbits(perf->ntb);
- outbits = ntb_msg_outbits(perf->ntb);
- (void)ntb_msg_set_mask(perf->ntb, inbits | outbits);
-
- incmd_bit = BIT_ULL(__ffs64(inbits));
- ret = ntb_msg_clear_mask(perf->ntb, incmd_bit);
-
- dev_dbg(&perf->ntb->dev, "MSG sts unmasked %#llx\n", incmd_bit);
- } else {
- scnt = ntb_spad_count(perf->ntb);
- for (sidx = 0; sidx < scnt; sidx++)
- ntb_spad_write(perf->ntb, sidx, PERF_CMD_INVAL);
- incmd_bit = PERF_SPAD_NOTIFY(perf->gidx);
- ret = ntb_db_clear_mask(perf->ntb, incmd_bit);
-
- dev_dbg(&perf->ntb->dev, "DB bits unmasked %#llx\n", incmd_bit);
- }
+ ret = nt_enable_messaging(perf->ntb, perf->gidx);
if (ret) {
ntb_clear_ctx(perf->ntb);
return ret;
@@ -739,19 +479,12 @@ static void perf_disable_service(struct perf_ctx *perf)
ntb_link_disable(perf->ntb);
- if (perf->cmd_send == perf_msg_cmd_send) {
- u64 inbits;
-
- inbits = ntb_msg_inbits(perf->ntb);
- (void)ntb_msg_set_mask(perf->ntb, inbits);
- } else {
- (void)ntb_db_set_mask(perf->ntb, PERF_SPAD_NOTIFY(perf->gidx));
- }
+ nt_disable_messaging(perf->ntb, perf->gidx);
ntb_clear_ctx(perf->ntb);
for (pidx = 0; pidx < perf->pcnt; pidx++)
- perf_cmd_exec(&perf->peers[pidx], PERF_CMD_CLEAR);
+ perf_cmd_exec(&perf->peers[pidx], NT_CMD_CLEAR);
for (pidx = 0; pidx < perf->pcnt; pidx++)
flush_work(&perf->peers[pidx].service);
@@ -1046,7 +779,7 @@ static int perf_submit_test(struct perf_peer *peer)
struct perf_thread *pthr;
int tidx, ret;
- if (!test_bit(PERF_STS_DONE, &peer->sts))
+ if (!test_bit(NT_STS_DONE, &peer->sts))
return -ENOLINK;
if (test_and_set_bit_lock(0, &perf->busy_flag))
@@ -1184,7 +917,7 @@ static ssize_t perf_dbgfs_read_info(struct file *filep, char __user *ubuf,
pos += scnprintf(buf + pos, buf_size - pos,
"\tLink status: %s\n",
- test_bit(PERF_STS_LNKUP, &peer->sts) ? "up" : "down");
+ test_bit(NT_STS_LNKUP, &peer->sts) ? "up" : "down");
pos += scnprintf(buf + pos, buf_size - pos,
"\tOut buffer addr 0x%pK\n", peer->outbuf);
@@ -1443,7 +1176,7 @@ static int perf_probe(struct ntb_client *client, struct ntb_dev *ntb)
perf_init_threads(perf);
- ret = perf_init_service(perf);
+ ret = nt_init_messaging(ntb, &perf->handle);
if (ret)
return ret;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
next prev parent reply other threads:[~2018-05-06 19:20 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-06 19:20 [PATCH v2 0/4] NTB : Introduce message library Atul Raut
2018-05-06 19:20 ` [PATCH v2 1/4] " Atul Raut
2018-05-07 5:29 ` Logan Gunthorpe
2018-05-10 2:10 ` Atul Raut
2018-05-10 4:35 ` Logan Gunthorpe
2018-05-10 18:13 ` Atul Raut
2018-05-11 22:40 ` Serge Semin
2018-05-06 19:20 ` [PATCH v2 2/4] NTB : Add message library NTB API Atul Raut
2018-05-11 22:44 ` Serge Semin
2018-05-11 23:11 ` Logan Gunthorpe
2018-05-14 20:25 ` Serge Semin
2018-05-14 20:59 ` Logan Gunthorpe
2018-05-14 21:39 ` Serge Semin
2018-05-14 22:04 ` Logan Gunthorpe
2018-05-13 0:25 ` Allen Hubbe
2018-05-13 0:31 ` Allen Hubbe
2018-05-14 23:16 ` Serge Semin
2018-05-15 14:21 ` Allen Hubbe
2018-05-31 22:27 ` Serge Semin
2018-05-06 19:20 ` Atul Raut [this message]
2018-05-06 19:20 ` [PATCH v2 4/4] NTB : Add support to message registers based devices Atul Raut
2018-05-11 22:39 ` [PATCH v2 0/4] NTB : Introduce message library Serge Semin
2018-05-11 23:00 ` Logan Gunthorpe
2018-05-14 20:40 ` Serge Semin
2018-05-14 21:04 ` Logan Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1525634420-19370-4-git-send-email-araut@codeaurora.org \
--to=araut@codeaurora.org \
--cc=linux-ntb@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox