* Re: sockets affected by IPsec always block (2.6.23)
From: Stefan Rompf @ 2007-12-05 18:42 UTC (permalink / raw)
To: David Miller; +Cc: herbert, simon, linux-kernel, netdev
In-Reply-To: <20071204.231200.117152338.davem@davemloft.net>
Am Mittwoch, 5. Dezember 2007 08:12 schrieb David Miller:
> Actually, consider even a case like DNS. Let's say the timeout
> is set to 2 seconds or something and you have 3 DNS servers
> listed, on different IPSEC destinations, in your resolv.conf
>
> Each IPSEC route that isn't currently resolved will cause packet loss
> of the DNS lookup request with xfrm_larval_drop set to '1'.
>
> If all 3 need to be resolved, the DNS lookup will fully fail
> which defeats the purpose of listing 3 servers for redundancy
> don't you think? :-)
In your example, the DNS server might actually stop responding to other
clients while waiting for the (expected to be non-blocking) connect() to
return. This is much much worse.
Stefan
^ permalink raw reply
* [PATCH 2/2] cxgb3 - Parity initialization for T3C adapters
From: Divy Le Ray @ 2007-12-05 18:15 UTC (permalink / raw)
To: jeff, netdev; +Cc: linux-kernel, swise, wenxiong
From: Divy Le Ray <divy@chelsio.com>
Add parity initialization for T3C adapters.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
---
drivers/net/cxgb3/adapter.h | 1
drivers/net/cxgb3/cxgb3_main.c | 82 ++++++++++++
drivers/net/cxgb3/cxgb3_offload.c | 15 ++
drivers/net/cxgb3/regs.h | 248 +++++++++++++++++++++++++++++++++++++
drivers/net/cxgb3/sge.c | 24 +++-
drivers/net/cxgb3/t3_hw.c | 131 +++++++++++++++++---
6 files changed, 472 insertions(+), 29 deletions(-)
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 60a62f5..eb305a0 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -71,6 +71,7 @@ enum { /* adapter flags */
USING_MSI = (1 << 1),
USING_MSIX = (1 << 2),
QUEUES_BOUND = (1 << 3),
+ TP_PARITY_INIT = (1 << 4),
};
struct fl_pg_chunk {
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 944423c..d1aa777 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -306,6 +306,77 @@ static int request_msix_data_irqs(struct adapter *adap)
return 0;
}
+static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
+ unsigned long n)
+{
+ int attempts = 5;
+
+ while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
+ if (!--attempts)
+ return -ETIMEDOUT;
+ msleep(10);
+ }
+ return 0;
+}
+
+static int init_tp_parity(struct adapter *adap)
+{
+ int i;
+ struct sk_buff *skb;
+ struct cpl_set_tcb_field *greq;
+ unsigned long cnt = adap->sge.qs[0].rspq.offload_pkts;
+
+ t3_tp_set_offload_mode(adap, 1);
+
+ for (i = 0; i < 16; i++) {
+ struct cpl_smt_write_req *req;
+
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+ req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req));
+ memset(req, 0, sizeof(*req));
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
+ req->iff = i;
+ t3_mgmt_tx(adap, skb);
+ }
+
+ for (i = 0; i < 2048; i++) {
+ struct cpl_l2t_write_req *req;
+
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+ req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
+ memset(req, 0, sizeof(*req));
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i));
+ req->params = htonl(V_L2T_W_IDX(i));
+ t3_mgmt_tx(adap, skb);
+ }
+
+ for (i = 0; i < 2048; i++) {
+ struct cpl_rte_write_req *req;
+
+ skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+ req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req));
+ memset(req, 0, sizeof(*req));
+ req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i));
+ req->l2t_idx = htonl(V_L2T_W_IDX(i));
+ t3_mgmt_tx(adap, skb);
+ }
+
+ skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
+ greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq));
+ memset(greq, 0, sizeof(*greq));
+ greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ OPCODE_TID(greq) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, 0));
+ greq->mask = cpu_to_be64(1);
+ t3_mgmt_tx(adap, skb);
+
+ i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
+ t3_tp_set_offload_mode(adap, 0);
+ return i;
+}
+
/**
* setup_rss - configure RSS
* @adap: the adapter
@@ -817,6 +888,7 @@ static int cxgb_up(struct adapter *adap)
if (err)
goto out;
+ t3_set_reg_field(adap, A_TP_PARA_REG5, 0, F_RXDDPOFFINIT);
t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
err = setup_sge_qsets(adap);
@@ -856,6 +928,16 @@ static int cxgb_up(struct adapter *adap)
t3_sge_start(adap);
t3_intr_enable(adap);
+ if (adap->params.rev >= T3_REV_C && !(adap->flags & TP_PARITY_INIT) &&
+ is_offload(adap) && init_tp_parity(adap) == 0)
+ adap->flags |= TP_PARITY_INIT;
+
+ if (adap->flags & TP_PARITY_INIT) {
+ t3_write_reg(adap, A_TP_INT_CAUSE,
+ F_CMCACHEPERR | F_ARPLUTPERR);
+ t3_write_reg(adap, A_TP_INT_ENABLE, 0x7fbfffff);
+ }
+
if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
bind_qsets(adap);
adap->flags |= QUEUES_BOUND;
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 650d06a..738de4b 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -403,8 +403,6 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data)
static int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs,
int n)
{
- CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n",
- n, ntohl(*(__be32 *)skbs[0]->data));
while (n--)
dev_kfree_skb_any(skbs[n]);
return 0;
@@ -634,6 +632,18 @@ static int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
return CPL_RET_BUF_DONE;
}
+static int do_rte_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
+{
+ struct cpl_rte_write_rpl *rpl = cplhdr(skb);
+
+ if (rpl->status != CPL_ERR_NONE)
+ printk(KERN_ERR
+ "Unexpected RTE_WRITE_RPL status %u for entry %u\n",
+ rpl->status, GET_TID(rpl));
+
+ return CPL_RET_BUF_DONE;
+}
+
static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb)
{
struct cpl_act_open_rpl *rpl = cplhdr(skb);
@@ -1257,6 +1267,7 @@ void __init cxgb3_offload_init(void)
t3_register_cpl_handler(CPL_SMT_WRITE_RPL, do_smt_write_rpl);
t3_register_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl);
+ t3_register_cpl_handler(CPL_RTE_WRITE_RPL, do_rte_write_rpl);
t3_register_cpl_handler(CPL_PASS_OPEN_RPL, do_stid_rpl);
t3_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_stid_rpl);
t3_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_cr);
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index 70e1961..02dbbb3 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1,5 +1,17 @@
#define A_SG_CONTROL 0x0
+#define S_CONGMODE 29
+#define V_CONGMODE(x) ((x) << S_CONGMODE)
+#define F_CONGMODE V_CONGMODE(1U)
+
+#define S_TNLFLMODE 28
+#define V_TNLFLMODE(x) ((x) << S_TNLFLMODE)
+#define F_TNLFLMODE V_TNLFLMODE(1U)
+
+#define S_FATLPERREN 27
+#define V_FATLPERREN(x) ((x) << S_FATLPERREN)
+#define F_FATLPERREN V_FATLPERREN(1U)
+
#define S_DROPPKT 20
#define V_DROPPKT(x) ((x) << S_DROPPKT)
#define F_DROPPKT V_DROPPKT(1U)
@@ -172,6 +184,64 @@
#define A_SG_INT_CAUSE 0x5c
+#define S_HIRCQPARITYERROR 31
+#define V_HIRCQPARITYERROR(x) ((x) << S_HIRCQPARITYERROR)
+#define F_HIRCQPARITYERROR V_HIRCQPARITYERROR(1U)
+
+#define S_LORCQPARITYERROR 30
+#define V_LORCQPARITYERROR(x) ((x) << S_LORCQPARITYERROR)
+#define F_LORCQPARITYERROR V_LORCQPARITYERROR(1U)
+
+#define S_HIDRBPARITYERROR 29
+#define V_HIDRBPARITYERROR(x) ((x) << S_HIDRBPARITYERROR)
+#define F_HIDRBPARITYERROR V_HIDRBPARITYERROR(1U)
+
+#define S_LODRBPARITYERROR 28
+#define V_LODRBPARITYERROR(x) ((x) << S_LODRBPARITYERROR)
+#define F_LODRBPARITYERROR V_LODRBPARITYERROR(1U)
+
+#define S_FLPARITYERROR 22
+#define M_FLPARITYERROR 0x3f
+#define V_FLPARITYERROR(x) ((x) << S_FLPARITYERROR)
+#define G_FLPARITYERROR(x) (((x) >> S_FLPARITYERROR) & M_FLPARITYERROR)
+
+#define S_ITPARITYERROR 20
+#define M_ITPARITYERROR 0x3
+#define V_ITPARITYERROR(x) ((x) << S_ITPARITYERROR)
+#define G_ITPARITYERROR(x) (((x) >> S_ITPARITYERROR) & M_ITPARITYERROR)
+
+#define S_IRPARITYERROR 19
+#define V_IRPARITYERROR(x) ((x) << S_IRPARITYERROR)
+#define F_IRPARITYERROR V_IRPARITYERROR(1U)
+
+#define S_RCPARITYERROR 18
+#define V_RCPARITYERROR(x) ((x) << S_RCPARITYERROR)
+#define F_RCPARITYERROR V_RCPARITYERROR(1U)
+
+#define S_OCPARITYERROR 17
+#define V_OCPARITYERROR(x) ((x) << S_OCPARITYERROR)
+#define F_OCPARITYERROR V_OCPARITYERROR(1U)
+
+#define S_CPPARITYERROR 16
+#define V_CPPARITYERROR(x) ((x) << S_CPPARITYERROR)
+#define F_CPPARITYERROR V_CPPARITYERROR(1U)
+
+#define S_R_REQ_FRAMINGERROR 15
+#define V_R_REQ_FRAMINGERROR(x) ((x) << S_R_REQ_FRAMINGERROR)
+#define F_R_REQ_FRAMINGERROR V_R_REQ_FRAMINGERROR(1U)
+
+#define S_UC_REQ_FRAMINGERROR 14
+#define V_UC_REQ_FRAMINGERROR(x) ((x) << S_UC_REQ_FRAMINGERROR)
+#define F_UC_REQ_FRAMINGERROR V_UC_REQ_FRAMINGERROR(1U)
+
+#define S_HICTLDRBDROPERR 13
+#define V_HICTLDRBDROPERR(x) ((x) << S_HICTLDRBDROPERR)
+#define F_HICTLDRBDROPERR V_HICTLDRBDROPERR(1U)
+
+#define S_LOCTLDRBDROPERR 12
+#define V_LOCTLDRBDROPERR(x) ((x) << S_LOCTLDRBDROPERR)
+#define F_LOCTLDRBDROPERR V_LOCTLDRBDROPERR(1U)
+
#define S_HIPIODRBDROPERR 11
#define V_HIPIODRBDROPERR(x) ((x) << S_HIPIODRBDROPERR)
#define F_HIPIODRBDROPERR V_HIPIODRBDROPERR(1U)
@@ -286,6 +356,10 @@
#define A_PCIX_CFG 0x88
+#define S_DMASTOPEN 19
+#define V_DMASTOPEN(x) ((x) << S_DMASTOPEN)
+#define F_DMASTOPEN V_DMASTOPEN(1U)
+
#define S_CLIDECEN 18
#define V_CLIDECEN(x) ((x) << S_CLIDECEN)
#define F_CLIDECEN V_CLIDECEN(1U)
@@ -313,6 +387,22 @@
#define V_BISTERR(x) ((x) << S_BISTERR)
+#define S_TXPARERR 18
+#define V_TXPARERR(x) ((x) << S_TXPARERR)
+#define F_TXPARERR V_TXPARERR(1U)
+
+#define S_RXPARERR 17
+#define V_RXPARERR(x) ((x) << S_RXPARERR)
+#define F_RXPARERR V_RXPARERR(1U)
+
+#define S_RETRYLUTPARERR 16
+#define V_RETRYLUTPARERR(x) ((x) << S_RETRYLUTPARERR)
+#define F_RETRYLUTPARERR V_RETRYLUTPARERR(1U)
+
+#define S_RETRYBUFPARERR 15
+#define V_RETRYBUFPARERR(x) ((x) << S_RETRYBUFPARERR)
+#define F_RETRYBUFPARERR V_RETRYBUFPARERR(1U)
+
#define S_PCIE_MSIXPARERR 12
#define M_PCIE_MSIXPARERR 0x7
@@ -348,6 +438,10 @@
#define A_PCIE_INT_CAUSE 0x84
+#define S_PCIE_DMASTOPEN 24
+#define V_PCIE_DMASTOPEN(x) ((x) << S_PCIE_DMASTOPEN)
+#define F_PCIE_DMASTOPEN V_PCIE_DMASTOPEN(1U)
+
#define A_PCIE_CFG 0x88
#define S_PCIE_CLIDECEN 16
@@ -741,6 +835,54 @@
#define A_CIM_HOST_INT_ENABLE 0x298
+#define S_DTAGPARERR 28
+#define V_DTAGPARERR(x) ((x) << S_DTAGPARERR)
+#define F_DTAGPARERR V_DTAGPARERR(1U)
+
+#define S_ITAGPARERR 27
+#define V_ITAGPARERR(x) ((x) << S_ITAGPARERR)
+#define F_ITAGPARERR V_ITAGPARERR(1U)
+
+#define S_IBQTPPARERR 26
+#define V_IBQTPPARERR(x) ((x) << S_IBQTPPARERR)
+#define F_IBQTPPARERR V_IBQTPPARERR(1U)
+
+#define S_IBQULPPARERR 25
+#define V_IBQULPPARERR(x) ((x) << S_IBQULPPARERR)
+#define F_IBQULPPARERR V_IBQULPPARERR(1U)
+
+#define S_IBQSGEHIPARERR 24
+#define V_IBQSGEHIPARERR(x) ((x) << S_IBQSGEHIPARERR)
+#define F_IBQSGEHIPARERR V_IBQSGEHIPARERR(1U)
+
+#define S_IBQSGELOPARERR 23
+#define V_IBQSGELOPARERR(x) ((x) << S_IBQSGELOPARERR)
+#define F_IBQSGELOPARERR V_IBQSGELOPARERR(1U)
+
+#define S_OBQULPLOPARERR 22
+#define V_OBQULPLOPARERR(x) ((x) << S_OBQULPLOPARERR)
+#define F_OBQULPLOPARERR V_OBQULPLOPARERR(1U)
+
+#define S_OBQULPHIPARERR 21
+#define V_OBQULPHIPARERR(x) ((x) << S_OBQULPHIPARERR)
+#define F_OBQULPHIPARERR V_OBQULPHIPARERR(1U)
+
+#define S_OBQSGEPARERR 20
+#define V_OBQSGEPARERR(x) ((x) << S_OBQSGEPARERR)
+#define F_OBQSGEPARERR V_OBQSGEPARERR(1U)
+
+#define S_DCACHEPARERR 19
+#define V_DCACHEPARERR(x) ((x) << S_DCACHEPARERR)
+#define F_DCACHEPARERR V_DCACHEPARERR(1U)
+
+#define S_ICACHEPARERR 18
+#define V_ICACHEPARERR(x) ((x) << S_ICACHEPARERR)
+#define F_ICACHEPARERR V_ICACHEPARERR(1U)
+
+#define S_DRAMPARERR 17
+#define V_DRAMPARERR(x) ((x) << S_DRAMPARERR)
+#define F_DRAMPARERR V_DRAMPARERR(1U)
+
#define A_CIM_HOST_INT_CAUSE 0x29c
#define S_BLKWRPLINT 12
@@ -799,8 +941,42 @@
#define A_CIM_HOST_ACC_DATA 0x2b4
+#define A_CIM_IBQ_DBG_CFG 0x2c0
+
+#define S_IBQDBGADDR 16
+#define M_IBQDBGADDR 0x1ff
+#define V_IBQDBGADDR(x) ((x) << S_IBQDBGADDR)
+#define G_IBQDBGADDR(x) (((x) >> S_IBQDBGADDR) & M_IBQDBGADDR)
+
+#define S_IBQDBGQID 3
+#define M_IBQDBGQID 0x3
+#define V_IBQDBGQID(x) ((x) << S_IBQDBGQID)
+#define G_IBQDBGQID(x) (((x) >> S_IBQDBGQID) & M_IBQDBGQID)
+
+#define S_IBQDBGWR 2
+#define V_IBQDBGWR(x) ((x) << S_IBQDBGWR)
+#define F_IBQDBGWR V_IBQDBGWR(1U)
+
+#define S_IBQDBGBUSY 1
+#define V_IBQDBGBUSY(x) ((x) << S_IBQDBGBUSY)
+#define F_IBQDBGBUSY V_IBQDBGBUSY(1U)
+
+#define S_IBQDBGEN 0
+#define V_IBQDBGEN(x) ((x) << S_IBQDBGEN)
+#define F_IBQDBGEN V_IBQDBGEN(1U)
+
+#define A_CIM_IBQ_DBG_DATA 0x2c8
+
#define A_TP_IN_CONFIG 0x300
+#define S_RXFBARBPRIO 25
+#define V_RXFBARBPRIO(x) ((x) << S_RXFBARBPRIO)
+#define F_RXFBARBPRIO V_RXFBARBPRIO(1U)
+
+#define S_TXFBARBPRIO 24
+#define V_TXFBARBPRIO(x) ((x) << S_TXFBARBPRIO)
+#define F_TXFBARBPRIO V_TXFBARBPRIO(1U)
+
#define S_NICMODE 14
#define V_NICMODE(x) ((x) << S_NICMODE)
#define F_NICMODE V_NICMODE(1U)
@@ -973,6 +1149,22 @@
#define A_TP_PC_CONFIG2 0x34c
+#define S_DISBLEDAPARBIT0 15
+#define V_DISBLEDAPARBIT0(x) ((x) << S_DISBLEDAPARBIT0)
+#define F_DISBLEDAPARBIT0 V_DISBLEDAPARBIT0(1U)
+
+#define S_ENABLEARPMISS 13
+#define V_ENABLEARPMISS(x) ((x) << S_ENABLEARPMISS)
+#define F_ENABLEARPMISS V_ENABLEARPMISS(1U)
+
+#define S_ENABLENONOFDTNLSYN 12
+#define V_ENABLENONOFDTNLSYN(x) ((x) << S_ENABLENONOFDTNLSYN)
+#define F_ENABLENONOFDTNLSYN V_ENABLENONOFDTNLSYN(1U)
+
+#define S_ENABLEIPV6RSS 11
+#define V_ENABLEIPV6RSS(x) ((x) << S_ENABLEIPV6RSS)
+#define F_ENABLEIPV6RSS V_ENABLEIPV6RSS(1U)
+
#define S_CHDRAFULL 4
#define V_CHDRAFULL(x) ((x) << S_CHDRAFULL)
#define F_CHDRAFULL V_CHDRAFULL(1U)
@@ -1024,6 +1216,12 @@
#define A_TP_PARA_REG4 0x370
+#define A_TP_PARA_REG5 0x374
+
+#define S_RXDDPOFFINIT 3
+#define V_RXDDPOFFINIT(x) ((x) << S_RXDDPOFFINIT)
+#define F_RXDDPOFFINIT V_RXDDPOFFINIT(1U)
+
#define A_TP_PARA_REG6 0x378
#define S_T3A_ENABLEESND 13
@@ -1144,6 +1342,10 @@
#define V_TNLLKPEN(x) ((x) << S_TNLLKPEN)
#define F_TNLLKPEN V_TNLLKPEN(1U)
+#define S_RRCPLMAPEN 7
+#define V_RRCPLMAPEN(x) ((x) << S_RRCPLMAPEN)
+#define F_RRCPLMAPEN V_RRCPLMAPEN(1U)
+
#define S_RRCPLCPUSIZE 4
#define M_RRCPLCPUSIZE 0x7
#define V_RRCPLCPUSIZE(x) ((x) << S_RRCPLCPUSIZE)
@@ -1216,6 +1418,14 @@
#define V_FLMRXFLSTEMPTY(x) ((x) << S_FLMRXFLSTEMPTY)
#define F_FLMRXFLSTEMPTY V_FLMRXFLSTEMPTY(1U)
+#define S_ARPLUTPERR 26
+#define V_ARPLUTPERR(x) ((x) << S_ARPLUTPERR)
+#define F_ARPLUTPERR V_ARPLUTPERR(1U)
+
+#define S_CMCACHEPERR 24
+#define V_CMCACHEPERR(x) ((x) << S_CMCACHEPERR)
+#define F_CMCACHEPERR V_CMCACHEPERR(1U)
+
#define A_TP_INT_CAUSE 0x474
#define A_TP_TX_MOD_Q1_Q0_RATE_LIMIT 0x8
@@ -1259,9 +1469,37 @@
#define A_ULPRX_INT_ENABLE 0x504
-#define S_PARERR 0
-#define V_PARERR(x) ((x) << S_PARERR)
-#define F_PARERR V_PARERR(1U)
+#define S_DATASELFRAMEERR0 7
+#define V_DATASELFRAMEERR0(x) ((x) << S_DATASELFRAMEERR0)
+#define F_DATASELFRAMEERR0 V_DATASELFRAMEERR0(1U)
+
+#define S_DATASELFRAMEERR1 6
+#define V_DATASELFRAMEERR1(x) ((x) << S_DATASELFRAMEERR1)
+#define F_DATASELFRAMEERR1 V_DATASELFRAMEERR1(1U)
+
+#define S_PCMDMUXPERR 5
+#define V_PCMDMUXPERR(x) ((x) << S_PCMDMUXPERR)
+#define F_PCMDMUXPERR V_PCMDMUXPERR(1U)
+
+#define S_ARBFPERR 4
+#define V_ARBFPERR(x) ((x) << S_ARBFPERR)
+#define F_ARBFPERR V_ARBFPERR(1U)
+
+#define S_ARBPF0PERR 3
+#define V_ARBPF0PERR(x) ((x) << S_ARBPF0PERR)
+#define F_ARBPF0PERR V_ARBPF0PERR(1U)
+
+#define S_ARBPF1PERR 2
+#define V_ARBPF1PERR(x) ((x) << S_ARBPF1PERR)
+#define F_ARBPF1PERR V_ARBPF1PERR(1U)
+
+#define S_PARERRPCMD 1
+#define V_PARERRPCMD(x) ((x) << S_PARERRPCMD)
+#define F_PARERRPCMD V_PARERRPCMD(1U)
+
+#define S_PARERRDATA 0
+#define V_PARERRDATA(x) ((x) << S_PARERRDATA)
+#define F_PARERRDATA V_PARERRDATA(1U)
#define A_ULPRX_INT_CAUSE 0x508
@@ -1559,6 +1797,10 @@
#define A_CPL_INTR_ENABLE 0x650
+#define S_CIM_OP_MAP_PERR 5
+#define V_CIM_OP_MAP_PERR(x) ((x) << S_CIM_OP_MAP_PERR)
+#define F_CIM_OP_MAP_PERR V_CIM_OP_MAP_PERR(1U)
+
#define S_CIM_OVFL_ERROR 4
#define V_CIM_OVFL_ERROR(x) ((x) << S_CIM_OVFL_ERROR)
#define F_CIM_OVFL_ERROR V_CIM_OVFL_ERROR(1U)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 666c317..cef153d 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2443,6 +2443,15 @@ irq_handler_t t3_intr_handler(struct adapter *adap, int polling)
return t3_intr;
}
+#define SGE_PARERR (F_CPPARITYERROR | F_OCPARITYERROR | F_RCPARITYERROR | \
+ F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
+ V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
+ F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
+ F_HIRCQPARITYERROR)
+#define SGE_FRAMINGERR (F_UC_REQ_FRAMINGERROR | F_R_REQ_FRAMINGERROR)
+#define SGE_FATALERR (SGE_PARERR | SGE_FRAMINGERR | F_RSPQCREDITOVERFOW | \
+ F_RSPQDISABLED)
+
/**
* t3_sge_err_intr_handler - SGE async event interrupt handler
* @adapter: the adapter
@@ -2453,6 +2462,13 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
{
unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE);
+ if (status & SGE_PARERR)
+ CH_ALERT(adapter, "SGE parity error (0x%x)\n",
+ status & SGE_PARERR);
+ if (status & SGE_FRAMINGERR)
+ CH_ALERT(adapter, "SGE framing error (0x%x)\n",
+ status & SGE_FRAMINGERR);
+
if (status & F_RSPQCREDITOVERFOW)
CH_ALERT(adapter, "SGE response queue credit overflow\n");
@@ -2469,7 +2485,7 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
status & F_HIPIODRBDROPERR ? "high" : "lo");
t3_write_reg(adapter, A_SG_INT_CAUSE, status);
- if (status & (F_RSPQCREDITOVERFOW | F_RSPQDISABLED))
+ if (status & SGE_FATALERR)
t3_fatal_err(adapter);
}
@@ -2781,7 +2797,7 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
unsigned int ctrl, ups = ffs(pci_resource_len(adap->pdev, 2) >> 12);
ctrl = F_DROPPKT | V_PKTSHIFT(2) | F_FLMODE | F_AVOIDCQOVFL |
- F_CQCRDTCTRL |
+ F_CQCRDTCTRL | F_CONGMODE | F_TNLFLMODE | F_FATLPERREN |
V_HOSTPAGESIZE(PAGE_SHIFT - 11) | F_BIGENDIANINGRESS |
V_USERSPACESIZE(ups ? ups - 1 : 0) | F_ISCSICOALESCING;
#if SGE_NUM_GENBITS == 1
@@ -2790,7 +2806,6 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
if (adap->params.rev > 0) {
if (!(adap->flags & (USING_MSIX | USING_MSI)))
ctrl |= F_ONEINTMULTQ | F_OPTONEINTMULTQ;
- ctrl |= F_CQCRDTCTRL | F_AVOIDCQOVFL;
}
t3_write_reg(adap, A_SG_CONTROL, ctrl);
t3_write_reg(adap, A_SG_EGR_RCQ_DRB_THRSH, V_HIRCQDRBTHRSH(512) |
@@ -2798,7 +2813,8 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
t3_write_reg(adap, A_SG_TIMER_TICK, core_ticks_per_usec(adap) / 10);
t3_write_reg(adap, A_SG_CMDQ_CREDIT_TH, V_THRESHOLD(32) |
V_TIMEOUT(200 * core_ticks_per_usec(adap)));
- t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH, 1000);
+ t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH,
+ adap->params.rev < T3_REV_C ? 1000 : 500);
t3_write_reg(adap, A_SG_HI_DRB_LO_THRSH, 256);
t3_write_reg(adap, A_SG_LO_DRB_HI_THRSH, 1000);
t3_write_reg(adap, A_SG_LO_DRB_LO_THRSH, 256);
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index dfdda47..6e5b499 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -62,7 +62,7 @@ int t3_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
return 0;
}
if (--attempts == 0)
- return -EAGAIN;
+ return -EAGAIN;
if (delay)
udelay(delay);
}
@@ -1263,7 +1263,13 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
return fatal;
}
-#define SGE_INTR_MASK (F_RSPQDISABLED)
+#define SGE_INTR_MASK (F_RSPQDISABLED | \
+ F_UC_REQ_FRAMINGERROR | F_R_REQ_FRAMINGERROR | \
+ F_CPPARITYERROR | F_OCPARITYERROR | F_RCPARITYERROR | \
+ F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
+ V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
+ F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
+ F_HIRCQPARITYERROR)
#define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \
F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \
F_NFASRCHFAIL)
@@ -1280,16 +1286,23 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
#define PCIE_INTR_MASK (F_UNXSPLCPLERRR | F_UNXSPLCPLERRC | F_PCIE_PIOPARERR |\
F_PCIE_WFPARERR | F_PCIE_RFPARERR | F_PCIE_CFPARERR | \
/* V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR) | */ \
- V_BISTERR(M_BISTERR))
-#define ULPRX_INTR_MASK F_PARERR
-#define ULPTX_INTR_MASK 0
-#define CPLSW_INTR_MASK (F_TP_FRAMING_ERROR | \
+ F_RETRYBUFPARERR | F_RETRYLUTPARERR | F_RXPARERR | \
+ F_TXPARERR | V_BISTERR(M_BISTERR))
+#define ULPRX_INTR_MASK (F_PARERRDATA | F_PARERRPCMD | F_ARBPF1PERR | \
+ F_ARBPF0PERR | F_ARBFPERR | F_PCMDMUXPERR | \
+ F_DATASELFRAMEERR1 | F_DATASELFRAMEERR0)
+#define ULPTX_INTR_MASK 0xfc
+#define CPLSW_INTR_MASK (F_CIM_OP_MAP_PERR | F_TP_FRAMING_ERROR | \
F_SGE_FRAMING_ERROR | F_CIM_FRAMING_ERROR | \
F_ZERO_SWITCH_ERROR)
#define CIM_INTR_MASK (F_BLKWRPLINT | F_BLKRDPLINT | F_BLKWRCTLINT | \
F_BLKRDCTLINT | F_BLKWRFLASHINT | F_BLKRDFLASHINT | \
F_SGLWRFLASHINT | F_WRBLKFLASHINT | F_BLKWRBOOTINT | \
- F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT)
+ F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT | \
+ F_DRAMPARERR | F_ICACHEPARERR | F_DCACHEPARERR | \
+ F_OBQSGEPARERR | F_OBQULPHIPARERR | F_OBQULPLOPARERR | \
+ F_IBQSGELOPARERR | F_IBQSGEHIPARERR | F_IBQULPPARERR | \
+ F_IBQTPPARERR | F_ITAGPARERR | F_DTAGPARERR)
#define PMTX_INTR_MASK (F_ZERO_C_CMD_ERROR | ICSPI_FRM_ERR | OESPI_FRM_ERR | \
V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR) | \
V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR))
@@ -1358,6 +1371,10 @@ static void pcie_intr_handler(struct adapter *adapter)
{F_PCIE_CFPARERR, "PCI command FIFO parity error", -1, 1},
{V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR),
"PCI MSI-X table/PBA parity error", -1, 1},
+ {F_RETRYBUFPARERR, "PCI retry buffer parity error", -1, 1},
+ {F_RETRYLUTPARERR, "PCI retry LUT parity error", -1, 1},
+ {F_RXPARERR, "PCI Rx parity error", -1, 1},
+ {F_TXPARERR, "PCI Tx parity error", -1, 1},
{V_BISTERR(M_BISTERR), "PCI BIST error", -1, 1},
{0}
};
@@ -1384,15 +1401,15 @@ static void tp_intr_handler(struct adapter *adapter)
};
static struct intr_info tp_intr_info_t3c[] = {
- { 0x1ffffff, "TP parity error", -1, 1 },
- { F_FLMRXFLSTEMPTY, "TP out of Rx pages", -1, 1 },
- { F_FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 },
- { 0 }
+ {0x1fffffff, "TP parity error", -1, 1},
+ {F_FLMRXFLSTEMPTY, "TP out of Rx pages", -1, 1},
+ {F_FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1},
+ {0}
};
if (t3_handle_intr_status(adapter, A_TP_INT_CAUSE, 0xffffffff,
adapter->params.rev < T3_REV_C ?
- tp_intr_info : tp_intr_info_t3c, NULL))
+ tp_intr_info : tp_intr_info_t3c, NULL))
t3_fatal_err(adapter);
}
@@ -1414,6 +1431,18 @@ static void cim_intr_handler(struct adapter *adapter)
{F_BLKWRCTLINT, "CIM block write to CTL space", -1, 1},
{F_BLKRDPLINT, "CIM block read from PL space", -1, 1},
{F_BLKWRPLINT, "CIM block write to PL space", -1, 1},
+ {F_DRAMPARERR, "CIM DRAM parity error", -1, 1},
+ {F_ICACHEPARERR, "CIM icache parity error", -1, 1},
+ {F_DCACHEPARERR, "CIM dcache parity error", -1, 1},
+ {F_OBQSGEPARERR, "CIM OBQ SGE parity error", -1, 1},
+ {F_OBQULPHIPARERR, "CIM OBQ ULPHI parity error", -1, 1},
+ {F_OBQULPLOPARERR, "CIM OBQ ULPLO parity error", -1, 1},
+ {F_IBQSGELOPARERR, "CIM IBQ SGELO parity error", -1, 1},
+ {F_IBQSGEHIPARERR, "CIM IBQ SGEHI parity error", -1, 1},
+ {F_IBQULPPARERR, "CIM IBQ ULP parity error", -1, 1},
+ {F_IBQTPPARERR, "CIM IBQ TP parity error", -1, 1},
+ {F_ITAGPARERR, "CIM itag parity error", -1, 1},
+ {F_DTAGPARERR, "CIM dtag parity error", -1, 1},
{0}
};
@@ -1428,7 +1457,14 @@ static void cim_intr_handler(struct adapter *adapter)
static void ulprx_intr_handler(struct adapter *adapter)
{
static const struct intr_info ulprx_intr_info[] = {
- {F_PARERR, "ULP RX parity error", -1, 1},
+ {F_PARERRDATA, "ULP RX data parity error", -1, 1},
+ {F_PARERRPCMD, "ULP RX command parity error", -1, 1},
+ {F_ARBPF1PERR, "ULP RX ArbPF1 parity error", -1, 1},
+ {F_ARBPF0PERR, "ULP RX ArbPF0 parity error", -1, 1},
+ {F_ARBFPERR, "ULP RX ArbF parity error", -1, 1},
+ {F_PCMDMUXPERR, "ULP RX PCMDMUX parity error", -1, 1},
+ {F_DATASELFRAMEERR1, "ULP RX frame error", -1, 1},
+ {F_DATASELFRAMEERR0, "ULP RX frame error", -1, 1},
{0}
};
@@ -1447,6 +1483,7 @@ static void ulptx_intr_handler(struct adapter *adapter)
STAT_ULP_CH0_PBL_OOB, 0},
{F_PBL_BOUND_ERR_CH1, "ULP TX channel 1 PBL out of bounds",
STAT_ULP_CH1_PBL_OOB, 0},
+ {0xfc, "ULP TX parity error", -1, 1},
{0}
};
@@ -1521,7 +1558,8 @@ static void pmrx_intr_handler(struct adapter *adapter)
static void cplsw_intr_handler(struct adapter *adapter)
{
static const struct intr_info cplsw_intr_info[] = {
-/* { F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1 }, */
+ {F_CIM_OP_MAP_PERR, "CPL switch CIM parity error", -1, 1},
+ {F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1},
{F_TP_FRAMING_ERROR, "CPL switch TP framing error", -1, 1},
{F_SGE_FRAMING_ERROR, "CPL switch SGE framing error", -1, 1},
{F_CIM_FRAMING_ERROR, "CPL switch CIM framing error", -1, 1},
@@ -1907,6 +1945,16 @@ static int t3_sge_write_context(struct adapter *adapter, unsigned int id,
0, SG_CONTEXT_CMD_ATTEMPTS, 1);
}
+static int clear_sge_ctxt(struct adapter *adap, unsigned int id,
+ unsigned int type)
+{
+ t3_write_reg(adap, A_SG_CONTEXT_DATA0, 0);
+ t3_write_reg(adap, A_SG_CONTEXT_DATA1, 0);
+ t3_write_reg(adap, A_SG_CONTEXT_DATA2, 0);
+ t3_write_reg(adap, A_SG_CONTEXT_DATA3, 0);
+ return t3_sge_write_context(adap, id, type);
+}
+
/**
* t3_sge_init_ecntxt - initialize an SGE egress context
* @adapter: the adapter to configure
@@ -2408,7 +2456,7 @@ static inline unsigned int pm_num_pages(unsigned int mem_size,
t3_write_reg((adap), A_ ## reg, (start)); \
start += size
-/*
+/**
* partition_mem - partition memory and configure TP memory settings
* @adap: the adapter
* @p: the TP parameters
@@ -2493,7 +2541,7 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1));
- t3_set_reg_field(adap, A_TP_IN_CONFIG, F_IPV6ENABLE | F_NICMODE,
+ t3_set_reg_field(adap, A_TP_IN_CONFIG, F_RXFBARBPRIO | F_TXFBARBPRIO,
F_IPV6ENABLE | F_NICMODE);
t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
@@ -2505,7 +2553,9 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
F_ENABLEEPCMDAFULL,
F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
- t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
+ t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL,
+ F_ENABLEIPV6RSS | F_ENABLENONOFDTNLSYN |
+ F_ENABLEARPMISS | F_DISBLEDAPARBIT0);
t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
@@ -3212,7 +3262,8 @@ static void config_pcie(struct adapter *adap)
V_REPLAYLMT(rpllmt));
t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
- t3_set_reg_field(adap, A_PCIE_CFG, F_PCIE_CLIDECEN, F_PCIE_CLIDECEN);
+ t3_set_reg_field(adap, A_PCIE_CFG, 0,
+ F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN);
}
/*
@@ -3225,7 +3276,7 @@ static void config_pcie(struct adapter *adap)
*/
int t3_init_hw(struct adapter *adapter, u32 fw_params)
{
- int err = -EIO, attempts = 100;
+ int err = -EIO, attempts, i;
const struct vpd_params *vpd = &adapter->params.vpd;
if (adapter->params.rev > 0)
@@ -3243,6 +3294,10 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
adapter->params.mc5.nfilters,
adapter->params.mc5.nroutes))
goto out_err;
+
+ for (i = 0; i < 32; i++)
+ if (clear_sge_ctxt(adapter, i, F_CQ))
+ goto out_err;
}
if (tp_init(adapter, &adapter->params.tp))
@@ -3258,7 +3313,8 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
if (is_pcie(adapter))
config_pcie(adapter);
else
- t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
+ t3_set_reg_field(adapter, A_PCIX_CFG, 0,
+ F_DMASTOPEN | F_CLIDECEN);
if (adapter->params.rev == T3_REV_C)
t3_set_reg_field(adapter, A_ULPTX_CONFIG, 0,
@@ -3275,6 +3331,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2));
t3_read_reg(adapter, A_CIM_BOOT_CFG); /* flush */
+ attempts = 100;
do { /* wait for uP to initialize */
msleep(20);
} while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
@@ -3409,6 +3466,7 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
t3_write_reg(adapter, A_T3DBG_GPIO_EN,
ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
+ t3_write_reg(adapter, A_SG_OCO_BASE, V_BASE1(0xfff));
if (adapter->params.rev == 0 || !uses_xaui(adapter))
val |= F_ENRGMII;
@@ -3458,6 +3516,36 @@ static int t3_reset_adapter(struct adapter *adapter)
return 0;
}
+static int __devinit init_parity(struct adapter *adap)
+{
+ int i, err, addr;
+
+ if (t3_read_reg(adap, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
+ return -EBUSY;
+
+ for (err = i = 0; !err && i < 16; i++)
+ err = clear_sge_ctxt(adap, i, F_EGRESS);
+ for (i = 0xfff0; !err && i <= 0xffff; i++)
+ err = clear_sge_ctxt(adap, i, F_EGRESS);
+ for (i = 0; !err && i < SGE_QSETS; i++)
+ err = clear_sge_ctxt(adap, i, F_RESPONSEQ);
+ if (err)
+ return err;
+
+ t3_write_reg(adap, A_CIM_IBQ_DBG_DATA, 0);
+ for (i = 0; i < 4; i++)
+ for (addr = 0; addr <= M_IBQDBGADDR; addr++) {
+ t3_write_reg(adap, A_CIM_IBQ_DBG_CFG, F_IBQDBGEN |
+ F_IBQDBGWR | V_IBQDBGQID(i) |
+ V_IBQDBGADDR(addr));
+ err = t3_wait_op_done(adap, A_CIM_IBQ_DBG_CFG,
+ F_IBQDBGBUSY, 0, 2, 1);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
/*
* Initialize adapter SW state for the various HW modules, set initial values
* for some adapter tunables, take PHYs out of reset, and initialize the MDIO
@@ -3525,6 +3613,9 @@ int __devinit t3_prep_adapter(struct adapter *adapter,
}
early_hw_init(adapter, ai);
+ ret = init_parity(adapter);
+ if (ret)
+ return ret;
for_each_port(adapter, i) {
u8 hw_addr[6];
^ permalink raw reply related
* [PATCH 1/2] cxgb3 - T3C support update
From: Divy Le Ray @ 2007-12-05 18:15 UTC (permalink / raw)
To: jeff, netdev; +Cc: linux-kernel, swise, wenxiong
From: Divy Le Ray <divy@chelsio.com>
Update GPIO mapping for T3C.
Update xgmac for T3C support.
Fix typo in mtu table.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
---
drivers/net/cxgb3/regs.h | 27 ++++++++++++++++++++++++++-
drivers/net/cxgb3/t3_hw.c | 6 +++---
drivers/net/cxgb3/xgmac.c | 44 +++++++++++++++++++++++++++++---------------
3 files changed, 58 insertions(+), 19 deletions(-)
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index a7d5f65..70e1961 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1959,6 +1959,10 @@
#define A_XGM_RXFIFO_CFG 0x884
+#define S_RXFIFO_EMPTY 31
+#define V_RXFIFO_EMPTY(x) ((x) << S_RXFIFO_EMPTY)
+#define F_RXFIFO_EMPTY V_RXFIFO_EMPTY(1U)
+
#define S_RXFIFOPAUSEHWM 17
#define M_RXFIFOPAUSEHWM 0xfff
@@ -1983,6 +1987,10 @@
#define A_XGM_TXFIFO_CFG 0x888
+#define S_UNDERUNFIX 22
+#define V_UNDERUNFIX(x) ((x) << S_UNDERUNFIX)
+#define F_UNDERUNFIX V_UNDERUNFIX(1U)
+
#define S_TXIPG 13
#define M_TXIPG 0xff
#define V_TXIPG(x) ((x) << S_TXIPG)
@@ -2056,10 +2064,27 @@
#define V_XAUIIMP(x) ((x) << S_XAUIIMP)
#define A_XGM_RX_MAX_PKT_SIZE 0x8a8
-#define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4
+
+#define S_RXMAXFRAMERSIZE 17
+#define M_RXMAXFRAMERSIZE 0x3fff
+#define V_RXMAXFRAMERSIZE(x) ((x) << S_RXMAXFRAMERSIZE)
+#define G_RXMAXFRAMERSIZE(x) (((x) >> S_RXMAXFRAMERSIZE) & M_RXMAXFRAMERSIZE)
+
+#define S_RXENFRAMER 14
+#define V_RXENFRAMER(x) ((x) << S_RXENFRAMER)
+#define F_RXENFRAMER V_RXENFRAMER(1U)
+
+#define S_RXMAXPKTSIZE 0
+#define M_RXMAXPKTSIZE 0x3fff
+#define V_RXMAXPKTSIZE(x) ((x) << S_RXMAXPKTSIZE)
+#define G_RXMAXPKTSIZE(x) (((x) >> S_RXMAXPKTSIZE) & M_RXMAXPKTSIZE)
#define A_XGM_RESET_CTRL 0x8ac
+#define S_XGMAC_STOP_EN 4
+#define V_XGMAC_STOP_EN(x) ((x) << S_XGMAC_STOP_EN)
+#define F_XGMAC_STOP_EN V_XGMAC_STOP_EN(1U)
+
#define S_XG2G_RESET_ 3
#define V_XG2G_RESET_(x) ((x) << S_XG2G_RESET_)
#define F_XG2G_RESET_ V_XG2G_RESET_(1U)
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 553dd9a..dfdda47 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -447,8 +447,8 @@ static const struct adapter_info t3_adap_info[] = {
&mi1_mdio_ops, "Chelsio T302"},
{1, 0, 0, 0,
F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
- F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
- SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
+ F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
+ 0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T310"},
{2, 0, 0, 0,
F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
@@ -2631,7 +2631,7 @@ static void __devinit init_mtus(unsigned short mtus[])
* it can accomodate max size TCP/IP headers when SACK and timestamps
* are enabled and still have at least 8 bytes of payload.
*/
- mtus[1] = 88;
+ mtus[0] = 88;
mtus[1] = 88;
mtus[2] = 256;
mtus[3] = 512;
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index 98303fd..ffdc0a1 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -106,6 +106,7 @@ int t3_mac_reset(struct cmac *mac)
t3_set_reg_field(adap, A_XGM_RXFIFO_CFG + oft,
F_RXSTRFRWRD | F_DISERRFRAMES,
uses_xaui(adap) ? 0 : F_RXSTRFRWRD);
+ t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft, 0, F_UNDERUNFIX);
if (uses_xaui(adap)) {
if (adap->params.rev == 0) {
@@ -124,7 +125,11 @@ int t3_mac_reset(struct cmac *mac)
xaui_serdes_reset(mac);
}
- val = F_MAC_RESET_;
+ t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + oft,
+ V_RXMAXFRAMERSIZE(M_RXMAXFRAMERSIZE),
+ V_RXMAXFRAMERSIZE(MAX_FRAME_SIZE) | F_RXENFRAMER);
+ val = F_MAC_RESET_ | F_XGMAC_STOP_EN;
+
if (is_10G(adap))
val |= F_PCS_RESET_;
else if (uses_xaui(adap))
@@ -313,8 +318,9 @@ static int rx_fifo_hwm(int mtu)
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
{
- int hwm, lwm;
- unsigned int thres, v;
+ int hwm, lwm, divisor;
+ int ipg;
+ unsigned int thres, v, reg;
struct adapter *adap = mac->adapter;
/*
@@ -335,27 +341,32 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
- if (adap->params.rev == T3_REV_B2 &&
+ if (adap->params.rev >= T3_REV_B2 &&
(t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
disable_exact_filters(mac);
v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
- /* drain rx FIFO */
- if (t3_wait_op_done(adap,
- A_XGM_RX_MAX_PKT_SIZE_ERR_CNT +
- mac->offset,
- 1 << 31, 1, 20, 5)) {
+ reg = adap->params.rev == T3_REV_B2 ?
+ A_XGM_RX_MAX_PKT_SIZE_ERR_CNT : A_XGM_RXFIFO_CFG;
+
+ /* drain RX FIFO */
+ if (t3_wait_op_done(adap, reg + mac->offset,
+ F_RXFIFO_EMPTY, 1, 20, 5)) {
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
enable_exact_filters(mac);
return -EIO;
}
- t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
+ t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
+ V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
+ V_RXMAXPKTSIZE(mtu));
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
enable_exact_filters(mac);
} else
- t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
+ t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
+ V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
+ V_RXMAXPKTSIZE(mtu));
/*
* Adjust the PAUSE frame watermarks. We always set the LWM, and the
@@ -379,13 +390,16 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
thres /= 10;
thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
thres = max(thres, 8U); /* need at least 8 */
+ ipg = (adap->params.rev == T3_REV_C) ? 0 : 1;
t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
- V_TXFIFOTHRESH(thres) | V_TXIPG(1));
+ V_TXFIFOTHRESH(thres) | V_TXIPG(ipg));
- if (adap->params.rev > 0)
+ if (adap->params.rev > 0) {
+ divisor = (adap->params.rev == T3_REV_C) ? 64 : 8;
t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
- (hwm - lwm) * 4 / 8);
+ (hwm - lwm) * 4 / divisor);
+ }
t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
MAC_RXFIFO_SIZE * 4 * 8 / 512);
return 0;
@@ -522,7 +536,7 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
goto rxcheck;
}
- if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0)) {
+ if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0)) {
if (mac->toggle_cnt > 4) {
status = 2;
goto out;
^ permalink raw reply related
* [PATCH 0/2] cxgb3 - driver update
From: Divy Le Ray @ 2007-12-05 18:14 UTC (permalink / raw)
To: Jeff Garzik, netdev; +Cc: linux-kernel, Steve Wise, Wen Xiong
Jeff,
I'm submitting a patch series for inclusion in 2.6.25.
The patches are built against netdev#upstream.
Here is a brief description:
- Update GPIO pinning and MAC support for T3C adapters
- Enable parity error detection.
Cheers,
Divy
^ permalink raw reply
* Re: cassini driver skb->truesize bug
From: KOVACS Krisztian @ 2007-12-05 17:30 UTC (permalink / raw)
To: Balazs Scheidler; +Cc: panther, netdev
In-Reply-To: <1196850226.9713.33.camel@bzorp.balabit>
Hi,
On Wed, Dec 05, 2007 at 11:23:46AM +0100, Balazs Scheidler wrote:
> Some more investigation revealed that the cassini driver leaks the data
> portion of all RXed packets, this makes the driver completely unusable.
>
> We've tested the following combinations:
> * 2.6.17 (patched, but no cassini related patches)
> * 2.6.22 Ubuntu Gutsy.
>
> It still worked in 2.6.12 where we originally backported the driver from
> 2.6.14.
>
> The sk_buff count in slabinfo stays normal, so the skbs are properly
> freed. I'm suspicious about all this cas_page_t wrappers.
Commit fa4f0774d7c6cccb4d1fda76b91dd8eddcb2dd6a?
I don't really see how the buffer count for a page used as a fragment gets
decreased when the skb is freed.
--
KOVACS Krisztian
^ permalink raw reply
* [PATCH net-2.6.25 3/3][ARP] Consolidate some code in arp_req_set/delete_publc
From: Pavel Emelyanov @ 2007-12-05 17:18 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
The PROXY_ARP is set on devconfigs in a similar way in
both calls.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 0a3f00c..ccd36fa 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -953,6 +953,19 @@ out_of_mem:
* Set (create) an ARP cache entry.
*/
+static int arp_req_set_proxy(struct net_device *dev, int on)
+{
+ if (dev == NULL) {
+ IPV4_DEVCONF_ALL(PROXY_ARP) = on;
+ return 0;
+ }
+ if (__in_dev_get_rtnl(dev)) {
+ IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
+ return 0;
+ }
+ return -ENXIO;
+}
+
static int arp_req_set_public(struct arpreq *r, struct net_device *dev)
{
__be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
@@ -971,15 +984,8 @@ static int arp_req_set_public(struct arpreq *r, struct net_device *dev)
return -ENOBUFS;
return 0;
}
- if (dev == NULL) {
- IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
- return 0;
- }
- if (__in_dev_get_rtnl(dev)) {
- IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
- return 0;
- }
- return -ENXIO;
+
+ return arp_req_set_proxy(dev, 1);
}
static int arp_req_set(struct arpreq *r, struct net_device * dev)
@@ -1083,19 +1089,10 @@ static int arp_req_delete_public(struct arpreq *r, struct net_device *dev)
if (mask == htonl(0xFFFFFFFF))
return pneigh_delete(&arp_tbl, &ip, dev);
- if (mask == 0) {
- if (dev == NULL) {
- IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
- return 0;
- }
- if (__in_dev_get_rtnl(dev)) {
- IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
- PROXY_ARP, 0);
- return 0;
- }
- return -ENXIO;
- }
- return -EINVAL;
+ if (mask)
+ return -EINVAL;
+
+ return arp_req_set_proxy(dev, 0);
}
static int arp_req_delete(struct arpreq *r, struct net_device * dev)
--
1.5.3.4
^ permalink raw reply related
* [PATCH net-2.6.25 2/3][ARP] Minus one level of ndentation in arp_req_delete
From: Pavel Emelyanov @ 2007-12-05 17:16 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
The same cleanup for deletion requests.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index d628e6e..0a3f00c 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1075,32 +1075,39 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
return err;
}
+static int arp_req_delete_public(struct arpreq *r, struct net_device *dev)
+{
+ __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+ __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
+
+ if (mask == htonl(0xFFFFFFFF))
+ return pneigh_delete(&arp_tbl, &ip, dev);
+
+ if (mask == 0) {
+ if (dev == NULL) {
+ IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
+ return 0;
+ }
+ if (__in_dev_get_rtnl(dev)) {
+ IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
+ PROXY_ARP, 0);
+ return 0;
+ }
+ return -ENXIO;
+ }
+ return -EINVAL;
+}
+
static int arp_req_delete(struct arpreq *r, struct net_device * dev)
{
int err;
- __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+ __be32 ip;
struct neighbour *neigh;
- if (r->arp_flags & ATF_PUBL) {
- __be32 mask =
- ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
- if (mask == htonl(0xFFFFFFFF))
- return pneigh_delete(&arp_tbl, &ip, dev);
- if (mask == 0) {
- if (dev == NULL) {
- IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
- return 0;
- }
- if (__in_dev_get_rtnl(dev)) {
- IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
- PROXY_ARP, 0);
- return 0;
- }
- return -ENXIO;
- }
- return -EINVAL;
- }
+ if (r->arp_flags & ATF_PUBL)
+ return arp_req_delete_public(r, dev);
+ ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
if (dev == NULL) {
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
.tos = RTO_ONLINK } } };
--
1.5.3.4
^ permalink raw reply related
* [PATCH net-2.6.25 1/3][ARP] Minus one level of indentation in arp_req_set
From: Pavel Emelyanov @ 2007-12-05 17:15 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
The ATF_PUBL requests are handled completely separate from
the others. Emphasize it with a separate function. This also
reduces the indentation level.
The same issue exists with the arp_delete_request, but
when I tried to make it in one patch diff produced completely
unreadable patch. So I split it into two, but they may be
done with one commit.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index b3f366a..d628e6e 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -953,37 +953,45 @@ out_of_mem:
* Set (create) an ARP cache entry.
*/
+static int arp_req_set_public(struct arpreq *r, struct net_device *dev)
+{
+ __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+ __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
+
+ if (mask && mask != htonl(0xFFFFFFFF))
+ return -EINVAL;
+ if (!dev && (r->arp_flags & ATF_COM)) {
+ dev = dev_getbyhwaddr(&init_net, r->arp_ha.sa_family,
+ r->arp_ha.sa_data);
+ if (!dev)
+ return -ENODEV;
+ }
+ if (mask) {
+ if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)
+ return -ENOBUFS;
+ return 0;
+ }
+ if (dev == NULL) {
+ IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
+ return 0;
+ }
+ if (__in_dev_get_rtnl(dev)) {
+ IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
+ return 0;
+ }
+ return -ENXIO;
+}
+
static int arp_req_set(struct arpreq *r, struct net_device * dev)
{
- __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+ __be32 ip;
struct neighbour *neigh;
int err;
- if (r->arp_flags&ATF_PUBL) {
- __be32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;
- if (mask && mask != htonl(0xFFFFFFFF))
- return -EINVAL;
- if (!dev && (r->arp_flags & ATF_COM)) {
- dev = dev_getbyhwaddr(&init_net, r->arp_ha.sa_family, r->arp_ha.sa_data);
- if (!dev)
- return -ENODEV;
- }
- if (mask) {
- if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)
- return -ENOBUFS;
- return 0;
- }
- if (dev == NULL) {
- IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
- return 0;
- }
- if (__in_dev_get_rtnl(dev)) {
- IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
- return 0;
- }
- return -ENXIO;
- }
+ if (r->arp_flags & ATF_PUBL)
+ return arp_req_set_public(r, dev);
+ ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
if (r->arp_flags & ATF_PERM)
r->arp_flags |= ATF_COM;
if (dev == NULL) {
--
1.5.3.4
^ permalink raw reply related
* [PATCH net-2.6.25 3/3][ROUTE] Convert rt_hash_lock_init() macro into function
From: Pavel Emelyanov @ 2007-12-05 17:09 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
There's no need in having this function exist in a form
of macro. Properly formatted function looks much better.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 3b9c430..6714bbc 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -235,16 +235,25 @@ struct rt_hash_bucket {
static spinlock_t *rt_hash_locks;
# define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)]
-# define rt_hash_lock_init() { \
- int i; \
- rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ, GFP_KERNEL); \
- if (!rt_hash_locks) panic("IP: failed to allocate rt_hash_locks\n"); \
- for (i = 0; i < RT_HASH_LOCK_SZ; i++) \
- spin_lock_init(&rt_hash_locks[i]); \
- }
+
+static __init void rt_hash_lock_init(void)
+{
+ int i;
+
+ rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ,
+ GFP_KERNEL);
+ if (!rt_hash_locks)
+ panic("IP: failed to allocate rt_hash_locks\n");
+
+ for (i = 0; i < RT_HASH_LOCK_SZ; i++)
+ spin_lock_init(&rt_hash_locks[i]);
+}
#else
# define rt_hash_lock_addr(slot) NULL
-# define rt_hash_lock_init()
+
+static inline void rt_hash_lock_init(void)
+{
+}
#endif
static struct rt_hash_bucket *rt_hash_table;
--
1.5.3.4
^ permalink raw reply related
* [PATCH net-2.6.25 2/3][ROUTE] Clean up proc files creation
From: Pavel Emelyanov @ 2007-12-05 17:06 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
The rt_cache, stats/rt_cache and rt_acct(optional) files
creation looks a bit messy. Clean this out and join them
to other proc-related functions under the proper ifdef.
The struct net * argument in a new function will help net
namespaces patches look nicer.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index cc5b730..3b9c430 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -520,6 +520,44 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
return length;
}
#endif
+
+static __init int ip_rt_proc_init(struct net *net)
+{
+ struct proc_dir_entry *pde;
+
+ pde = proc_net_fops_create(net, "rt_cache", S_IRUGO,
+ &rt_cache_seq_fops);
+ if (!pde)
+ goto err1;
+
+ pde = create_proc_entry("rt_cache", S_IRUGO, net->proc_net_stat);
+ if (!pde)
+ goto err2;
+
+ pde->proc_fops = &rt_cpu_seq_fops;
+
+#ifdef CONFIG_NET_CLS_ROUTE
+ pde = create_proc_read_entry("rt_acct", 0, net->proc_net,
+ ip_rt_acct_read, NULL);
+ if (!pde)
+ goto err3;
+#endif
+ return 0;
+
+#ifdef CONFIG_NET_CLS_ROUTE
+err3:
+ remove_proc_entry("rt_cache", net->proc_net_stat);
+#endif
+err2:
+ remove_proc_entry("rt_cache", net->proc_net);
+err1:
+ return -ENOMEM;
+}
+#else
+static inline int ip_rt_proc_init(struct net *net)
+{
+ return 0;
+}
#endif /* CONFIG_PROC_FS */
static __inline__ void rt_free(struct rtable *rt)
@@ -2997,20 +3035,8 @@ int __init ip_rt_init(void)
ip_rt_secret_interval;
add_timer(&rt_secret_timer);
-#ifdef CONFIG_PROC_FS
- {
- struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */
- if (!proc_net_fops_create(&init_net, "rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
- !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
- init_net.proc_net_stat))) {
- return -ENOMEM;
- }
- rtstat_pde->proc_fops = &rt_cpu_seq_fops;
- }
-#ifdef CONFIG_NET_CLS_ROUTE
- create_proc_read_entry("rt_acct", 0, init_net.proc_net, ip_rt_acct_read, NULL);
-#endif
-#endif
+ if (ip_rt_proc_init(&init_net))
+ printk(KERN_ERR "Unable to create route proc files\n");
#ifdef CONFIG_XFRM
xfrm_init();
xfrm4_init();
--
1.5.3.4
^ permalink raw reply related
* [PATCH net-2.6.25 1/3][ROUTE] Collect proc-related functions together
From: Pavel Emelyanov @ 2007-12-05 17:04 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
The net/ipv4/route.c file declares some entries for proc
to dump some routing info. The reading functions are
scattered over this file - collect them together.
Besides, remove a useless IP_RT_ACCT_CPU macro.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 134cab5..cc5b730 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -481,6 +481,45 @@ static const struct file_operations rt_cpu_seq_fops = {
.release = seq_release,
};
+#ifdef CONFIG_NET_CLS_ROUTE
+static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
+ int length, int *eof, void *data)
+{
+ unsigned int i;
+
+ if ((offset & 3) || (length & 3))
+ return -EIO;
+
+ if (offset >= sizeof(struct ip_rt_acct) * 256) {
+ *eof = 1;
+ return 0;
+ }
+
+ if (offset + length >= sizeof(struct ip_rt_acct) * 256) {
+ length = sizeof(struct ip_rt_acct) * 256 - offset;
+ *eof = 1;
+ }
+
+ offset /= sizeof(u32);
+
+ if (length > 0) {
+ u32 *dst = (u32 *) buffer;
+
+ *start = buffer;
+ memset(dst, 0, length);
+
+ for_each_possible_cpu(i) {
+ unsigned int j;
+ u32 *src;
+
+ src = ((u32 *) per_cpu_ptr(ip_rt_acct, i)) + offset;
+ for (j = 0; j < length/4; j++)
+ dst[j] += src[j];
+ }
+ }
+ return length;
+}
+#endif
#endif /* CONFIG_PROC_FS */
static __inline__ void rt_free(struct rtable *rt)
@@ -2895,48 +2934,6 @@ ctl_table ipv4_route_table[] = {
#ifdef CONFIG_NET_CLS_ROUTE
struct ip_rt_acct *ip_rt_acct __read_mostly;
-
-/* IP route accounting ptr for this logical cpu number. */
-#define IP_RT_ACCT_CPU(cpu) (per_cpu_ptr(ip_rt_acct, cpu))
-
-#ifdef CONFIG_PROC_FS
-static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
-{
- unsigned int i;
-
- if ((offset & 3) || (length & 3))
- return -EIO;
-
- if (offset >= sizeof(struct ip_rt_acct) * 256) {
- *eof = 1;
- return 0;
- }
-
- if (offset + length >= sizeof(struct ip_rt_acct) * 256) {
- length = sizeof(struct ip_rt_acct) * 256 - offset;
- *eof = 1;
- }
-
- offset /= sizeof(u32);
-
- if (length > 0) {
- u32 *dst = (u32 *) buffer;
-
- *start = buffer;
- memset(dst, 0, length);
-
- for_each_possible_cpu(i) {
- unsigned int j;
- u32 *src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset;
-
- for (j = 0; j < length/4; j++)
- dst[j] += src[j];
- }
- }
- return length;
-}
-#endif /* CONFIG_PROC_FS */
#endif /* CONFIG_NET_CLS_ROUTE */
static __initdata unsigned long rhash_entries;
--
1.5.3.4
^ permalink raw reply related
* Re: TCP event tracking via netlink...
From: Joe Perches @ 2007-12-05 16:53 UTC (permalink / raw)
To: David Miller; +Cc: ilpo.jarvinen, netdev
In-Reply-To: <20071205.053031.87154402.davem@davemloft.net>
> it occurred to me that we might want to do something
> like a state change event generator.
This could be a basis for an interesting TCP
performance tester.
^ permalink raw reply
* Re: [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Arnaldo Carvalho de Melo @ 2007-12-05 15:18 UTC (permalink / raw)
To: Gerrit Renker, Arnaldo Carvalho de Melo, dccp, netdev
In-Reply-To: <20071205145309.GA10991@gerrit.erg.abdn.ac.uk>
Em Wed, Dec 05, 2007 at 02:53:09PM +0000, Gerrit Renker escreveu:
> | Thanks, I folded this into the reorganized RX history handling patch,
> | together with reverting ccid3_hc_rx_packet_recv to very close to your
> | original patch, with this changes:
> |
> | 1. no need to calculate the payload size for non data packets as this
> | value won't be used.
> | 2. Initialize hcrx->ccid3hcrx_bytes_recv with the payload size when
> | hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA.
> | 3. tfrc_rx_hist_duplicate() is only called when ccid3hcrx_state !=
> | TFRC_RSTATE_NO_DATA, so it doesn't need to goto the done_receiving
> | label (that was removed as this was its only use) as do_feedback
> | would always be CCID3_FBACK_NONE and so the test would always fail
> | and no feedback would be sent, so just return right there.
> |
> | Now it reads:
> |
> | static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
> | {
> | struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
> | enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE;
> | const u32 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
> | const bool is_data_packet = dccp_data_packet(skb);
> |
> | if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
> | if (is_data_packet) {
> | const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
> | do_feedback = FBACK_INITIAL;
> | ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
> | hcrx->ccid3hcrx_s =
> | hcrx->ccid3hcrx_bytes_recv = payload_size;
>
> ==> Please see other email regarding bytes_recv, but I think you already got that.
> Maybe one could then write
> hcrx->ccid3hcrx_s = skb->len - dccp_hdr(skb)->dccph_doff * 4;
OK, I got that.
> | }
> | goto update_records;
> | }
> |
> | if (tfrc_rx_hist_duplicate(&hcrx->ccid3hcrx_hist, skb))
> | return; /* done receiving */
> |
> | if (is_data_packet) {
> | const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
> | /*
> | * Update moving-average of s and the sum of received payload bytes
> | */
> | hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, payload_size, 9);
> | hcrx->ccid3hcrx_bytes_recv += payload_size;
> | }
> |
> | /*
> | * Handle pending losses and otherwise check for new loss
> | */
> | if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
> | goto update_records;
> |
> | /*
> | * Handle data packets: RTT sampling and monitoring p
> | */
> | if (unlikely(!is_data_packet))
> | goto update_records;
> |
> | if (list_empty(&hcrx->ccid3hcrx_li_hist)) { /* no loss so far: p = 0 */
> | const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
> ==> If you like, you could add the original comment here that p=0 if no loss occured, i.e.
> /*
> * Empty loss history: no loss so far, hence p stays 0.
> * Sample RTT values, since an RTT estimate is required for the
> * computation of p when the first loss occurs; RFC 3448, 6.3.1.
> */
done
> | if (sample != 0)
> | hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);
> | }
> |
> | /*
> | * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3
> | */
> | if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->ccid3hcrx_last_counter) > 3)
> | do_feedback = CCID3_FBACK_PERIODIC;
> |
> | update_records:
> | tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);
> |
> ==> here a jump label is missing. It is not needed by this patch and
> above you have replaced it with a return + comment, but it is needed in a later
> patch: when a new loss event occurs, the control jumps to `done_receiving' and
> sends a feedback packet with type FBACK_PARAM_CHANGE.
OK, I was wondering that the user for FBACK_PARAM_CHANGE in
ccid3_hc_rx_send_feedback was in another patch.
> done_receiving:
Ok, we can add the jump label when we make use of it
> | if (do_feedback)
> | ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
> | }
> |
>
> | Now to some questions and please bear with me as I haven't got to the
> | patches after this:
> |
> | tfrc_rx_hist->loss_count as of now is a boolean, my understanding is
> | that you are counting loss events, i.e. it doesn't matter in:
> |
> It is not a boolean, but uses a hidden trick which maybe should be commented:
> * here and in the TCP world NDUPACK = 3
> * hence the bitfield size for loss_count is 2 bits, which can express
> at most 3 = NDUPACK (that is why it is declared as loss_count:2)
> * the trick is that when the loss count increases beyond 3, it automatically
> cycles back to 0 (although the code does not rely on that features
> and does this explicitly);
> * loss_start is the same
OK, will read the next patches with this in mind, thanks for the
explanations.
- Arnaldo
^ permalink raw reply
* Re: TCP event tracking via netlink...
From: Samir Bellabes @ 2007-12-05 15:12 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: John Heffner, David Miller, ilpo.jarvinen, netdev
In-Reply-To: <20071205144843.GB2623@2ka.mipt.ru>
Evgeniy Polyakov <johnpol@2ka.mipt.ru> writes:
> Hi.
>
> On Wed, Dec 05, 2007 at 09:11:01AM -0500, John Heffner (jheffner@psc.edu) wrote:
>> >Maybe if we want to get really fancy we can have some more-expensive
>> >debug mode where detailed specific events get generated via some
>> >macros we can scatter all over the place. This won't be useful
>> >for general user problem analysis, but it will be excellent for
>> >developers.
>> >
>> >Let me know if you think this is useful enough and I'll work on
>> >an implementation we can start playing with.
>>
>>
>> FWIW, sounds similar to what these guys are doing with SIFTR for FreeBSD:
>> http://caia.swin.edu.au/urp/newtcp/tools.html
>> http://caia.swin.edu.au/reports/070824A/CAIA-TR-070824A.pdf
>
> And even more similar to this patch from Samir Bellabes of Mandriva:
> http://lwn.net/Articles/202255/
Indeed, I was thinking about this idea. but yet, my goal is not to deal
with specific protocols like TCP, it's just to deal with the LSM hooks.
Anyway, the idea is the same, having a deamon is userspace to catch
informations. So why not a expansion?
Lately, I'm moving the code to generic netlink, from connector.
regards,
sam
^ permalink raw reply
* Re: [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Gerrit Renker @ 2007-12-05 14:53 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, dccp, netdev
In-Reply-To: <20071205141027.GD4653@ghostprotocols.net>
| Thanks, I folded this into the reorganized RX history handling patch,
| together with reverting ccid3_hc_rx_packet_recv to very close to your
| original patch, with this changes:
|
| 1. no need to calculate the payload size for non data packets as this
| value won't be used.
| 2. Initialize hcrx->ccid3hcrx_bytes_recv with the payload size when
| hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA.
| 3. tfrc_rx_hist_duplicate() is only called when ccid3hcrx_state !=
| TFRC_RSTATE_NO_DATA, so it doesn't need to goto the done_receiving
| label (that was removed as this was its only use) as do_feedback
| would always be CCID3_FBACK_NONE and so the test would always fail
| and no feedback would be sent, so just return right there.
|
| Now it reads:
|
| static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
| {
| struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
| enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE;
| const u32 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
| const bool is_data_packet = dccp_data_packet(skb);
|
| if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
| if (is_data_packet) {
| const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
| do_feedback = FBACK_INITIAL;
| ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
| hcrx->ccid3hcrx_s =
| hcrx->ccid3hcrx_bytes_recv = payload_size;
==> Please see other email regarding bytes_recv, but I think you already got that.
Maybe one could then write
hcrx->ccid3hcrx_s = skb->len - dccp_hdr(skb)->dccph_doff * 4;
| }
| goto update_records;
| }
|
| if (tfrc_rx_hist_duplicate(&hcrx->ccid3hcrx_hist, skb))
| return; /* done receiving */
|
| if (is_data_packet) {
| const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
| /*
| * Update moving-average of s and the sum of received payload bytes
| */
| hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, payload_size, 9);
| hcrx->ccid3hcrx_bytes_recv += payload_size;
| }
|
| /*
| * Handle pending losses and otherwise check for new loss
| */
| if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
| goto update_records;
|
| /*
| * Handle data packets: RTT sampling and monitoring p
| */
| if (unlikely(!is_data_packet))
| goto update_records;
|
| if (list_empty(&hcrx->ccid3hcrx_li_hist)) { /* no loss so far: p = 0 */
| const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
==> If you like, you could add the original comment here that p=0 if no loss occured, i.e.
/*
* Empty loss history: no loss so far, hence p stays 0.
* Sample RTT values, since an RTT estimate is required for the
* computation of p when the first loss occurs; RFC 3448, 6.3.1.
*/
| if (sample != 0)
| hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);
| }
|
| /*
| * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3
| */
| if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->ccid3hcrx_last_counter) > 3)
| do_feedback = CCID3_FBACK_PERIODIC;
|
| update_records:
| tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);
|
==> here a jump label is missing. It is not needed by this patch and
above you have replaced it with a return + comment, but it is needed in a later
patch: when a new loss event occurs, the control jumps to `done_receiving' and
sends a feedback packet with type FBACK_PARAM_CHANGE.
done_receiving:
| if (do_feedback)
| ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
| }
|
| Now to some questions and please bear with me as I haven't got to the
| patches after this:
|
| tfrc_rx_hist->loss_count as of now is a boolean, my understanding is
| that you are counting loss events, i.e. it doesn't matter in:
|
It is not a boolean, but uses a hidden trick which maybe should be commented:
* here and in the TCP world NDUPACK = 3
* hence the bitfield size for loss_count is 2 bits, which can express
at most 3 = NDUPACK (that is why it is declared as loss_count:2)
* the trick is that when the loss count increases beyond 3, it automatically
cycles back to 0 (although the code does not rely on that features
and does this explicitly);
* loss_start is the same
| /* any data packets missing between last reception and skb ? */
| int tfrc_rx_hist_new_loss_indicated(struct tfrc_rx_hist *h,
| const struct sk_buff *skb, u32 ndp)
| {
| int delta = dccp_delta_seqno(tfrc_rx_hist_last_rcv(h)->tfrchrx_seqno,
| DCCP_SKB_CB(skb)->dccpd_seq);
|
| if (delta > 1 && ndp < delta)
| tfrc_rx_hist_loss_indicated(h);
|
| return tfrc_rx_hist_loss_pending(h);
| }
|
| if (delta - ndp) is > 1, i.e. tfrc_rx_hist->loss_count only indicates
| that there was loss. But then in other parts of the code it assumes it
| can be more than 1:
In the above case the first loss is recorded in the history, which is
why loss_count is set to 1. Maybe it gets clearer in the next patch set,
which has three helper functions
__one_after_loss: to deal with the first lost packet
__two_after_loss: which deals when loss_count=2 packets are missing
__three_after_loss is already a new loss event (3=NDUPACK), so that
function only recycles the loss records
| /**
| * tfrc_rx_hist - RX history structure for TFRC-based protocols
| *
| * @ring: Packet history for RTT sampling and loss detection
| * @loss_count: Number of entries in circular history
| * @loss_start: Movable index (for loss detection)
| * @rtt_sample_prev: Used during RTT sampling, points to candidate entry
| */
| struct tfrc_rx_hist {
| struct tfrc_rx_hist_entry *ring[TFRC_NDUPACK + 1];
| u8 loss_count:2,
| loss_start:2;
| #define rtt_sample_prev loss_start
| };
|
| There is space for TFRC_NDUPACK + 1 possible values in loss_count (:2)
| and the comment says it is the number of entries in the circular
| history, and also:
|
| /* has the packet contained in skb been seen before? */
| int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb)
| {
| const u64 seq = DCCP_SKB_CB(skb)->dccpd_seq;
| int i;
|
| if (dccp_delta_seqno(tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno, seq) <= 0)
| return 1;
|
| for (i = 1; i <= h->loss_count; i++)
| if (tfrc_rx_hist_entry(h, i)->tfrchrx_seqno == seq)
| return 1;
|
| return 0;
| }
|
| With the current code this will always check just one entry, as
| loss_count only gets to 1 in tfrc_rx_hist_loss_indicated.
|
Again the resolution is in the next patch:
* when loss_count = 0 (no loss so far), loss_indicated() is called, sets loss_count = 2
* when loss_count = 1, __one_after_loss() is called, which checks if this a genuine loss
--> it then has the line
h->loss_count = 2; /* second packet lost */
* when loss_count = 2, __two_after_loss() is called,
- this function returns 1 when the current packet indicates a genuine loss
- in that case loss_count is set to 3
* when loss_count = 3, __three_after_loss() is called, and the whole structure is recycled.
^ permalink raw reply
* Re: [PATCH] correct typo in __xfrm4_bundle_create()
From: David Miller @ 2007-12-05 14:53 UTC (permalink / raw)
To: ianbrn; +Cc: netdev
In-Reply-To: <d0383f90712050633q5dadf8dbxa357a7d50f54528d@mail.gmail.com>
From: "Ian Brown" <ianbrn@gmail.com>
Date: Wed, 5 Dec 2007 16:33:56 +0200
> Hello,
> Sorry, but I had tried several times from 3 machines (without
> iptables/SELinux) and git-clone
> gives "Connection refused" error.
>
> git-clone git://kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25.git 2.6.25
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25.git
I just publish my URL's in the:
kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git
canonical form so that they are easy to edit into:
master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git
for SSH users and into:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25.git
for non-SSH users.
^ permalink raw reply
* Re: TCP event tracking via netlink...
From: Evgeniy Polyakov @ 2007-12-05 14:48 UTC (permalink / raw)
To: John Heffner; +Cc: David Miller, ilpo.jarvinen, netdev
In-Reply-To: <4756B175.5010108@psc.edu>
Hi.
On Wed, Dec 05, 2007 at 09:11:01AM -0500, John Heffner (jheffner@psc.edu) wrote:
> >Maybe if we want to get really fancy we can have some more-expensive
> >debug mode where detailed specific events get generated via some
> >macros we can scatter all over the place. This won't be useful
> >for general user problem analysis, but it will be excellent for
> >developers.
> >
> >Let me know if you think this is useful enough and I'll work on
> >an implementation we can start playing with.
>
>
> FWIW, sounds similar to what these guys are doing with SIFTR for FreeBSD:
> http://caia.swin.edu.au/urp/newtcp/tools.html
> http://caia.swin.edu.au/reports/070824A/CAIA-TR-070824A.pdf
And even more similar to this patch from Samir Bellabes of Mandriva:
http://lwn.net/Articles/202255/
--
Evgeniy Polyakov
^ permalink raw reply
* Re: [PATCH] correct typo in __xfrm4_bundle_create()
From: Ian Brown @ 2007-12-05 14:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20071205.060316.74563693.davem@davemloft.net>
Hello,
Sorry, but I had tried several times from 3 machines (without
iptables/SELinux) and git-clone
gives "Connection refused" error.
git-clone git://kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25.git 2.6.25
Initialized empty Git repository in /work/src/2.6.25/.git/
fatal: unable to connect a socket (Connection refused)
fetch-pack from
'git://kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25.git'
failed.
Ian
On Dec 5, 2007 4:03 PM, David Miller <davem@davemloft.net> wrote:
> From: "Ian Brown" <ianbrn@gmail.com>
> Date: Wed, 5 Dec 2007 15:59:52 +0200
>
> > Hello,
> > Sorry ; but is this tree can be fetched ? it requires a password.
> >
> > I try:
> > git-clone kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.25.git net-2.6.25
> > and get:
> > root@kernel.org's password:
>
> Use the git:// URL prefix.
>
^ permalink raw reply
* Re: [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Arnaldo Carvalho de Melo @ 2007-12-05 14:23 UTC (permalink / raw)
To: Gerrit Renker, Arnaldo Carvalho de Melo, dccp, netdev
In-Reply-To: <20071205135511.GD893@gerrit.erg.abdn.ac.uk>
Em Wed, Dec 05, 2007 at 01:55:11PM +0000, Gerrit Renker escreveu:
> | > @@ -788,8 +782,8 @@ static void ccid3_hc_rx_packet_recv(stru
> | > if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
> | > if (is_data_packet) {
> | > do_feedback = FBACK_INITIAL;
> | > + hcrx->ccid3hcrx_s = payload_size;
> | > ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
> | > - ccid3_hc_rx_update_s(hcrx, payload_size);
> |
> | We have to set ccid3hcrx_bytes_recv to the payload_size here too, I'm
> | fixing this on the reworked patch that introduces the RX history.
> |
> I almost did the same error again by wanting to agree too prematurely.
>
> But updating ccid3hcrx_bytes_recv is in fact not needed here and if it
> would be done it would not have a useable effect. The reason is that the
> first data packet will trigger the initial feedback; and in the initial
> feedback packet X_recv (which is ccid3hcrx_bytes_recv / the_time_spent)
> is set to 0 (RFC 3448, 6.3).
>
> For this reason, updating bytes_recv for the first data packet is also not
> in the flowchart on
> http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/ccid3_packet_reception/
OK, I will add a comment on the code stating why it is not needed so
that new people don't commit the same mistake again.
- Arnaldo
^ permalink raw reply
* Re: [patch resend build-breakage] make bnx2x select ZLIB_INFLATE
From: David Miller @ 2007-12-05 14:16 UTC (permalink / raw)
To: eliezert; +Cc: netdev, jeff, Lee.Schermerhorn
In-Reply-To: <1196863959.5204.25.camel@lb-tlvb-eliezer.il.broadcom.com>
From: "Eliezer Tamir" <eliezert@broadcom.com>
Date: Wed, 05 Dec 2007 16:12:39 +0200
> The bnx2x module depends on the zlib_inflate functions. The
> build will fail if ZLIB_INFLATE has not been selected manually
> or by building another module that automatically selects it.
>
> Modify BNX2X config option to 'select ZLIB_INFLATE' like BNX2
> and others. This seems to fix it.
>
> Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
> Acked-by: Eliezer Tamir <eliezert@broadcom.com>
Looks better, Jeff please suck this in.
^ permalink raw reply
* Re: [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Arnaldo Carvalho de Melo @ 2007-12-05 14:13 UTC (permalink / raw)
To: Gerrit Renker; +Cc: dccp, netdev
In-Reply-To: <11968535864083-git-send-email-gerrit@erg.abdn.ac.uk>
Em Wed, Dec 05, 2007 at 11:19:44AM +0000, Gerrit Renker escreveu:
> This revision fixes a bug present in the per-socket allocation of RX history
> entries; identification of this bug is thanks to Arnaldo Carvalho de Melo.
>
> The bug was in not deallocating history entries when the allocation of
> one array element failed. The solution in this revised patch set is the
> original one written by Arnaldo.
Ok, this one I posted with some other comments and explanations about
changes other than namespacing, renaming of some functions and removal
of functions not used in this patch.
- Arnaldo
^ permalink raw reply
* [patch resend build-breakage] make bnx2x select ZLIB_INFLATE
From: Eliezer Tamir @ 2007-12-05 14:12 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net
Cc: jeff@garzik.org, Lee Schermerhorn
The bnx2x module depends on the zlib_inflate functions. The
build will fail if ZLIB_INFLATE has not been selected manually
or by building another module that automatically selects it.
Modify BNX2X config option to 'select ZLIB_INFLATE' like BNX2
and others. This seems to fix it.
Signed-off-by: Lee Schermerhorn <lee.schermerhorn@hp.com>
Acked-by: Eliezer Tamir <eliezert@broadcom.com>
---
drivers/net/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5bafb30..b9d7f5b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2594,6 +2594,7 @@ config TEHUTI
config BNX2X
tristate "Broadcom NetXtremeII 10Gb support"
depends on PCI
+ select ZLIB_INFLATE
help
This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
--
1.5.3.2
^ permalink raw reply related
* Re: [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Arnaldo Carvalho de Melo @ 2007-12-05 14:11 UTC (permalink / raw)
To: Gerrit Renker; +Cc: dccp, netdev
In-Reply-To: <11968535861091-git-send-email-gerrit@erg.abdn.ac.uk>
Em Wed, Dec 05, 2007 at 11:19:45AM +0000, Gerrit Renker escreveu:
> This fixes a problem in the initial revision of the patch: The loss interval
> history was not de-allocated when the initialisation of the packet history
> failed. The identification of this problem is also thanks due to Arnaldo.
>
> The interdiff to the previous revision is:
>
> --- b/net/dccp/ccids/lib/tfrc_module.c
> +++ b/net/dccp/ccids/lib/tfrc_module.c
> @@ -26,7 +26,12 @@
>
> if (rc == 0)
> rc = packet_history_init();
> + if (rc == 0)
> + goto out;
>
> +out_free_loss_intervals:
> + dccp_li_exit();
> +out:
> return rc;
> }
>
Ok, this one is kept on the series I have pending submission.
- Arnaldo
^ permalink raw reply
* Re: TCP event tracking via netlink...
From: John Heffner @ 2007-12-05 14:11 UTC (permalink / raw)
To: David Miller; +Cc: ilpo.jarvinen, netdev
In-Reply-To: <20071205.053031.87154402.davem@davemloft.net>
David Miller wrote:
> Ilpo, I was pondering the kind of debugging one does to find
> congestion control issues and even SACK bugs and it's currently too
> painful because there is no standard way to track state changes.
>
> I assume you're using something like carefully crafted printk's,
> kprobes, or even ad-hoc statistic counters. That's what I used to do
> :-)
>
> With that in mind it occurred to me that we might want to do something
> like a state change event generator.
>
> Basically some application or even a daemon listens on this generic
> netlink socket family we create. The header of each event packet
> indicates what socket the event is for and then there is some state
> information.
>
> Then you can look at a tcpdump and this state dump side by side and
> see what the kernel decided to do.
>
> Now there is the question of granularity.
>
> A very important consideration in this is that we want this thing to
> be enabled in the distributions, therefore it must be cheap. Perhaps
> one test at the end of the packet input processing.
>
> So I say we pick some state to track (perhaps start with tcp_info)
> and just push that at the end of every packet input run. Also,
> we add some minimal filtering capability (match on specific IP
> address and/or port, for example).
>
> Maybe if we want to get really fancy we can have some more-expensive
> debug mode where detailed specific events get generated via some
> macros we can scatter all over the place. This won't be useful
> for general user problem analysis, but it will be excellent for
> developers.
>
> Let me know if you think this is useful enough and I'll work on
> an implementation we can start playing with.
FWIW, sounds similar to what these guys are doing with SIFTR for FreeBSD:
http://caia.swin.edu.au/urp/newtcp/tools.html
http://caia.swin.edu.au/reports/070824A/CAIA-TR-070824A.pdf
-John
^ permalink raw reply
* Re: [PATCH v2 0/3][BUG-FIX]: Test tree updates and bug fixes
From: Arnaldo Carvalho de Melo @ 2007-12-05 14:10 UTC (permalink / raw)
To: Gerrit Renker; +Cc: dccp, netdev
In-Reply-To: <11968535861367-git-send-email-gerrit@erg.abdn.ac.uk>
Em Wed, Dec 05, 2007 at 11:19:46AM +0000, Gerrit Renker escreveu:
> This patch removes the following redundancies:
> * ccid3_hc_rx_update_s() is only called for data packets (that is what it should be called for);
> * each call to ccid3_hc_rx_update_s() is wrapped inside a "if (is_data_packet)" test';
> * therefore testing each time if "len > 0" is redundant (pointed out by Arnaldo);
> * no other code calls this function, hence the inline function can go.
>
> Also replaced the first call to updating s with direct assignment of `payload_size'; this has also
> been pointed out by Arnaldo.
Thanks, I folded this into the reorganized RX history handling patch,
together with reverting ccid3_hc_rx_packet_recv to very close to your
original patch, with this changes:
1. no need to calculate the payload size for non data packets as this
value won't be used.
2. Initialize hcrx->ccid3hcrx_bytes_recv with the payload size when
hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA.
3. tfrc_rx_hist_duplicate() is only called when ccid3hcrx_state !=
TFRC_RSTATE_NO_DATA, so it doesn't need to goto the done_receiving
label (that was removed as this was its only use) as do_feedback
would always be CCID3_FBACK_NONE and so the test would always fail
and no feedback would be sent, so just return right there.
Now it reads:
static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE;
const u32 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
const bool is_data_packet = dccp_data_packet(skb);
if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
if (is_data_packet) {
const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
do_feedback = FBACK_INITIAL;
ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
hcrx->ccid3hcrx_s =
hcrx->ccid3hcrx_bytes_recv = payload_size;
}
goto update_records;
}
if (tfrc_rx_hist_duplicate(&hcrx->ccid3hcrx_hist, skb))
return; /* done receiving */
if (is_data_packet) {
const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
/*
* Update moving-average of s and the sum of received payload bytes
*/
hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, payload_size, 9);
hcrx->ccid3hcrx_bytes_recv += payload_size;
}
/*
* Handle pending losses and otherwise check for new loss
*/
if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
goto update_records;
/*
* Handle data packets: RTT sampling and monitoring p
*/
if (unlikely(!is_data_packet))
goto update_records;
if (list_empty(&hcrx->ccid3hcrx_li_hist)) { /* no loss so far: p = 0 */
const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
if (sample != 0)
hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);
}
/*
* Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3
*/
if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->ccid3hcrx_last_counter) > 3)
do_feedback = CCID3_FBACK_PERIODIC;
update_records:
tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);
if (do_feedback)
ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
}
Now to some questions and please bear with me as I haven't got to the
patches after this:
tfrc_rx_hist->loss_count as of now is a boolean, my understanding is
that you are counting loss events, i.e. it doesn't matter in:
/* any data packets missing between last reception and skb ? */
int tfrc_rx_hist_new_loss_indicated(struct tfrc_rx_hist *h,
const struct sk_buff *skb, u32 ndp)
{
int delta = dccp_delta_seqno(tfrc_rx_hist_last_rcv(h)->tfrchrx_seqno,
DCCP_SKB_CB(skb)->dccpd_seq);
if (delta > 1 && ndp < delta)
tfrc_rx_hist_loss_indicated(h);
return tfrc_rx_hist_loss_pending(h);
}
if (delta - ndp) is > 1, i.e. tfrc_rx_hist->loss_count only indicates
that there was loss. But then in other parts of the code it assumes it
can be more than 1:
/**
* tfrc_rx_hist - RX history structure for TFRC-based protocols
*
* @ring: Packet history for RTT sampling and loss detection
* @loss_count: Number of entries in circular history
* @loss_start: Movable index (for loss detection)
* @rtt_sample_prev: Used during RTT sampling, points to candidate entry
*/
struct tfrc_rx_hist {
struct tfrc_rx_hist_entry *ring[TFRC_NDUPACK + 1];
u8 loss_count:2,
loss_start:2;
#define rtt_sample_prev loss_start
};
There is space for TFRC_NDUPACK + 1 possible values in loss_count (:2)
and the comment says it is the number of entries in the circular
history, and also:
/* has the packet contained in skb been seen before? */
int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb)
{
const u64 seq = DCCP_SKB_CB(skb)->dccpd_seq;
int i;
if (dccp_delta_seqno(tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno, seq) <= 0)
return 1;
for (i = 1; i <= h->loss_count; i++)
if (tfrc_rx_hist_entry(h, i)->tfrchrx_seqno == seq)
return 1;
return 0;
}
With the current code this will always check just one entry, as
loss_count only gets to 1 in tfrc_rx_hist_loss_indicated.
I'm not implying there is an error, I need to read the patches that
follow, I'm just trying to get over coding conventions and basic
algorithm sanity tests.
I'll look at your page looking for extra explanations about this.
- Arnaldo
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox