mirror of https://gitee.com/openkylin/linux.git
[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: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5a606b72a4
commit
cb48123584
|
@ -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)
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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,
|
||||||
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 {
|
||||||
#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
|
||||||
|
|
Loading…
Reference in New Issue