Commit cb481235 authored by David S. Miller's avatar David S. Miller

[SPARC64]: Assorted LDC bug cures.

1) LDC_MODE_RELIABLE is deprecated an unused by anything, plus
   it and LDC_MODE_STREAM were mis-numbered.

2) read_stream() should try to read as much as possible into
   the per-LDC stream buffer area, so do not trim the read_nonraw()
   length by the caller's size parameter.

3) Send data ACKs when necessary in read_nonraw().

4) In read_nonraw() when we get a pure ACK, advance the RX head
   unconditionally past it.

5) Provide the ACKID field in the ldcdgb() packet dump in read_nonraw().
   This helps debugging stream mode LDC channel problems.

6) Decrease verbosity of rx_data_wait() so that it is more useful.
   A debugging message each loop iteration is too much.

7) In process_data_ack() stop the loop checking when we hit lp->tx_tail
   not lp->tx_head.

8) Set the seqid field properly in send_data_nack().
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5a606b72
...@@ -239,8 +239,7 @@ static struct ldc_packet *handshake_get_tx_packet(struct ldc_channel *lp, ...@@ -239,8 +239,7 @@ static struct ldc_packet *handshake_get_tx_packet(struct ldc_channel *lp,
*/ */
static unsigned long head_for_data(struct ldc_channel *lp) static unsigned long head_for_data(struct ldc_channel *lp)
{ {
if (lp->cfg.mode == LDC_MODE_RELIABLE || if (lp->cfg.mode == LDC_MODE_STREAM)
lp->cfg.mode == LDC_MODE_STREAM)
return lp->tx_acked; return lp->tx_acked;
return lp->tx_head; return lp->tx_head;
} }
...@@ -494,7 +493,7 @@ static int send_data_nack(struct ldc_channel *lp, struct ldc_packet *data_pkt) ...@@ -494,7 +493,7 @@ static int send_data_nack(struct ldc_channel *lp, struct ldc_packet *data_pkt)
p->type = data_pkt->type; p->type = data_pkt->type;
p->stype = LDC_NACK; p->stype = LDC_NACK;
p->ctrl = data_pkt->ctrl & LDC_CTRL_MSK; p->ctrl = data_pkt->ctrl & LDC_CTRL_MSK;
p->seqid = lp->snd_nxt; p->seqid = lp->snd_nxt + 1;
p->u.r.ackid = lp->rcv_nxt; p->u.r.ackid = lp->rcv_nxt;
ldcdbg(HS, "SEND DATA NACK type[0x%x] ctl[0x%x] seq[0x%x] ack[0x%x]\n", ldcdbg(HS, "SEND DATA NACK type[0x%x] ctl[0x%x] seq[0x%x] ack[0x%x]\n",
...@@ -765,7 +764,7 @@ static int process_data_ack(struct ldc_channel *lp, ...@@ -765,7 +764,7 @@ static int process_data_ack(struct ldc_channel *lp,
lp->tx_acked = head; lp->tx_acked = head;
return 0; return 0;
} }
if (head == lp->tx_head) if (head == lp->tx_tail)
return ldc_abort(lp); return ldc_abort(lp);
} }
...@@ -1093,11 +1092,6 @@ struct ldc_channel *ldc_alloc(unsigned long id, ...@@ -1093,11 +1092,6 @@ struct ldc_channel *ldc_alloc(unsigned long id,
mss = LDC_PACKET_SIZE - 8; mss = LDC_PACKET_SIZE - 8;
break; break;
case LDC_MODE_RELIABLE:
mops = &nonraw_ops;
mss = LDC_PACKET_SIZE - 8 - 8;
break;
case LDC_MODE_STREAM: case LDC_MODE_STREAM:
mops = &stream_ops; mops = &stream_ops;
mss = LDC_PACKET_SIZE - 8 - 8; mss = LDC_PACKET_SIZE - 8 - 8;
...@@ -1579,15 +1573,14 @@ static int rx_data_wait(struct ldc_channel *lp, unsigned long cur_head) ...@@ -1579,15 +1573,14 @@ static int rx_data_wait(struct ldc_channel *lp, unsigned long cur_head)
if (hv_err) if (hv_err)
return ldc_abort(lp); return ldc_abort(lp);
ldcdbg(DATA, "REREAD head[%lx] tail[%lx] chan_state[%lx]\n",
dummy, lp->rx_tail, lp->chan_state);
if (lp->chan_state == LDC_CHANNEL_DOWN || if (lp->chan_state == LDC_CHANNEL_DOWN ||
lp->chan_state == LDC_CHANNEL_RESETTING) lp->chan_state == LDC_CHANNEL_RESETTING)
return -ECONNRESET; return -ECONNRESET;
if (cur_head != lp->rx_tail) { if (cur_head != lp->rx_tail) {
ldcdbg(DATA, "DATA WAIT DONE\n"); ldcdbg(DATA, "DATA WAIT DONE "
"head[%lx] tail[%lx] chan_state[%lx]\n",
dummy, lp->rx_tail, lp->chan_state);
return 0; return 0;
} }
...@@ -1607,6 +1600,28 @@ static int rx_set_head(struct ldc_channel *lp, unsigned long head) ...@@ -1607,6 +1600,28 @@ static int rx_set_head(struct ldc_channel *lp, unsigned long head)
return 0; return 0;
} }
static void send_data_ack(struct ldc_channel *lp)
{
unsigned long new_tail;
struct ldc_packet *p;
p = data_get_tx_packet(lp, &new_tail);
if (likely(p)) {
int err;
memset(p, 0, sizeof(*p));
p->type = LDC_DATA;
p->stype = LDC_ACK;
p->ctrl = 0;
p->seqid = lp->snd_nxt + 1;
p->u.r.ackid = lp->rcv_nxt;
err = send_tx_packet(lp, p, new_tail);
if (!err)
lp->snd_nxt++;
}
}
static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size) static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
{ {
struct ldc_packet *first_frag; struct ldc_packet *first_frag;
...@@ -1637,13 +1652,14 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size) ...@@ -1637,13 +1652,14 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
BUG_ON(new == lp->rx_tail); BUG_ON(new == lp->rx_tail);
p = lp->rx_base + (new / LDC_PACKET_SIZE); p = lp->rx_base + (new / LDC_PACKET_SIZE);
ldcdbg(RX, "RX read pkt[%02x:%02x:%02x:%02x:%08x] " ldcdbg(RX, "RX read pkt[%02x:%02x:%02x:%02x:%08x:%08x] "
"rcv_nxt[%08x]\n", "rcv_nxt[%08x]\n",
p->type, p->type,
p->stype, p->stype,
p->ctrl, p->ctrl,
p->env, p->env,
p->seqid, p->seqid,
p->u.r.ackid,
lp->rcv_nxt); lp->rcv_nxt);
if (unlikely(!rx_seq_ok(lp, p->seqid))) { if (unlikely(!rx_seq_ok(lp, p->seqid))) {
...@@ -1672,6 +1688,9 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size) ...@@ -1672,6 +1688,9 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
} }
if (!(p->stype & LDC_INFO)) { if (!(p->stype & LDC_INFO)) {
new = rx_advance(lp, new); new = rx_advance(lp, new);
err = rx_set_head(lp, new);
if (err)
break;
goto no_data; goto no_data;
} }
...@@ -1748,8 +1767,11 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size) ...@@ -1748,8 +1767,11 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
if (err && first_frag) if (err && first_frag)
lp->rcv_nxt = first_frag->seqid - 1; lp->rcv_nxt = first_frag->seqid - 1;
if (!err) if (!err) {
err = copied; err = copied;
if (err > 0 && lp->cfg.mode != LDC_MODE_UNRELIABLE)
send_data_ack(lp);
}
return err; return err;
} }
...@@ -1770,9 +1792,7 @@ static int write_stream(struct ldc_channel *lp, const void *buf, ...@@ -1770,9 +1792,7 @@ static int write_stream(struct ldc_channel *lp, const void *buf,
static int read_stream(struct ldc_channel *lp, void *buf, unsigned int size) static int read_stream(struct ldc_channel *lp, void *buf, unsigned int size)
{ {
if (!lp->mssbuf_len) { if (!lp->mssbuf_len) {
int err = read_nonraw(lp, lp->mssbuf, int err = read_nonraw(lp, lp->mssbuf, lp->cfg.mtu);
(size > lp->cfg.mtu ?
lp->cfg.mtu : size));
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -25,8 +25,7 @@ struct ldc_channel_config { ...@@ -25,8 +25,7 @@ struct ldc_channel_config {
#define LDC_MODE_RAW 0x00 #define LDC_MODE_RAW 0x00
#define LDC_MODE_UNRELIABLE 0x01 #define LDC_MODE_UNRELIABLE 0x01
#define LDC_MODE_RESERVED 0x02 #define LDC_MODE_RESERVED 0x02
#define LDC_MODE_RELIABLE 0x03 #define LDC_MODE_STREAM 0x03
#define LDC_MODE_STREAM 0x04
u8 debug; u8 debug;
#define LDC_DEBUG_HS 0x01 #define LDC_DEBUG_HS 0x01
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment