* [PATCH net-next 2/4] cxgb4: Add support for cim_la entry in debugfs
From: Hariprasad Shenai @ 2015-01-07 3:18 UTC (permalink / raw)
To: netdev; +Cc: davem, leedom, nirranjan, anish, Hariprasad Shenai
In-Reply-To: <1420600683-23289-1-git-send-email-hariprasad@chelsio.com>
The CIM LA captures the embedded processorâs internal state. Optionally, it can
also trace the flow of data in and out of the embedded processor. Therefore, the
CIM LA output contains detailed information of what code the embedded processor
executed prior to the CIM LA capture.
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 7 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 129 +++++++++++++++++++-
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h | 12 ++
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 120 ++++++++++++++++++
drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 4 +
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 34 +++++
6 files changed, 304 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 73b1f3a..46cd506 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -304,6 +304,8 @@ struct adapter_params {
struct devlog_params devlog;
enum pcie_memwin drv_memwin;
+ unsigned int cim_la_size;
+
unsigned int sf_size; /* serial flash size in bytes */
unsigned int sf_nsec; /* # of flash sectors */
unsigned int sf_fw_start; /* start of FW image in flash */
@@ -1034,6 +1036,11 @@ int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
u64 *parity);
int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data,
u64 *parity);
+int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
+ unsigned int *valp);
+int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n,
+ const unsigned int *valp);
+int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr);
const char *t4_get_port_type_description(enum fw_port_type port_type);
void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 1d3d1c5..0f7b23f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -43,8 +43,132 @@
#include "cxgb4_debugfs.h"
#include "l2t.h"
-/* Firmware Device Log dump.
- */
+/* generic seq_file support for showing a table of size rows x width. */
+static void *seq_tab_get_idx(struct seq_tab *tb, loff_t pos)
+{
+ pos -= tb->skip_first;
+ return pos >= tb->rows ? NULL : &tb->data[pos * tb->width];
+}
+
+static void *seq_tab_start(struct seq_file *seq, loff_t *pos)
+{
+ struct seq_tab *tb = seq->private;
+
+ if (tb->skip_first && *pos == 0)
+ return SEQ_START_TOKEN;
+
+ return seq_tab_get_idx(tb, *pos);
+}
+
+static void *seq_tab_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ v = seq_tab_get_idx(seq->private, *pos + 1);
+ if (v)
+ ++*pos;
+ return v;
+}
+
+static void seq_tab_stop(struct seq_file *seq, void *v)
+{
+}
+
+static int seq_tab_show(struct seq_file *seq, void *v)
+{
+ const struct seq_tab *tb = seq->private;
+
+ return tb->show(seq, v, ((char *)v - tb->data) / tb->width);
+}
+
+static const struct seq_operations seq_tab_ops = {
+ .start = seq_tab_start,
+ .next = seq_tab_next,
+ .stop = seq_tab_stop,
+ .show = seq_tab_show
+};
+
+struct seq_tab *seq_open_tab(struct file *f, unsigned int rows,
+ unsigned int width, unsigned int have_header,
+ int (*show)(struct seq_file *seq, void *v, int i))
+{
+ struct seq_tab *p;
+
+ p = __seq_open_private(f, &seq_tab_ops, sizeof(*p) + rows * width);
+ if (p) {
+ p->show = show;
+ p->rows = rows;
+ p->width = width;
+ p->skip_first = have_header != 0;
+ }
+ return p;
+}
+
+static int cim_la_show(struct seq_file *seq, void *v, int idx)
+{
+ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "Status Data PC LS0Stat LS0Addr "
+ " LS0Data\n");
+ else {
+ const u32 *p = v;
+
+ seq_printf(seq,
+ " %02x %x%07x %x%07x %08x %08x %08x%08x%08x%08x\n",
+ (p[0] >> 4) & 0xff, p[0] & 0xf, p[1] >> 4,
+ p[1] & 0xf, p[2] >> 4, p[2] & 0xf, p[3], p[4], p[5],
+ p[6], p[7]);
+ }
+ return 0;
+}
+
+static int cim_la_show_3in1(struct seq_file *seq, void *v, int idx)
+{
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, "Status Data PC\n");
+ } else {
+ const u32 *p = v;
+
+ seq_printf(seq, " %02x %08x %08x\n", p[5] & 0xff, p[6],
+ p[7]);
+ seq_printf(seq, " %02x %02x%06x %02x%06x\n",
+ (p[3] >> 8) & 0xff, p[3] & 0xff, p[4] >> 8,
+ p[4] & 0xff, p[5] >> 8);
+ seq_printf(seq, " %02x %x%07x %x%07x\n", (p[0] >> 4) & 0xff,
+ p[0] & 0xf, p[1] >> 4, p[1] & 0xf, p[2] >> 4);
+ }
+ return 0;
+}
+
+static int cim_la_open(struct inode *inode, struct file *file)
+{
+ int ret;
+ unsigned int cfg;
+ struct seq_tab *p;
+ struct adapter *adap = inode->i_private;
+
+ ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
+ if (ret)
+ return ret;
+
+ p = seq_open_tab(file, adap->params.cim_la_size / 8, 8 * sizeof(u32), 1,
+ cfg & UPDBGLACAPTPCONLY_F ?
+ cim_la_show_3in1 : cim_la_show);
+ if (!p)
+ return -ENOMEM;
+
+ ret = t4_cim_read_la(adap, (u32 *)p->data, NULL);
+ if (ret)
+ seq_release_private(inode, file);
+ return ret;
+}
+
+static const struct file_operations cim_la_fops = {
+ .owner = THIS_MODULE,
+ .open = cim_la_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private
+};
+
+/* Firmware Device Log dump. */
static const char * const devlog_level_strings[] = {
[FW_DEVLOG_LEVEL_EMERG] = "EMERG",
[FW_DEVLOG_LEVEL_CRIT] = "CRIT",
@@ -318,6 +442,7 @@ int t4_setup_debugfs(struct adapter *adap)
u32 size;
static struct t4_debugfs_entry t4_debugfs_files[] = {
+ { "cim_la", &cim_la_fops, S_IRUSR, 0 },
{ "devlog", &devlog_fops, S_IRUSR, 0 },
{ "l2t", &t4_l2t_fops, S_IRUSR, 0},
};
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
index a3d8867..70fcbc9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
@@ -44,6 +44,18 @@ struct t4_debugfs_entry {
unsigned char data;
};
+struct seq_tab {
+ int (*show)(struct seq_file *seq, void *v, int idx);
+ unsigned int rows; /* # of entries */
+ unsigned char width; /* size in bytes of each entry */
+ unsigned char skip_first; /* whether the first line is a header */
+ char data[0]; /* the table data */
+};
+
+struct seq_tab *seq_open_tab(struct file *f, unsigned int rows,
+ unsigned int width, unsigned int have_header,
+ int (*show)(struct seq_file *seq, void *v, int i));
+
int t4_setup_debugfs(struct adapter *adap);
void add_debugfs_files(struct adapter *adap,
struct t4_debugfs_entry *files,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 3776279..1e30554 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -4031,6 +4031,7 @@ int t4_prep_adapter(struct adapter *adapter)
return -EINVAL;
}
+ adapter->params.cim_la_size = CIMLA_SIZE;
init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
/*
@@ -4323,3 +4324,122 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
}
return 0;
}
+
+/**
+ * t4_cim_read - read a block from CIM internal address space
+ * @adap: the adapter
+ * @addr: the start address within the CIM address space
+ * @n: number of words to read
+ * @valp: where to store the result
+ *
+ * Reads a block of 4-byte words from the CIM intenal address space.
+ */
+int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
+ unsigned int *valp)
+{
+ int ret = 0;
+
+ if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
+ return -EBUSY;
+
+ for ( ; !ret && n--; addr += 4) {
+ t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr);
+ ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
+ 0, 5, 2);
+ if (!ret)
+ *valp++ = t4_read_reg(adap, CIM_HOST_ACC_DATA_A);
+ }
+ return ret;
+}
+
+/**
+ * t4_cim_write - write a block into CIM internal address space
+ * @adap: the adapter
+ * @addr: the start address within the CIM address space
+ * @n: number of words to write
+ * @valp: set of values to write
+ *
+ * Writes a block of 4-byte words into the CIM intenal address space.
+ */
+int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n,
+ const unsigned int *valp)
+{
+ int ret = 0;
+
+ if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
+ return -EBUSY;
+
+ for ( ; !ret && n--; addr += 4) {
+ t4_write_reg(adap, CIM_HOST_ACC_DATA_A, *valp++);
+ t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr | HOSTWRITE_F);
+ ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
+ 0, 5, 2);
+ }
+ return ret;
+}
+
+static int t4_cim_write1(struct adapter *adap, unsigned int addr,
+ unsigned int val)
+{
+ return t4_cim_write(adap, addr, 1, &val);
+}
+
+/**
+ * t4_cim_read_la - read CIM LA capture buffer
+ * @adap: the adapter
+ * @la_buf: where to store the LA data
+ * @wrptr: the HW write pointer within the capture buffer
+ *
+ * Reads the contents of the CIM LA buffer with the most recent entry at
+ * the end of the returned data and with the entry at @wrptr first.
+ * We try to leave the LA in the running state we find it in.
+ */
+int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
+{
+ int i, ret;
+ unsigned int cfg, val, idx;
+
+ ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
+ if (ret)
+ return ret;
+
+ if (cfg & UPDBGLAEN_F) { /* LA is running, freeze it */
+ ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A, 0);
+ if (ret)
+ return ret;
+ }
+
+ ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
+ if (ret)
+ goto restart;
+
+ idx = UPDBGLAWRPTR_G(val);
+ if (wrptr)
+ *wrptr = idx;
+
+ for (i = 0; i < adap->params.cim_la_size; i++) {
+ ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
+ UPDBGLARDPTR_V(idx) | UPDBGLARDEN_F);
+ if (ret)
+ break;
+ ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
+ if (ret)
+ break;
+ if (val & UPDBGLARDEN_F) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+ ret = t4_cim_read(adap, UP_UP_DBG_LA_DATA_A, 1, &la_buf[i]);
+ if (ret)
+ break;
+ idx = (idx + 1) & UPDBGLARDPTR_M;
+ }
+restart:
+ if (cfg & UPDBGLAEN_F) {
+ int r = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
+ cfg & ~UPDBGLARDEN_F);
+ if (!ret)
+ ret = r;
+ }
+ return ret;
+}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
index 5e5eee6..bcc925b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
@@ -56,6 +56,10 @@ enum {
};
enum {
+ CIMLA_SIZE = 2048, /* # of 32-bit words in CIM LA */
+};
+
+enum {
SF_PAGE_SIZE = 256, /* serial flash page size */
SF_SEC_SIZE = 64 * 1024, /* serial flash sector size */
};
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 4077227..3fe6eeb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -2062,4 +2062,38 @@
#define PL_VF_WHOAMI_A 0x0
#define PL_VF_REVISION_A 0x8
+/* registers for module CIM */
+#define CIM_HOST_ACC_CTRL_A 0x7b50
+#define CIM_HOST_ACC_DATA_A 0x7b54
+#define UP_UP_DBG_LA_CFG_A 0x140
+#define UP_UP_DBG_LA_DATA_A 0x144
+
+#define HOSTBUSY_S 17
+#define HOSTBUSY_V(x) ((x) << HOSTBUSY_S)
+#define HOSTBUSY_F HOSTBUSY_V(1U)
+
+#define HOSTWRITE_S 16
+#define HOSTWRITE_V(x) ((x) << HOSTWRITE_S)
+#define HOSTWRITE_F HOSTWRITE_V(1U)
+
+#define UPDBGLARDEN_S 1
+#define UPDBGLARDEN_V(x) ((x) << UPDBGLARDEN_S)
+#define UPDBGLARDEN_F UPDBGLARDEN_V(1U)
+
+#define UPDBGLAEN_S 0
+#define UPDBGLAEN_V(x) ((x) << UPDBGLAEN_S)
+#define UPDBGLAEN_F UPDBGLAEN_V(1U)
+
+#define UPDBGLARDPTR_S 2
+#define UPDBGLARDPTR_M 0xfffU
+#define UPDBGLARDPTR_V(x) ((x) << UPDBGLARDPTR_S)
+
+#define UPDBGLAWRPTR_S 16
+#define UPDBGLAWRPTR_M 0xfffU
+#define UPDBGLAWRPTR_G(x) (((x) >> UPDBGLAWRPTR_S) & UPDBGLAWRPTR_M)
+
+#define UPDBGLACAPTPCONLY_S 30
+#define UPDBGLACAPTPCONLY_V(x) ((x) << UPDBGLACAPTPCONLY_S)
+#define UPDBGLACAPTPCONLY_F UPDBGLACAPTPCONLY_V(1U)
+
#endif /* __T4_REGS_H */
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 3/4] cxgb4: Add support for cim_qcfg entry in debugfs
From: Hariprasad Shenai @ 2015-01-07 3:18 UTC (permalink / raw)
To: netdev; +Cc: davem, leedom, nirranjan, anish, Hariprasad Shenai
In-Reply-To: <1420600683-23289-1-git-send-email-hariprasad@chelsio.com>
Adds debug log to get cim queue config
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 70 ++++++++++++++++++++
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 35 ++++++++++
drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 3 +
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 55 +++++++++++++++
5 files changed, 164 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 46cd506..7c785b5 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1041,6 +1041,7 @@ int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n,
const unsigned int *valp);
int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr);
+void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres);
const char *t4_get_port_type_description(enum fw_port_type port_type);
void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p);
void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 0f7b23f..a8b0223 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -168,6 +168,75 @@ static const struct file_operations cim_la_fops = {
.release = seq_release_private
};
+static int cim_qcfg_show(struct seq_file *seq, void *v)
+{
+ static const char * const qname[] = {
+ "TP0", "TP1", "ULP", "SGE0", "SGE1", "NC-SI",
+ "ULP0", "ULP1", "ULP2", "ULP3", "SGE", "NC-SI",
+ "SGE0-RX", "SGE1-RX"
+ };
+
+ int i;
+ struct adapter *adap = seq->private;
+ u16 base[CIM_NUM_IBQ + CIM_NUM_OBQ_T5];
+ u16 size[CIM_NUM_IBQ + CIM_NUM_OBQ_T5];
+ u32 stat[(4 * (CIM_NUM_IBQ + CIM_NUM_OBQ_T5))];
+ u16 thres[CIM_NUM_IBQ];
+ u32 obq_wr_t4[2 * CIM_NUM_OBQ], *wr;
+ u32 obq_wr_t5[2 * CIM_NUM_OBQ_T5];
+ u32 *p = stat;
+ int cim_num_obq = is_t4(adap->params.chip) ?
+ CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
+
+ i = t4_cim_read(adap, is_t4(adap->params.chip) ? UP_IBQ_0_RDADDR_A :
+ UP_IBQ_0_SHADOW_RDADDR_A,
+ ARRAY_SIZE(stat), stat);
+ if (!i) {
+ if (is_t4(adap->params.chip)) {
+ i = t4_cim_read(adap, UP_OBQ_0_REALADDR_A,
+ ARRAY_SIZE(obq_wr_t4), obq_wr_t4);
+ wr = obq_wr_t4;
+ } else {
+ i = t4_cim_read(adap, UP_OBQ_0_SHADOW_REALADDR_A,
+ ARRAY_SIZE(obq_wr_t5), obq_wr_t5);
+ wr = obq_wr_t5;
+ }
+ }
+ if (i)
+ return i;
+
+ t4_read_cimq_cfg(adap, base, size, thres);
+
+ seq_printf(seq,
+ " Queue Base Size Thres RdPtr WrPtr SOP EOP Avail\n");
+ for (i = 0; i < CIM_NUM_IBQ; i++, p += 4)
+ seq_printf(seq, "%7s %5x %5u %5u %6x %4x %4u %4u %5u\n",
+ qname[i], base[i], size[i], thres[i],
+ IBQRDADDR_G(p[0]), IBQWRADDR_G(p[1]),
+ QUESOPCNT_G(p[3]), QUEEOPCNT_G(p[3]),
+ QUEREMFLITS_G(p[2]) * 16);
+ for ( ; i < CIM_NUM_IBQ + cim_num_obq; i++, p += 4, wr += 2)
+ seq_printf(seq, "%7s %5x %5u %12x %4x %4u %4u %5u\n",
+ qname[i], base[i], size[i],
+ QUERDADDR_G(p[0]) & 0x3fff, wr[0] - base[i],
+ QUESOPCNT_G(p[3]), QUEEOPCNT_G(p[3]),
+ QUEREMFLITS_G(p[2]) * 16);
+ return 0;
+}
+
+static int cim_qcfg_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cim_qcfg_show, inode->i_private);
+}
+
+static const struct file_operations cim_qcfg_fops = {
+ .owner = THIS_MODULE,
+ .open = cim_qcfg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* Firmware Device Log dump. */
static const char * const devlog_level_strings[] = {
[FW_DEVLOG_LEVEL_EMERG] = "EMERG",
@@ -443,6 +512,7 @@ int t4_setup_debugfs(struct adapter *adap)
static struct t4_debugfs_entry t4_debugfs_files[] = {
{ "cim_la", &cim_la_fops, S_IRUSR, 0 },
+ { "cim_qcfg", &cim_qcfg_fops, S_IRUSR, 0 },
{ "devlog", &devlog_fops, S_IRUSR, 0 },
{ "l2t", &t4_l2t_fops, S_IRUSR, 0},
};
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 1e30554..734d33e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -4326,6 +4326,41 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
}
/**
+ * t4_read_cimq_cfg - read CIM queue configuration
+ * @adap: the adapter
+ * @base: holds the queue base addresses in bytes
+ * @size: holds the queue sizes in bytes
+ * @thres: holds the queue full thresholds in bytes
+ *
+ * Returns the current configuration of the CIM queues, starting with
+ * the IBQs, then the OBQs.
+ */
+void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres)
+{
+ unsigned int i, v;
+ int cim_num_obq = is_t4(adap->params.chip) ?
+ CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
+
+ for (i = 0; i < CIM_NUM_IBQ; i++) {
+ t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, IBQSELECT_F |
+ QUENUMSELECT_V(i));
+ v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
+ /* value is in 256-byte units */
+ *base++ = CIMQBASE_G(v) * 256;
+ *size++ = CIMQSIZE_G(v) * 256;
+ *thres++ = QUEFULLTHRSH_G(v) * 8; /* 8-byte unit */
+ }
+ for (i = 0; i < cim_num_obq; i++) {
+ t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
+ QUENUMSELECT_V(i));
+ v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
+ /* value is in 256-byte units */
+ *base++ = CIMQBASE_G(v) * 256;
+ *size++ = CIMQSIZE_G(v) * 256;
+ }
+}
+
+/**
* t4_cim_read - read a block from CIM internal address space
* @adap: the adapter
* @addr: the start address within the CIM address space
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
index bcc925b..f6b82da 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
@@ -56,6 +56,9 @@ enum {
};
enum {
+ CIM_NUM_IBQ = 6, /* # of CIM IBQs */
+ CIM_NUM_OBQ = 6, /* # of CIM OBQs */
+ CIM_NUM_OBQ_T5 = 8, /* # of CIM OBQs for T5 adapter */
CIMLA_SIZE = 2048, /* # of 32-bit words in CIM LA */
};
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 3fe6eeb..a2cae0e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -2096,4 +2096,59 @@
#define UPDBGLACAPTPCONLY_V(x) ((x) << UPDBGLACAPTPCONLY_S)
#define UPDBGLACAPTPCONLY_F UPDBGLACAPTPCONLY_V(1U)
+#define CIM_QUEUE_CONFIG_REF_A 0x7b48
+#define CIM_QUEUE_CONFIG_CTRL_A 0x7b4c
+
+#define CIMQSIZE_S 24
+#define CIMQSIZE_M 0x3fU
+#define CIMQSIZE_G(x) (((x) >> CIMQSIZE_S) & CIMQSIZE_M)
+
+#define CIMQBASE_S 16
+#define CIMQBASE_M 0x3fU
+#define CIMQBASE_G(x) (((x) >> CIMQBASE_S) & CIMQBASE_M)
+
+#define QUEFULLTHRSH_S 0
+#define QUEFULLTHRSH_M 0x1ffU
+#define QUEFULLTHRSH_G(x) (((x) >> QUEFULLTHRSH_S) & QUEFULLTHRSH_M)
+
+#define UP_IBQ_0_RDADDR_A 0x10
+#define UP_IBQ_0_SHADOW_RDADDR_A 0x280
+#define UP_OBQ_0_REALADDR_A 0x104
+#define UP_OBQ_0_SHADOW_REALADDR_A 0x394
+
+#define IBQRDADDR_S 0
+#define IBQRDADDR_M 0x1fffU
+#define IBQRDADDR_G(x) (((x) >> IBQRDADDR_S) & IBQRDADDR_M)
+
+#define IBQWRADDR_S 0
+#define IBQWRADDR_M 0x1fffU
+#define IBQWRADDR_G(x) (((x) >> IBQWRADDR_S) & IBQWRADDR_M)
+
+#define QUERDADDR_S 0
+#define QUERDADDR_M 0x7fffU
+#define QUERDADDR_G(x) (((x) >> QUERDADDR_S) & QUERDADDR_M)
+
+#define QUEREMFLITS_S 0
+#define QUEREMFLITS_M 0x7ffU
+#define QUEREMFLITS_G(x) (((x) >> QUEREMFLITS_S) & QUEREMFLITS_M)
+
+#define QUEEOPCNT_S 16
+#define QUEEOPCNT_M 0xfffU
+#define QUEEOPCNT_G(x) (((x) >> QUEEOPCNT_S) & QUEEOPCNT_M)
+
+#define QUESOPCNT_S 0
+#define QUESOPCNT_M 0xfffU
+#define QUESOPCNT_G(x) (((x) >> QUESOPCNT_S) & QUESOPCNT_M)
+
+#define OBQSELECT_S 4
+#define OBQSELECT_V(x) ((x) << OBQSELECT_S)
+#define OBQSELECT_F OBQSELECT_V(1U)
+
+#define IBQSELECT_S 3
+#define IBQSELECT_V(x) ((x) << IBQSELECT_S)
+#define IBQSELECT_F IBQSELECT_V(1U)
+
+#define QUENUMSELECT_S 0
+#define QUENUMSELECT_V(x) ((x) << QUENUMSELECT_S)
+
#endif /* __T4_REGS_H */
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 4/4] cxgb4: Add support for mps_tcam debugfs
From: Hariprasad Shenai @ 2015-01-07 3:18 UTC (permalink / raw)
To: netdev; +Cc: davem, leedom, nirranjan, anish, Hariprasad Shenai
In-Reply-To: <1420600683-23289-1-git-send-email-hariprasad@chelsio.com>
Debug log to get the MPS TCAM table
Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 131 ++++++++++++++++++++
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 60 +++++++++
2 files changed, 191 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index a8b0223..e9f3489 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -433,6 +433,136 @@ static const struct file_operations devlog_fops = {
.release = seq_release_private
};
+static inline void tcamxy2valmask(u64 x, u64 y, u8 *addr, u64 *mask)
+{
+ *mask = x | y;
+ y = (__force u64)cpu_to_be64(y);
+ memcpy(addr, (char *)&y + 2, ETH_ALEN);
+}
+
+static int mps_tcam_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN)
+ seq_puts(seq, "Idx Ethernet address Mask Vld Ports PF"
+ " VF Replication "
+ "P0 P1 P2 P3 ML\n");
+ else {
+ u64 mask;
+ u8 addr[ETH_ALEN];
+ struct adapter *adap = seq->private;
+ unsigned int idx = (uintptr_t)v - 2;
+ u64 tcamy = t4_read_reg64(adap, MPS_CLS_TCAM_Y_L(idx));
+ u64 tcamx = t4_read_reg64(adap, MPS_CLS_TCAM_X_L(idx));
+ u32 cls_lo = t4_read_reg(adap, MPS_CLS_SRAM_L(idx));
+ u32 cls_hi = t4_read_reg(adap, MPS_CLS_SRAM_H(idx));
+ u32 rplc[4] = {0, 0, 0, 0};
+
+ if (tcamx & tcamy) {
+ seq_printf(seq, "%3u -\n", idx);
+ goto out;
+ }
+
+ if (cls_lo & REPLICATE_F) {
+ struct fw_ldst_cmd ldst_cmd;
+ int ret;
+
+ memset(&ldst_cmd, 0, sizeof(ldst_cmd));
+ ldst_cmd.op_to_addrspace =
+ htonl(FW_CMD_OP_V(FW_LDST_CMD) |
+ FW_CMD_REQUEST_F |
+ FW_CMD_READ_F |
+ FW_LDST_CMD_ADDRSPACE_V(
+ FW_LDST_ADDRSPC_MPS));
+ ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));
+ ldst_cmd.u.mps.fid_ctl =
+ htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) |
+ FW_LDST_CMD_CTL_V(idx));
+ ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd,
+ sizeof(ldst_cmd), &ldst_cmd);
+ if (ret)
+ dev_warn(adap->pdev_dev, "Can't read MPS "
+ "replication map for idx %d: %d\n",
+ idx, -ret);
+ else {
+ rplc[0] = ntohl(ldst_cmd.u.mps.rplc31_0);
+ rplc[1] = ntohl(ldst_cmd.u.mps.rplc63_32);
+ rplc[2] = ntohl(ldst_cmd.u.mps.rplc95_64);
+ rplc[3] = ntohl(ldst_cmd.u.mps.rplc127_96);
+ }
+ }
+
+ tcamxy2valmask(tcamx, tcamy, addr, &mask);
+ seq_printf(seq, "%3u %02x:%02x:%02x:%02x:%02x:%02x %012llx"
+ "%3c %#x%4u%4d",
+ idx, addr[0], addr[1], addr[2], addr[3], addr[4],
+ addr[5], (unsigned long long)mask,
+ (cls_lo & SRAM_VLD_F) ? 'Y' : 'N', PORTMAP_G(cls_hi),
+ PF_G(cls_lo),
+ (cls_lo & VF_VALID_F) ? VF_G(cls_lo) : -1);
+ if (cls_lo & REPLICATE_F)
+ seq_printf(seq, " %08x %08x %08x %08x",
+ rplc[3], rplc[2], rplc[1], rplc[0]);
+ else
+ seq_printf(seq, "%36c", ' ');
+ seq_printf(seq, "%4u%3u%3u%3u %#x\n",
+ SRAM_PRIO0_G(cls_lo), SRAM_PRIO1_G(cls_lo),
+ SRAM_PRIO2_G(cls_lo), SRAM_PRIO3_G(cls_lo),
+ (cls_lo >> MULTILISTEN0_S) & 0xf);
+ }
+out: return 0;
+}
+
+static inline void *mps_tcam_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct adapter *adap = seq->private;
+ int max_mac_addr = is_t4(adap->params.chip) ?
+ NUM_MPS_CLS_SRAM_L_INSTANCES :
+ NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
+ return ((pos <= max_mac_addr) ? (void *)(uintptr_t)(pos + 1) : NULL);
+}
+
+static void *mps_tcam_start(struct seq_file *seq, loff_t *pos)
+{
+ return *pos ? mps_tcam_get_idx(seq, *pos) : SEQ_START_TOKEN;
+}
+
+static void *mps_tcam_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+ return mps_tcam_get_idx(seq, *pos);
+}
+
+static void mps_tcam_stop(struct seq_file *seq, void *v)
+{
+}
+
+static const struct seq_operations mps_tcam_seq_ops = {
+ .start = mps_tcam_start,
+ .next = mps_tcam_next,
+ .stop = mps_tcam_stop,
+ .show = mps_tcam_show
+};
+
+static int mps_tcam_open(struct inode *inode, struct file *file)
+{
+ int res = seq_open(file, &mps_tcam_seq_ops);
+
+ if (!res) {
+ struct seq_file *seq = file->private_data;
+
+ seq->private = inode->i_private;
+ }
+ return res;
+}
+
+static const struct file_operations mps_tcam_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = mps_tcam_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
@@ -515,6 +645,7 @@ int t4_setup_debugfs(struct adapter *adap)
{ "cim_qcfg", &cim_qcfg_fops, S_IRUSR, 0 },
{ "devlog", &devlog_fops, S_IRUSR, 0 },
{ "l2t", &t4_l2t_fops, S_IRUSR, 0},
+ { "mps_tcam", &mps_tcam_debugfs_fops, S_IRUSR, 0 },
};
add_debugfs_files(adap,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index a2cae0e..7ce55f9 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -1708,6 +1708,66 @@
#define MPS_RX_PERR_INT_CAUSE_A 0x11074
+#define MPS_CLS_TCAM_Y_L_A 0xf000
+#define MPS_CLS_TCAM_X_L_A 0xf008
+
+#define MPS_CLS_TCAM_Y_L(idx) (MPS_CLS_TCAM_Y_L_A + (idx) * 16)
+#define NUM_MPS_CLS_TCAM_Y_L_INSTANCES 512
+
+#define MPS_CLS_TCAM_X_L(idx) (MPS_CLS_TCAM_X_L_A + (idx) * 16)
+#define NUM_MPS_CLS_TCAM_X_L_INSTANCES 512
+
+#define MPS_CLS_SRAM_L_A 0xe000
+#define MPS_CLS_SRAM_H_A 0xe004
+
+#define MPS_CLS_SRAM_L(idx) (MPS_CLS_SRAM_L_A + (idx) * 8)
+#define NUM_MPS_CLS_SRAM_L_INSTANCES 336
+
+#define MPS_CLS_SRAM_H(idx) (MPS_CLS_SRAM_H_A + (idx) * 8)
+#define NUM_MPS_CLS_SRAM_H_INSTANCES 336
+
+#define MULTILISTEN0_S 25
+
+#define REPLICATE_S 11
+#define REPLICATE_V(x) ((x) << REPLICATE_S)
+#define REPLICATE_F REPLICATE_V(1U)
+
+#define PF_S 8
+#define PF_M 0x7U
+#define PF_G(x) (((x) >> PF_S) & PF_M)
+
+#define VF_VALID_S 7
+#define VF_VALID_V(x) ((x) << VF_VALID_S)
+#define VF_VALID_F VF_VALID_V(1U)
+
+#define VF_S 0
+#define VF_M 0x7fU
+#define VF_G(x) (((x) >> VF_S) & VF_M)
+
+#define SRAM_PRIO3_S 22
+#define SRAM_PRIO3_M 0x7U
+#define SRAM_PRIO3_G(x) (((x) >> SRAM_PRIO3_S) & SRAM_PRIO3_M)
+
+#define SRAM_PRIO2_S 19
+#define SRAM_PRIO2_M 0x7U
+#define SRAM_PRIO2_G(x) (((x) >> SRAM_PRIO2_S) & SRAM_PRIO2_M)
+
+#define SRAM_PRIO1_S 16
+#define SRAM_PRIO1_M 0x7U
+#define SRAM_PRIO1_G(x) (((x) >> SRAM_PRIO1_S) & SRAM_PRIO1_M)
+
+#define SRAM_PRIO0_S 13
+#define SRAM_PRIO0_M 0x7U
+#define SRAM_PRIO0_G(x) (((x) >> SRAM_PRIO0_S) & SRAM_PRIO0_M)
+
+#define SRAM_VLD_S 12
+#define SRAM_VLD_V(x) ((x) << SRAM_VLD_S)
+#define SRAM_VLD_F SRAM_VLD_V(1U)
+
+#define PORTMAP_S 0
+#define PORTMAP_M 0xfU
+#define PORTMAP_G(x) (((x) >> PORTMAP_S) & PORTMAP_M)
+
#define CPL_INTR_CAUSE_A 0x19054
#define CIM_OP_MAP_PERR_S 5
--
1.7.1
^ permalink raw reply related
* Re: [PATCH net-next v1 2/3] ARM: imx: add FEC sleep mode callback function
From: Shawn Guo @ 2015-01-07 3:17 UTC (permalink / raw)
To: fugang.duan@freescale.com, davem@davemloft.net
Cc: netdev@vger.kernel.org, bhutchings@solarflare.com,
stephen@networkplumber.org
In-Reply-To: <BLUPR03MB37385464C06052A231ABF19F5460@BLUPR03MB373.namprd03.prod.outlook.com>
On Wed, Jan 07, 2015 at 02:40:33AM +0000, fugang.duan@freescale.com wrote:
> Yes, the platform code will become quite messy and tremendous.
> I agree with your thinking.
>
> But David applied the patches, how can I do it now ?
David,
Can you please drop the last two arch/arm/ patches, or revert them if
your tree is non-rebasable?
Shawn
^ permalink raw reply
* Re: [PATCH next] net: e1000: support txtd update delay via xmit_more
From: Jeff Kirsher @ 2015-01-07 3:34 UTC (permalink / raw)
To: Florian Westphal; +Cc: netdev
In-Reply-To: <1420557419-18869-1-git-send-email-fw@strlen.de>
On Tue, Jan 6, 2015 at 7:16 AM, Florian Westphal <fw@strlen.de> wrote:
> Don't update tx tail descriptor if we queue hasn't been stopped and
> we know at least one more skb will be sent right away.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> drivers/net/ethernet/intel/e1000/e1000_main.c | 14 ++++++++------
> 1 file changed, 8 insertions(+), 6 deletions(-)
Thanks Florian, I will add your patch to my queue.
^ permalink raw reply
* Re: [PATCH 2/6] vxlan: Group Policy extension
From: Alexei Starovoitov @ 2015-01-07 3:37 UTC (permalink / raw)
To: Thomas Graf
Cc: dev-yBygre7rU0TnMu66kgdUjQ@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Stephen Hemminger,
David S. Miller
On Tue, Jan 6, 2015 at 6:05 PM, Thomas Graf <tgraf@suug.ch> wrote:
> +struct vxlan_gbp {
> +#ifdef __LITTLE_ENDIAN_BITFIELD
> + __u8 reserved_flags1:3,
...
> + __be16 policy_id;
> +} __packed;
are you sure that compiler will be smart enough
to do single short load when you pack
u8 + struct vxlan_gbp inside struct vxlanhdr ?
I suspect compiler will use two byte loads
with shifts and ors every time to access policy_id.
Even it works ok, I think this struct layout is ugly.
imo would be much easier to read if you replace
the whole vxlanhdr with vxlanhdr_gbp
or split vxlanhdr into two 32-bit structs.
then __packed hacks won't be needed.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev
^ permalink raw reply
* [PATCH 0/6] driver/net/irda: Use ktime_t instead of timeval
From: Chunyan Zhang @ 2015-01-07 3:39 UTC (permalink / raw)
To: samuel; +Cc: arnd, zhang.lyra, netdev, linux-kernel
In-Reply-To: <driver-irda>
This patch-set removed all uses of timeval and used ktime_t instead if
needed, since 32-bit time types will break in the year 2038.
This patch-set also used the ktime_xxx functions accordingly.
e.g.
* Used ktime_get to get the current time instead of do_gettimeofday.
* And, used ktime_us_delta to get the elapsed time directly.
Chunyan Zhang (6):
driver/net/irda: Removed all unused timeval variables
driver/net/irda: Replace timeval with ktime_t in ali-ircc
driver/net/irda: Replace timeval with ktime_t in irda-usb
driver/net/irda: Replace timeval with ktime_t in nsc-ircc
driver/net/irda: Replace timeval with ktime_t in stir4200
driver/net/irda: Replace timeval with ktime_t in vlsi_ir
drivers/net/irda/ali-ircc.c | 12 ++++------
drivers/net/irda/ali-ircc.h | 6 ++---
drivers/net/irda/au1k_ir.c | 3 ---
drivers/net/irda/irda-usb.c | 11 +++------
drivers/net/irda/irda-usb.h | 6 ++---
drivers/net/irda/kingsun-sir.c | 3 ---
drivers/net/irda/ks959-sir.c | 3 ---
drivers/net/irda/mcs7780.c | 2 --
drivers/net/irda/mcs7780.h | 1 -
drivers/net/irda/nsc-ircc.c | 8 +++----
drivers/net/irda/nsc-ircc.h | 6 ++---
drivers/net/irda/stir4200.c | 18 +++++++-------
drivers/net/irda/via-ircc.h | 4 ----
drivers/net/irda/vlsi_ir.c | 51 ++++++++++++++--------------------------
drivers/net/irda/vlsi_ir.h | 2 +-
15 files changed, 46 insertions(+), 90 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH 1/6] driver/net/irda: Removed all unused timeval variables
From: Chunyan Zhang @ 2015-01-07 3:39 UTC (permalink / raw)
To: samuel; +Cc: arnd, zhang.lyra, netdev, linux-kernel
In-Reply-To: <1420601978-15866-1-git-send-email-zhang.chunyan@linaro.org>
In the file au1k_ir.c & via-ircc.h, there were two unused
definitions of the timeval type members, so I removed them
entirely in this patch.
In other three files, the same problem is the rx_time
member is only ever written, never read, so removed it
entirely.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
drivers/net/irda/au1k_ir.c | 3 ---
drivers/net/irda/kingsun-sir.c | 3 ---
drivers/net/irda/ks959-sir.c | 3 ---
drivers/net/irda/mcs7780.c | 2 --
drivers/net/irda/mcs7780.h | 1 -
drivers/net/irda/via-ircc.h | 4 ----
6 files changed, 16 deletions(-)
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index e151205..44e4f38 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -24,7 +24,6 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/time.h>
#include <linux/types.h>
#include <linux/ioport.h>
@@ -163,8 +162,6 @@ struct au1k_private {
iobuff_t rx_buff;
struct net_device *netdev;
- struct timeval stamp;
- struct timeval now;
struct qos_info qos;
struct irlap_cb *irlap;
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index e638893..fb5d162 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -114,7 +114,6 @@ struct kingsun_cb {
(usually 8) */
iobuff_t rx_buff; /* receive unwrap state machine */
- struct timeval rx_time;
spinlock_t lock;
int receiving;
@@ -235,7 +234,6 @@ static void kingsun_rcv_irq(struct urb *urb)
&kingsun->netdev->stats,
&kingsun->rx_buff, bytes[i]);
}
- do_gettimeofday(&kingsun->rx_time);
kingsun->receiving =
(kingsun->rx_buff.state != OUTSIDE_FRAME)
? 1 : 0;
@@ -273,7 +271,6 @@ static int kingsun_net_open(struct net_device *netdev)
skb_reserve(kingsun->rx_buff.skb, 1);
kingsun->rx_buff.head = kingsun->rx_buff.skb->data;
- do_gettimeofday(&kingsun->rx_time);
kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kingsun->rx_urb)
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index e6b3804..8e6e0ed 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -187,7 +187,6 @@ struct ks959_cb {
__u8 *rx_buf;
__u8 rx_variable_xormask;
iobuff_t rx_unwrap_buff;
- struct timeval rx_time;
struct usb_ctrlrequest *speed_setuprequest;
struct urb *speed_urb;
@@ -476,7 +475,6 @@ static void ks959_rcv_irq(struct urb *urb)
bytes[i]);
}
}
- do_gettimeofday(&kingsun->rx_time);
kingsun->receiving =
(kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
}
@@ -514,7 +512,6 @@ static int ks959_net_open(struct net_device *netdev)
skb_reserve(kingsun->rx_unwrap_buff.skb, 1);
kingsun->rx_unwrap_buff.head = kingsun->rx_unwrap_buff.skb->data;
- do_gettimeofday(&kingsun->rx_time);
kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kingsun->rx_urb)
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index e4d678f..bca6a1e 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -722,7 +722,6 @@ static int mcs_net_open(struct net_device *netdev)
skb_reserve(mcs->rx_buff.skb, 1);
mcs->rx_buff.head = mcs->rx_buff.skb->data;
- do_gettimeofday(&mcs->rx_time);
/*
* Now that everything should be initialized properly,
@@ -799,7 +798,6 @@ static void mcs_receive_irq(struct urb *urb)
mcs_unwrap_fir(mcs, urb->transfer_buffer,
urb->actual_length);
}
- do_gettimeofday(&mcs->rx_time);
}
ret = usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/drivers/net/irda/mcs7780.h b/drivers/net/irda/mcs7780.h
index b10689b..a6e8f7d 100644
--- a/drivers/net/irda/mcs7780.h
+++ b/drivers/net/irda/mcs7780.h
@@ -116,7 +116,6 @@ struct mcs_cb {
__u8 *fifo_status;
iobuff_t rx_buff; /* receive unwrap state machine */
- struct timeval rx_time;
spinlock_t lock;
int receiving;
diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h
index 7ce820e..ac15255 100644
--- a/drivers/net/irda/via-ircc.h
+++ b/drivers/net/irda/via-ircc.h
@@ -29,7 +29,6 @@ this program; if not, see <http://www.gnu.org/licenses/>.
********************************************************************/
#ifndef via_IRCC_H
#define via_IRCC_H
-#include <linux/time.h>
#include <linux/spinlock.h>
#include <linux/pm.h>
#include <linux/types.h>
@@ -106,9 +105,6 @@ struct via_ircc_cb {
__u8 ier; /* Interrupt enable register */
- struct timeval stamp;
- struct timeval now;
-
spinlock_t lock; /* For serializing operations */
__u32 flags; /* Interface flags */
--
1.7.9.5
^ permalink raw reply related
* [PATCH 3/6] driver/net/irda: Replace timeval with ktime_t in irda-usb
From: Chunyan Zhang @ 2015-01-07 3:39 UTC (permalink / raw)
To: samuel; +Cc: arnd, zhang.lyra, netdev, linux-kernel
In-Reply-To: <1420601978-15866-1-git-send-email-zhang.chunyan@linaro.org>
This patch changes the 32-bit time type (timeval) to the 64-bit one
(ktime_t), since 32-bit time types will break in the year 2038.
So, I use ktime_t instead of all uses of timeval.
This patch also changes do_gettimeofday() to ktime_get() accordingly,
since ktime_get returns a ktime_t, but do_gettimeofday returns a
struct timeval, and the other reason is that ktime_get() uses
the monotonic clock.
This patch use ktime_us_delta to get the elapsed time, and in this
way it no longer needs to check for the overflow, because
ktime_us_delta returns time difference of microsecond.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
drivers/net/irda/irda-usb.c | 11 +++--------
drivers/net/irda/irda-usb.h | 6 +++---
2 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 48b2f9a..be86840 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -495,18 +495,13 @@ static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb,
mtt = irda_get_mtt(skb);
if (mtt) {
int diff;
- do_gettimeofday(&self->now);
- diff = self->now.tv_usec - self->stamp.tv_usec;
+ self->now = ktime_get();
+ diff = ktime_us_delta(self->now, self->stamp);
#ifdef IU_USB_MIN_RTT
/* Factor in USB delays -> Get rid of udelay() that
* would be lost in the noise - Jean II */
diff += IU_USB_MIN_RTT;
#endif /* IU_USB_MIN_RTT */
- /* If the usec counter did wraparound, the diff will
- * go negative (tv_usec is a long), so we need to
- * correct it by one second. Jean II */
- if (diff < 0)
- diff += 1000000;
/* Check if the mtt is larger than the time we have
* already used by all the protocol processing
@@ -869,7 +864,7 @@ static void irda_usb_receive(struct urb *urb)
* reduce the min turn time a bit since we will know
* how much time we have used for protocol processing
*/
- do_gettimeofday(&self->stamp);
+ self->stamp = ktime_get();
/* Check if we need to copy the data to a new skb or not.
* For most frames, we use ZeroCopy and pass the already
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h
index 58ddb52..8093216 100644
--- a/drivers/net/irda/irda-usb.h
+++ b/drivers/net/irda/irda-usb.h
@@ -29,7 +29,7 @@
*
*****************************************************************************/
-#include <linux/time.h>
+#include <linux/ktime.h>
#include <net/irda/irda.h>
#include <net/irda/irda_device.h> /* struct irlap_cb */
@@ -157,8 +157,8 @@ struct irda_usb_cb {
char *speed_buff; /* Buffer for speed changes */
char *tx_buff;
- struct timeval stamp;
- struct timeval now;
+ ktime_t stamp;
+ ktime_t now;
spinlock_t lock; /* For serializing Tx operations */
--
1.7.9.5
^ permalink raw reply related
* [PATCH 4/6] driver/net/irda: Replace timeval with ktime_t in nsc-ircc
From: Chunyan Zhang @ 2015-01-07 3:39 UTC (permalink / raw)
To: samuel; +Cc: arnd, zhang.lyra, netdev, linux-kernel
In-Reply-To: <1420601978-15866-1-git-send-email-zhang.chunyan@linaro.org>
This patch changes the 32-bit time type (timeval) to the 64-bit one
(ktime_t), since 32-bit time types will break in the year 2038.
So, I use ktime_t instead of all uses of timeval.
This patch also changes do_gettimeofday() to ktime_get() accordingly,
since ktime_get returns a ktime_t, but do_gettimeofday returns a
struct timeval, and the other reason is that ktime_get() uses
the monotonic clock.
This patch use ktime_us_delta to get the elapsed time, and in this
way it no longer needs to check for the overflow, because
ktime_us_delta returns time difference of microsecond.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
drivers/net/irda/nsc-ircc.c | 8 +++-----
drivers/net/irda/nsc-ircc.h | 6 +++---
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index e7317b1..cabb82e 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -1501,10 +1501,8 @@ static netdev_tx_t nsc_ircc_hard_xmit_fir(struct sk_buff *skb,
mtt = irda_get_mtt(skb);
if (mtt) {
/* Check how much time we have used already */
- do_gettimeofday(&self->now);
- diff = self->now.tv_usec - self->stamp.tv_usec;
- if (diff < 0)
- diff += 1000000;
+ self->now = ktime_get();
+ diff = ktime_us_delta(self->now, self->stamp);
/* Check if the mtt is larger than the time we have
* already used by all the protocol processing
@@ -1867,7 +1865,7 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase)
* reduce the min turn time a bit since we will know
* how much time we have used for protocol processing
*/
- do_gettimeofday(&self->stamp);
+ self->stamp = ktime_get();
skb = dev_alloc_skb(len+1);
if (skb == NULL) {
diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h
index 32fa582..dd2185a 100644
--- a/drivers/net/irda/nsc-ircc.h
+++ b/drivers/net/irda/nsc-ircc.h
@@ -28,7 +28,7 @@
#ifndef NSC_IRCC_H
#define NSC_IRCC_H
-#include <linux/time.h>
+#include <linux/ktime.h>
#include <linux/spinlock.h>
#include <linux/pm.h>
@@ -263,8 +263,8 @@ struct nsc_ircc_cb {
__u8 ier; /* Interrupt enable register */
- struct timeval stamp;
- struct timeval now;
+ ktime_t stamp;
+ ktime_t now;
spinlock_t lock; /* For serializing operations */
--
1.7.9.5
^ permalink raw reply related
* [PATCH 5/6] driver/net/irda: Replace timeval with ktime_t in stir4200
From: Chunyan Zhang @ 2015-01-07 3:39 UTC (permalink / raw)
To: samuel; +Cc: arnd, zhang.lyra, netdev, linux-kernel
In-Reply-To: <1420601978-15866-1-git-send-email-zhang.chunyan@linaro.org>
This patch changes the 32-bit time type (timeval) to the 64-bit one
(ktime_t), since 32-bit time types will break in the year 2038.
So, I use ktime_t instead of all uses of timeval.
This patch also changes do_gettimeofday() to ktime_get() accordingly,
since ktime_get returns a ktime_t, but do_gettimeofday returns a
struct timeval, and the other reason is that ktime_get() uses
the monotonic clock.
This patch use ktime_us_delta to get the elapsed time of microsecond.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
drivers/net/irda/stir4200.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index dd1bd10..008e12d 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -40,6 +40,7 @@
#include <linux/moduleparam.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/types.h>
#include <linux/time.h>
#include <linux/skbuff.h>
@@ -174,7 +175,7 @@ struct stir_cb {
__u8 *fifo_status;
iobuff_t rx_buff; /* receive unwrap state machine */
- struct timeval rx_time;
+ ktime_t rx_time;
int receiving;
struct urb *rx_urb;
};
@@ -650,15 +651,14 @@ static int fifo_txwait(struct stir_cb *stir, int space)
static void turnaround_delay(const struct stir_cb *stir, long us)
{
long ticks;
- struct timeval now;
+ ktime_t now;
if (us <= 0)
return;
- do_gettimeofday(&now);
- if (now.tv_sec - stir->rx_time.tv_sec > 0)
- us -= USEC_PER_SEC;
- us -= now.tv_usec - stir->rx_time.tv_usec;
+ now = ktime_get();
+ us -= ktime_us_delta(now, stir->rx_time);
+
if (us < 10)
return;
@@ -823,8 +823,8 @@ static void stir_rcv_irq(struct urb *urb)
pr_debug("receive %d\n", urb->actual_length);
unwrap_chars(stir, urb->transfer_buffer,
urb->actual_length);
-
- do_gettimeofday(&stir->rx_time);
+
+ stir->rx_time = ktime_get();
}
/* kernel thread is stopping receiver don't resubmit */
@@ -876,7 +876,7 @@ static int stir_net_open(struct net_device *netdev)
skb_reserve(stir->rx_buff.skb, 1);
stir->rx_buff.head = stir->rx_buff.skb->data;
- do_gettimeofday(&stir->rx_time);
+ stir->rx_time = ktime_get();
stir->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!stir->rx_urb)
--
1.7.9.5
^ permalink raw reply related
* [PATCH 6/6] driver/net/irda: Replace timeval with ktime_t in vlsi_ir
From: Chunyan Zhang @ 2015-01-07 3:39 UTC (permalink / raw)
To: samuel; +Cc: arnd, zhang.lyra, netdev, linux-kernel
In-Reply-To: <1420601978-15866-1-git-send-email-zhang.chunyan@linaro.org>
This patch changes the 32-bit time type (timeval) to the 64-bit one
(ktime_t), since 32-bit time types will break in the year 2038.
So, I use ktime_t instead of all uses of timeval.
This patch also changes do_gettimeofday() to ktime_get() accordingly,
since ktime_get returns a ktime_t, but do_gettimeofday returns a
struct timeval, and the other reason is that ktime_get() uses
the monotonic clock.
This patch uses ktime_us_delta to get the elapsed time of microsecond,
and uses div_s64_rem to get what seconds & microseconds time elapsed
for printing.
This patch also changes the code of function 'vlsi_hard_start_xmit' to
do the same things as the others drivers, that is passing the remaining
time into udelay() instead of looping until enough time has passed.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
drivers/net/irda/vlsi_ir.c | 51 +++++++++++++++-----------------------------
drivers/net/irda/vlsi_ir.h | 2 +-
2 files changed, 18 insertions(+), 35 deletions(-)
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index ac39d9f..a60a73d 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -33,6 +33,7 @@ MODULE_LICENSE("GPL");
/********************************************************/
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
@@ -40,9 +41,9 @@ MODULE_LICENSE("GPL");
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
-#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/math64.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
@@ -180,8 +181,8 @@ static void vlsi_proc_ndev(struct seq_file *seq, struct net_device *ndev)
vlsi_irda_dev_t *idev = netdev_priv(ndev);
u8 byte;
u16 word;
- unsigned delta1, delta2;
- struct timeval now;
+ ktime_t now;
+ s32 sec, usec;
unsigned iobase = ndev->base_addr;
seq_printf(seq, "\n%s link state: %s / %s / %s / %s\n", ndev->name,
@@ -277,17 +278,10 @@ static void vlsi_proc_ndev(struct seq_file *seq, struct net_device *ndev)
seq_printf(seq, "\nsw-state:\n");
seq_printf(seq, "IrPHY setup: %d baud - %s encoding\n", idev->baud,
(idev->mode==IFF_SIR)?"SIR":((idev->mode==IFF_MIR)?"MIR":"FIR"));
- do_gettimeofday(&now);
- if (now.tv_usec >= idev->last_rx.tv_usec) {
- delta2 = now.tv_usec - idev->last_rx.tv_usec;
- delta1 = 0;
- }
- else {
- delta2 = 1000000 + now.tv_usec - idev->last_rx.tv_usec;
- delta1 = 1;
- }
- seq_printf(seq, "last rx: %lu.%06u sec\n",
- now.tv_sec - idev->last_rx.tv_sec - delta1, delta2);
+ now = ktime_get();
+ sec = div_s64_rem(ktime_us_delta(now, idev->last_rx),
+ USEC_PER_SEC, &usec);
+ seq_printf(seq, "last rx: %ul.%06u sec\n", sec, usec);
seq_printf(seq, "RX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu",
ndev->stats.rx_packets, ndev->stats.rx_bytes, ndev->stats.rx_errors,
@@ -661,7 +655,7 @@ static void vlsi_rx_interrupt(struct net_device *ndev)
}
}
- do_gettimeofday(&idev->last_rx); /* remember "now" for later mtt delay */
+ idev->last_rx = ktime_get(); /* remember "now" for later mtt delay */
vlsi_fill_rx(r);
@@ -858,9 +852,9 @@ static netdev_tx_t vlsi_hard_start_xmit(struct sk_buff *skb,
unsigned iobase = ndev->base_addr;
u8 status;
u16 config;
- int mtt;
+ int mtt, diff;
int len, speed;
- struct timeval now, ready;
+ ktime_t now;
char *msg = NULL;
speed = irda_get_next_speed(skb);
@@ -940,21 +934,10 @@ static netdev_tx_t vlsi_hard_start_xmit(struct sk_buff *skb,
spin_unlock_irqrestore(&idev->lock, flags);
if ((mtt = irda_get_mtt(skb)) > 0) {
-
- ready.tv_usec = idev->last_rx.tv_usec + mtt;
- ready.tv_sec = idev->last_rx.tv_sec;
- if (ready.tv_usec >= 1000000) {
- ready.tv_usec -= 1000000;
- ready.tv_sec++; /* IrLAP 1.1: mtt always < 1 sec */
- }
- for(;;) {
- do_gettimeofday(&now);
- if (now.tv_sec > ready.tv_sec ||
- (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
- break;
- udelay(100);
- /* must not sleep here - called under netif_tx_lock! */
- }
+ now = ktime_get();
+ diff = ktime_us_delta(now, idev->last_rx);
+ if (mtt > diff)
+ udelay(mtt - diff);
}
/* tx buffer already owned by CPU due to pci_dma_sync_single_for_cpu()
@@ -1333,7 +1316,7 @@ static int vlsi_start_hw(vlsi_irda_dev_t *idev)
vlsi_fill_rx(idev->rx_ring);
- do_gettimeofday(&idev->last_rx); /* first mtt may start from now on */
+ idev->last_rx = ktime_get(); /* first mtt may start from now on */
outw(0, iobase+VLSI_PIO_PROMPT); /* kick hw state machine */
@@ -1520,7 +1503,7 @@ static int vlsi_open(struct net_device *ndev)
if (!idev->irlap)
goto errout_free_ring;
- do_gettimeofday(&idev->last_rx); /* first mtt may start from now on */
+ idev->last_rx = ktime_get(); /* first mtt may start from now on */
idev->new_baud = 9600; /* start with IrPHY using 9600(SIR) mode */
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index f9119c6..f9db2ce 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -723,7 +723,7 @@ typedef struct vlsi_irda_dev {
void *virtaddr;
struct vlsi_ring *tx_ring, *rx_ring;
- struct timeval last_rx;
+ ktime_t last_rx;
spinlock_t lock;
struct mutex mtx;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/6] driver/net/irda: Replace timeval with ktime_t in ali-ircc
From: Chunyan Zhang @ 2015-01-07 3:39 UTC (permalink / raw)
To: samuel; +Cc: arnd, zhang.lyra, netdev, linux-kernel
In-Reply-To: <1420601978-15866-1-git-send-email-zhang.chunyan@linaro.org>
This patch changes the 32-bit time type (timeval) to the 64-bit one
(ktime_t), since 32-bit time types will break in the year 2038.
So, I use ktime_t instead of all uses of timeval.
This patch also changes do_gettimeofday() to ktime_get() accordingly,
since ktime_get returns a ktime_t, but do_gettimeofday returns a
struct timeval, and the other reason is that ktime_get() uses
the monotonic clock.
This patch use ktime_us_delta to get the elapsed time, and in this
way it no longer needs to check for the overflow, because
ktime_us_delta returns time difference of microsecond.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
drivers/net/irda/ali-ircc.c | 12 ++++--------
drivers/net/irda/ali-ircc.h | 6 +++---
2 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 58f98f4..ab041a4 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -1462,17 +1462,13 @@ static netdev_tx_t ali_ircc_fir_hard_xmit(struct sk_buff *skb,
if (mtt)
{
/* Check how much time we have used already */
- do_gettimeofday(&self->now);
-
- diff = self->now.tv_usec - self->stamp.tv_usec;
+ self->now = ktime_get();
+ diff = ktime_us_delta(self->now, self->stamp);
/* self->stamp is set from ali_ircc_dma_receive_complete() */
pr_debug("%s(), ******* diff = %d *******\n",
__func__, diff);
-
- if (diff < 0)
- diff += 1000000;
-
+
/* Check if the mtt is larger than the time we have
* already used by all the protocol processing
*/
@@ -1884,7 +1880,7 @@ static int ali_ircc_dma_receive_complete(struct ali_ircc_cb *self)
* reduce the min turn time a bit since we will know
* how much time we have used for protocol processing
*/
- do_gettimeofday(&self->stamp);
+ self->stamp = ktime_get();
skb = dev_alloc_skb(len+1);
if (skb == NULL)
diff --git a/drivers/net/irda/ali-ircc.h b/drivers/net/irda/ali-ircc.h
index 0c8edb4..164ee42 100644
--- a/drivers/net/irda/ali-ircc.h
+++ b/drivers/net/irda/ali-ircc.h
@@ -22,7 +22,7 @@
#ifndef ALI_IRCC_H
#define ALI_IRCC_H
-#include <linux/time.h>
+#include <linux/ktime.h>
#include <linux/spinlock.h>
#include <linux/pm.h>
@@ -209,8 +209,8 @@ struct ali_ircc_cb {
unsigned char rcvFramesOverflow;
- struct timeval stamp;
- struct timeval now;
+ ktime_t stamp;
+ ktime_t now;
spinlock_t lock; /* For serializing operations */
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH net-next v1 2/3] ARM: imx: add FEC sleep mode callback function
From: Fabio Estevam @ 2015-01-07 3:44 UTC (permalink / raw)
To: Shawn Guo
Cc: fugang.duan@freescale.com, davem@davemloft.net,
netdev@vger.kernel.org, bhutchings@solarflare.com,
stephen@networkplumber.org
In-Reply-To: <20150107023307.GA4928@dragon>
On Wed, Jan 7, 2015 at 12:33 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
> The GPR difference between SoCs can be encoded in device tree as well.
> It's pointless to repeat the same code pattern for every single
> platform, that need to set up GPR bits for enabling magic packet wake
> up, while the only difference is the register and bit offset.
>
> The platform code will become quite messy and unmaintainable if every
> device driver dump their GPR register setup code into platform.
>
> Sorry, but it's NACK from me.
This patch has already reached linux-next via Dave's tree as commit
456062b3ec6f5.
Should a revert patch be sent?
Also, this commit causes a build warning in linux-next:
arch/arm/mach-imx/mach-imx6sx.c:59:20: warning: 'imx6sx_enet_plt_init'
defined but not used [-Wunused-function]
^ permalink raw reply
* Re: [PATCH 1/6] vxlan: Allow for VXLAN extensions to be implemented
From: Tom Herbert @ 2015-01-07 3:46 UTC (permalink / raw)
To: Thomas Graf
Cc: David Miller, Jesse Gross, Stephen Hemminger, Pravin B Shelar,
Linux Netdev List, dev@openvswitch.org
In-Reply-To: <7c5e8240263a22a69042c45a632c9940e5ae1062.1420594925.git.tgraf@suug.ch>
On Tue, Jan 6, 2015 at 6:05 PM, Thomas Graf <tgraf@suug.ch> wrote:
> The VXLAN receive code is currently conservative in what it accepts and
> will reject any frame that uses any of the reserved VXLAN protocol fields.
> The VXLAN draft specifies that "reserved fields MUST be set to zero on
> transmit and ignored on receive.".
>
IMO it is an unfortunate decision in VXLAN to ignore set reserved
fields on receive. Had they not done this, then adding a protocol
field to the header would have been feasible and we wouldn't need yet
another encapsulation protocol (i.e. VXLAN-GPE). Rejecting frames with
reserved bits set is the better behavior, but I think the comment
about this needs to be clear about why this diverges from RFC7348.
> Retain the current conservative parsing behaviour by default but allows
> these fields to be used by VXLAN extensions which are explicitly enabled
> on the VXLAN socket respectively VXLAN net_device.
>
Conceptually, VXLAN has both mandatory flags and optional flags for
extensions. You may want to look at the VXLAN RCO patches that added
an extension and infrastructure for them.
Tom
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> ---
> drivers/net/vxlan.c | 29 +++++++++++++++++++----------
> include/net/vxlan.h | 32 +++++++++++++++++++++++++++++---
> 2 files changed, 48 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index 2ab0922..4d52aa9 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -65,7 +65,7 @@
> #define VXLAN_VID_MASK (VXLAN_N_VID - 1)
> #define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
>
> -#define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */
> +#define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags default value. */
>
> /* UDP port for VXLAN traffic.
> * The IANA assigned port is 4789, but the Linux default is 8472
> @@ -1100,22 +1100,28 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
> if (!pskb_may_pull(skb, VXLAN_HLEN))
> goto error;
>
> + vs = rcu_dereference_sk_user_data(sk);
> + if (!vs)
> + goto drop;
> +
> /* Return packets with reserved bits set */
> vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
> - if (vxh->vx_flags != htonl(VXLAN_FLAGS) ||
> - (vxh->vx_vni & htonl(0xff))) {
> - netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
> - ntohl(vxh->vx_flags), ntohl(vxh->vx_vni));
> - goto error;
> +
> + /* For backwards compatibility, only allow reserved fields to be
> + * used by VXLAN extensions if explicitly requested.
> + */
> + if (vs->exts) {
> + if (!vxh->vni_present)
> + goto error_invalid_header;
> + } else {
> + if (vxh->vx_flags != htonl(VXLAN_FLAGS) ||
> + (vxh->vx_vni & htonl(0xff)))
> + goto error_invalid_header;
> }
>
> if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
> goto drop;
>
> - vs = rcu_dereference_sk_user_data(sk);
> - if (!vs)
> - goto drop;
> -
> vs->rcv(vs, skb, vxh->vx_vni);
> return 0;
>
> @@ -1124,6 +1130,9 @@ drop:
> kfree_skb(skb);
> return 0;
>
> +error_invalid_header:
> + netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
> + ntohl(vxh->vx_flags), ntohl(vxh->vx_vni));
> error:
> /* Return non vxlan pkt */
> return 1;
> diff --git a/include/net/vxlan.h b/include/net/vxlan.h
> index 903461a..3e98d31 100644
> --- a/include/net/vxlan.h
> +++ b/include/net/vxlan.h
> @@ -11,10 +11,35 @@
> #define VNI_HASH_BITS 10
> #define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
>
> -/* VXLAN protocol header */
> +/* VXLAN protocol header:
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |R|R|R|R|I|R|R|R| Reserved |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * | VXLAN Network Identifier (VNI) | Reserved |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + *
> + * I = 1 VXLAN Network Identifier (VNI) present
> + */
> struct vxlanhdr {
> - __be32 vx_flags;
> - __be32 vx_vni;
> + union {
> + struct {
> +#ifdef __LITTLE_ENDIAN_BITFIELD
> + __u8 reserved_flags1:3,
> + vni_present:1,
> + reserved_flags2:4;
> +#elif defined(__BIG_ENDIAN_BITFIELD)
> + __u8 reserved_flags2:4,
> + vni_present:1,
> + reserved_flags1:3;
> +#else
> +#error "Please fix <asm/byteorder.h>"
> +#endif
> + __u8 vx_reserved1;
> + __be16 vx_reserved2;
> + };
> + __be32 vx_flags;
> + };
> + __be32 vx_vni;
> };
>
> struct vxlan_sock;
> @@ -25,6 +50,7 @@ struct vxlan_sock {
> struct hlist_node hlist;
> vxlan_rcv_t *rcv;
> void *data;
> + u32 exts;
> struct work_struct del_work;
> struct socket *sock;
> struct rcu_head rcu;
> --
> 1.9.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Some warnings for skge - netpoll/netconsole induced
From: poma @ 2015-01-07 5:29 UTC (permalink / raw)
To: netdev
------------[ cut here ]------------
WARNING: CPU: 1 PID: 2991 at net/core/netpoll.c:362 netpoll_send_skb_on_dev+0x25e/0x270()
netpoll_send_skb_on_dev(): enp1s6 enabled interrupts in poll (skge_xmit_frame+0x0/0x680 [skge])
...
CPU: 1 PID: 2991 Comm: modprobe Not tainted 3.19.0-0.rc3.git0.1.fc21.x86_64 #1
...
Call Trace:
[<ffffffff8176cf2d>] dump_stack+0x45/0x57
[<ffffffff8109b09a>] warn_slowpath_common+0x8a/0xc0
[<ffffffff8109b125>] warn_slowpath_fmt+0x55/0x70
[<ffffffff813a2aab>] ? delay_tsc+0x3b/0x70
[<ffffffffa00d3be0>] ? skge_rx_setup.isra.44+0x180/0x180 [skge]
[<ffffffff8167518e>] netpoll_send_skb_on_dev+0x25e/0x270
[<ffffffff81675462>] netpoll_send_udp+0x2c2/0x410
[<ffffffffa079b92f>] write_msg+0xcf/0x140 [netconsole]
[<ffffffff810ef2aa>] call_console_drivers.constprop.22+0xaa/0xf0
[<ffffffff810f0992>] console_unlock+0x362/0x450
[<ffffffff810f0e30>] vprintk_emit+0x3b0/0x550
[<ffffffff810f1159>] vprintk_default+0x29/0x40
[<ffffffff8176b42c>] printk+0x55/0x6b
[<ffffffff810f15cd>] register_console+0x1bd/0x380
[<ffffffffa07a0000>] ? 0xffffffffa07a0000
[<ffffffffa07a01c4>] init_netconsole+0x1c4/0x1000 [netconsole]
[<ffffffffa07a0000>] ? 0xffffffffa07a0000
[<ffffffff81002148>] do_one_initcall+0xd8/0x210
[<ffffffff811de302>] ? __vunmap+0xa2/0x100
[<ffffffff8111ef16>] load_module+0x2256/0x2800
[<ffffffff8111a750>] ? store_uevent+0x70/0x70
[<ffffffff8111f58d>] SyS_init_module+0xcd/0x120
[<ffffffff81773929>] system_call_fastpath+0x12/0x17
---[ end trace 257df3717d2db089 ]---
^ permalink raw reply
* [PATCH] sh_eth: Fix access to TRSCER register
From: Nobuhiro Iwamatsu @ 2015-01-07 5:35 UTC (permalink / raw)
To: netdev; +Cc: yoshihiro.shimoda.uh, linux-sh, Nobuhiro Iwamatsu
TRSCER register is configured differently by SoCs. TRSCER of R-Car is
RINT8 bit only valid, other bits are reserved bits.
This removes access to TRSCER register reserve bit.
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index c29ba80..59ee457 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1294,7 +1294,11 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start)
/* Frame recv control (enable multiple-packets per rx irq) */
sh_eth_write(ndev, RMCR_RNC, RMCR);
- sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER);
+ if (mdp->cd->register_type == SH_ETH_REG_FAST_RCAR)
+ sh_eth_write(ndev, DESC_I_RINT8, TRSCER);
+ else
+ sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2,
+ TRSCER);
if (mdp->cd->bculr)
sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */
--
2.1.3
^ permalink raw reply related
* Re: [net-next PATCH v1 01/11] net: flow_table: create interface for hw match/action tables
From: John Fastabend @ 2015-01-07 5:37 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Thomas Graf, Scott Feldman, Jiří Pírko,
Jamal Hadi Salim, simon.horman, netdev@vger.kernel.org,
David S. Miller, Andy Gospodarek
In-Reply-To: <CAADnVQJ6MWVCPsBX6oZpQq=D=4iO7zE5rV8N1Vw5WHxDFGZ7xg@mail.gmail.com>
On 01/06/2015 05:14 PM, Alexei Starovoitov wrote:
> On Wed, Dec 31, 2014 at 11:45 AM, John Fastabend
> <john.fastabend@gmail.com> wrote:
>> + * [NET_FLOW_TABLE_IDENTIFIER_TYPE]
>> + * [NET_FLOW_TABLE_IDENTIFIER]
>> + * [NET_FLOW_TABLE_TABLES]
>> + * [NET_FLOW_TABLE]
>> + * [NET_FLOW_TABLE_ATTR_NAME]
>> + * [NET_FLOW_TABLE_ATTR_UID]
>> + * [NET_FLOW_TABLE_ATTR_SOURCE]
>> + * [NET_FLOW_TABLE_ATTR_SIZE]
> ...
>> + * Header definitions used to define headers with user friendly
>> + * names.
>> + *
>> + * [NET_FLOW_TABLE_HEADERS]
>> + * [NET_FLOW_HEADER]
>> + * [NET_FLOW_HEADER_ATTR_NAME]
>> + * [NET_FLOW_HEADER_ATTR_UID]
>> + * [NET_FLOW_HEADER_ATTR_FIELDS]
>> + * [NET_FLOW_HEADER_ATTR_FIELD]
>> + * [NET_FLOW_FIELD_ATTR_NAME]
>> + * [NET_FLOW_FIELD_ATTR_UID]
>> + * [NET_FLOW_FIELD_ATTR_BITWIDTH]
>> + * [NET_FLOW_HEADER_ATTR_FIELD]
>> + * [...]
>> + * [...]
>> + * Action definitions supported by tables
>> + *
>> + * [NET_FLOW_TABLE_ACTIONS]
>> + * [NET_FLOW_TABLE_ATTR_ACTIONS]
>> + * [NET_FLOW_ACTION]
>> + * [NET_FLOW_ACTION_ATTR_NAME]
>> + * [NET_FLOW_ACTION_ATTR_UID]
>> + * [NET_FLOW_ACTION_ATTR_SIGNATURE]
>> + * [NET_FLOW_ACTION_ARG]
> ..
>> + * Get Table Graph <Reply> description
>> + *
>> + * [NET_FLOW_TABLE_TABLE_GRAPH]
>> + * [TABLE_GRAPH_NODE]
>> + * [TABLE_GRAPH_NODE_UID]
>> + * [TABLE_GRAPH_NODE_JUMP]
>
> I think NET_FLOW prefix everywhere is too verbose.
> Especially since you've missed it in the above 3.
> and in patch 2 it is:
> NET_FLOW_FLOW
> which is kinda awkward.
> Can you abbreviate it to NFL_ or something else ?
hmm I'm open for a better name, NFL_ might work but seems
a bit cryptic to me. Maybe it is better than NET_FLOW.
Anyone other suggestions?
>
> I couldn't find get_headers() and get_header_graph()
> implementation on rocker side ?
It is in patch
[net-next PATCH v1 04/11] rocker: add pipeline model for rocker switch
+#ifdef CONFIG_NET_FLOW_TABLES
+ .ndo_flow_get_tables = rocker_get_tables,
+ .ndo_flow_get_headers = rocker_get_headers,
+ .ndo_flow_get_actions = rocker_get_actions,
+ .ndo_flow_get_tbl_graph = rocker_get_tgraph,
+ .ndo_flow_get_hdr_graph = rocker_get_hgraph,
+#endif
although v2 will address some good feedback and clean it up a bit.
> Could you describe how put_header_graph() will look like?
The signature for get_hdrs and get_hdrs_graph in my latest deck
(I'll push shortly still need to sort out the caching for
get_flows) look like this,
struct net_flow_hdr **(*ndo_flow_get_hdrs)(struct net_device *dev);
struct net_flow_hdr_node **(*ndo_flow_get_hdr_graph)(struct
net_device *dev)
I could then use the following signatures for put hdrs,
int (*ndo_flow_put_hdrs)(struct net_device *dev, struct net_flow_hdr
**hdrs);
int (*ndo_flow_put_hdrs_graph(struct net_device *dev, struct
net_flow_hdr_graph **graph);
If the user supplies a new set of hdrs via put_hdrs it would
invalidate the hdrs graph though so we could either smash those two
operations into one or require both to occur when the device is down but
not allow it to come up without a graph operation. Currently my
preference is to smash the above two ops to this,
> int (*ndo_flow_put_hdrs)(struct net_device *dev, struct net_flow_hdr **hdrs, struct net_flow_hdr_graph **graph);
I've gone back and forth on this, doing updates to the hdrs/graph
while the device is online doesn't seem practical. I don't have access
to any devices that would support this. If your device is a software
one though (futuristic eBPF-OVS) it may make some sense.
> When it comes to parsing I'm assuming that hw will fall
> into N categories:
> - that has get_headers() and get_header_graph() only
> which would mean fixed parser
right this is rocker and what the initial series is trying to
address.
> - above plus put_header_graph() which will allow to
> rearrange some fixed sized headers ?
OK but I'm not sure where/if these devices exist. Maybe your
thinking of a software dataplane case? Would get_headers return
some headers/fields but not include them in the graph and then
expect the user to build a graph with them if the user needs
them. Are there restrictions on how the graph can be built
out? I guess I'm working with the assumption that the device
returns a complete parse graph for all combinations it supports.
Are there really devices that could only support certain combinations
and then if you shuffled the headers graph around support others?
I'm just not aware of any device.
> - above plus put_header() ?
> I'm having a hard time envisioning how that would
> look like.
This case makes more sense to me. The user supplies the definition
of the headers and the graph showing how they are related and the
driver can program the parser to work correctly. This implies a
flexible parser but I think some devices could support this. You
would need some attributes to define depth of the parser and such
restrictions if the device has restrictions on the parsers that
can be supported.
Maybe one concrete example would be to introduce a header tag that
was previously unknown to the device. You could define it using
the header/fields (bit/length/offset) notation and then give the
graph to let the parser "know" where to expect it. Finally this
could be passed to the driver and the parser could be generated.
To be honest though I would really be happy getting the 1st option
working.
> - ... ?
>
> also can we change a name from add_flow
> to add_entry or add_rule ?
> I think 'rule' fits better, since rule = field_ref+action
> and one real TCP flow may need multiple rules
> inserted into table, right?
> The whole thing can still be called 'flow API'...
add_rule/del_rule fine by me.
>
> will there be a put_table_graph() ?
> probably not, right? since as soon as HW supports
> 'goto' aciton, the meaning of table_graph is lost and
> it's actually just a set of disconnected tables and the
> way to jump from one into another is through 'goto'.
hmm I have support in another tree for create/destroy table. This
allows users to create tables and destroy them. .
I think the table_graph is still relevant its just the graph
is completely connected. I'm not sure you will really see hardware
like this anytime soon though :) or maybe I just mean I haven't
seen any.
>
> I think OVS guys are quiet, since they're skeptical
> that headers+header_graph approach can work?
> Would be great if they can share the experience...
>
hmm maybe but I could define all the headers OVS supports using
this. And then define a linear array of tables. It might be an
interesting exercise to build this on top of rocker.
--
John Fastabend Intel Corporation
^ permalink raw reply
* [PATCH] sh-eth: Set fdr_value of R-Car SoCs
From: Nobuhiro Iwamatsu @ 2015-01-07 5:40 UTC (permalink / raw)
To: netdev; +Cc: yoshihiro.shimoda.uh, linux-sh, Nobuhiro Iwamatsu
FDR register of R-Car set in fdr_value can have the original settings.
This sets the value that is suitable for each SoCs to fdr_value of R8A777x
and R8A779x.
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 59ee457..62f2e88 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -473,6 +473,7 @@ static struct sh_eth_cpu_data r8a777x_data = {
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
EESR_ECI,
+ .fdr_value = 0x00000f0f,
.apr = 1,
.mpr = 1,
@@ -495,6 +496,7 @@ static struct sh_eth_cpu_data r8a779x_data = {
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
EESR_ECI,
+ .fdr_value = 0x00000f0f,
.apr = 1,
.mpr = 1,
--
2.1.3
^ permalink raw reply related
* Re: [PATCH net] ipv6: Prevent ipv6_find_hdr() from returning ENOENT for valid non-first fragments
From: Rahul Sharma @ 2015-01-07 5:41 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: netdev, linux-kernel, Hannes Frederic Sowa, netfilter-devel
In-Reply-To: <20150106224706.GA7416@salvia>
Hi Pablo,
On Wed, Jan 7, 2015 at 4:17 AM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Wed, Jan 07, 2015 at 03:03:20AM +0530, Rahul Sharma wrote:
>> ipv6_find_hdr() currently assumes that the next-header field in the
>> fragment header of the non-first fragment is the "protocol number of
>> the last header" (here last header excludes any extension header
>> protocol numbers ) which is incorrect as per RFC2460. The next-header
>> value is the first header of the fragmentable part of the original
>> packet (which can be extension header as well).
>> This can create reassembly problems. For example: Fragmented
>> authenticated OSPFv3 packets (where AH header is inserted before the
>> protocol header). For the second fragment, the next header value in
>> the fragment header will be NEXTHDR_AUTH which is correct but
>> ipv6_find_hdr will return ENOENT since AH is an extension header
>> resulting in second fragment getting dropped. This check for the
>> presence of non-extension header needs to be removed.
>>
>> Signed-off-by: Rahul Sharma <rsharma@arista.com>
>> ---
>> --- linux-3.18.1/net/ipv6/exthdrs_core.c.orig 2015-01-06
>> 10:25:36.411419863 -0800
>> +++ linux-3.18.1/net/ipv6/exthdrs_core.c 2015-01-06
>> 10:51:45.819364986 -0800
>> @@ -171,10 +171,11 @@ EXPORT_SYMBOL_GPL(ipv6_find_tlv);
>> * If the first fragment doesn't contain the final protocol header or
>> * NEXTHDR_NONE it is considered invalid.
>> *
>> - * Note that non-1st fragment is special case that "the protocol number
>> - * of last header" is "next header" field in Fragment header. In this case,
>> - * *offset is meaningless and fragment offset is stored in *fragoff if fragoff
>> - * isn't NULL.
>> + * Note that non-1st fragment is special case that "the protocol number of the
>> + * first header of the fragmentable part of the original packet" is
>> + * "next header" field in the Fragment header. In this case, *offset is
>> + * meaningless and fragment offset is stored in *fragoff if fragoff isn't
>> + * NULL.
>> *
>> * if flags is not NULL and it's a fragment, then the frag flag
>> * IP6_FH_F_FRAG will be set. If it's an AH header, the
>> @@ -250,9 +251,7 @@ int ipv6_find_hdr(const struct sk_buff *
>>
>> _frag_off = ntohs(*fp) & ~0x7;
>> if (_frag_off) {
>> - if (target < 0 &&
>> - ((!ipv6_ext_hdr(hp->nexthdr)) ||
>
> This check assumes that the following headers cannot show up in the
> fragmented part of the IPv6 packet:
>
> 12 bool ipv6_ext_hdr(u8 nexthdr)
> 13 {
> 14 /*
> 15 * find out if nexthdr is an extension header or a protocol
> 16 */
> 17 return (nexthdr == NEXTHDR_HOP) ||
> 18 (nexthdr == NEXTHDR_ROUTING) ||
> 19 (nexthdr == NEXTHDR_FRAGMENT) ||
> 20 (nexthdr == NEXTHDR_AUTH) ||
> 21 (nexthdr == NEXTHDR_NONE) ||
> 22 (nexthdr == NEXTHDR_DEST);
>
>> - hp->nexthdr == NEXTHDR_NONE)) {
>> + if (target < 0) {
>> if (fragoff)
>> *fragoff = _frag_off;
>> return hp->nexthdr;
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
I think this is incorrect. Authentication header shows up in the
fragmentable part of the original IPv6 packet. So, for the non-first
fragments the next-header field value can be NEXTHDR_AUTH.
Thanks
^ permalink raw reply
* [PATCH net-next v2 0/7] Involve rhashtable_lookup_insert routine
From: Ying Xue @ 2015-01-07 5:41 UTC (permalink / raw)
To: tgraf; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion, davem
The series aims to involve rhashtable_lookup_insert() to guarantee
that the process of lookup and insertion of an object from/into hash
table is finished atomically, allowing rhashtable's users not to
introduce an extra lock during search and insertion. For example,
tipc socket is the first user benefiting from this enhancement.
v2 changes:
- fix the issue of waking up worker thread under a wrong condition in
patch #2, which is pointed by Thomas.
- move a comment from rhashtable_inser() to rhashtable_wakeup_worker()
according to Thomas's suggestion in patch #2.
- indent the third line of condition statement in
rhashtable_wakeup_worker() to inner bracket in patch #2.
- drop patch #3 of v1 series
- fix an issue of being unable to remove an object from hash table in
certain special case in patch #4.
- involve a new patch #5 to avoid unnecessary wakeup for worker queue
thread
- involve a new patch #6 to initialize atomic "nelems" variable
- adjust "nelem_hint" value from 256 to 192 avoiding to unnecessarily
to shrink hash table from the beginning phase in patch #7.
v1 changes:
But before rhashtable_lookup_insert() is involved, the following
optimizations need to be first done:
- simplify rhashtable_lookup by reusing rhashtable_lookup_compare()
- introduce rhashtable_wakeup_worker() to further reduce duplicated
code in patch #2
- fix an issue in patch #3
- involve rhashtable_lookup_insert(). But in this version, we firstly
use rhashtable_lookup() to search duplicate key in both old and new
bucket table; secondly introduce another __rhashtable_insert() helper
function to reduce the duplicated code between rhashtable_insert()
and rhashtable_lookup_insert().
- add patch #5 into the series as it depends on above patches. But in
this version, no change is made comparing with its previous version.
Ying Xue (7):
rhashtable: optimize rhashtable_lookup routine
rhashtable: introduce rhashtable_wakeup_worker helper function
rhashtable: involve rhashtable_lookup_insert routine
rhashtable: future table needs to be traversed when remove an object
rhashtable: avoid unnecessary wakeup for worker queue
rhashtable: initialize atomic nelems variable
tipc: convert tipc reference table to use generic rhashtable
include/linux/rhashtable.h | 3 +-
lib/rhashtable.c | 182 +++++++++++------
net/tipc/Kconfig | 12 --
net/tipc/config.c | 24 +--
net/tipc/core.c | 10 +-
net/tipc/core.h | 3 -
net/tipc/socket.c | 480 ++++++++++++++++----------------------------
net/tipc/socket.h | 4 +-
8 files changed, 306 insertions(+), 412 deletions(-)
--
1.7.9.5
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
^ permalink raw reply
* [PATCH net-next v2 1/7] rhashtable: optimize rhashtable_lookup routine
From: Ying Xue @ 2015-01-07 5:41 UTC (permalink / raw)
To: tgraf; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion, davem
In-Reply-To: <1420609318-3261-1-git-send-email-ying.xue@windriver.com>
Define an internal compare function and relevant compare argument,
and then make use of rhashtable_lookup_compare() to lookup key in
hash table, reducing duplicated code between rhashtable_lookup()
and rhashtable_lookup_compare().
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Cc: Thomas Graf <tgraf@suug.ch>
Acked-by: Thomas Graf <tgraf@suug.ch>
---
lib/rhashtable.c | 41 ++++++++++++++++++-----------------------
1 file changed, 18 insertions(+), 23 deletions(-)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index cbad192..f2fdd7a 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -612,6 +612,19 @@ restart:
}
EXPORT_SYMBOL_GPL(rhashtable_remove);
+struct rhashtable_compare_arg {
+ struct rhashtable *ht;
+ const void *key;
+};
+
+static bool rhashtable_compare(void *ptr, void *arg)
+{
+ struct rhashtable_compare_arg *x = arg;
+ struct rhashtable *ht = x->ht;
+
+ return !memcmp(ptr + ht->p.key_offset, x->key, ht->p.key_len);
+}
+
/**
* rhashtable_lookup - lookup key in hash table
* @ht: hash table
@@ -627,32 +640,14 @@ EXPORT_SYMBOL_GPL(rhashtable_remove);
*/
void *rhashtable_lookup(struct rhashtable *ht, const void *key)
{
- const struct bucket_table *tbl, *old_tbl;
- struct rhash_head *he;
- u32 hash;
+ struct rhashtable_compare_arg arg = {
+ .ht = ht,
+ .key = key,
+ };
BUG_ON(!ht->p.key_len);
- rcu_read_lock();
- old_tbl = rht_dereference_rcu(ht->tbl, ht);
- tbl = rht_dereference_rcu(ht->future_tbl, ht);
- hash = key_hashfn(ht, key, ht->p.key_len);
-restart:
- rht_for_each_rcu(he, tbl, rht_bucket_index(tbl, hash)) {
- if (memcmp(rht_obj(ht, he) + ht->p.key_offset, key,
- ht->p.key_len))
- continue;
- rcu_read_unlock();
- return rht_obj(ht, he);
- }
-
- if (unlikely(tbl != old_tbl)) {
- tbl = old_tbl;
- goto restart;
- }
-
- rcu_read_unlock();
- return NULL;
+ return rhashtable_lookup_compare(ht, key, &rhashtable_compare, &arg);
}
EXPORT_SYMBOL_GPL(rhashtable_lookup);
--
1.7.9.5
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
^ permalink raw reply related
* [PATCH net-next v2 2/7] rhashtable: introduce rhashtable_wakeup_worker helper function
From: Ying Xue @ 2015-01-07 5:41 UTC (permalink / raw)
To: tgraf; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion, davem
In-Reply-To: <1420609318-3261-1-git-send-email-ying.xue@windriver.com>
Introduce rhashtable_wakeup_worker() helper function to reduce
duplicated code where to wake up worker.
By the way, as long as the both "future_tbl" and "tbl" bucket table
pointers point to the same bucket array, we should try to wake up
the resizing worker thread, otherwise, it indicates the work of
resizing hash table is not finished yet. However, currently we will
wake up the worker thread only when the two pointers point to
different bucket array. Obviously this is wrong. So, the issue is
also fixed as well in the patch.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Cc: Thomas Graf <tgraf@suug.ch>
---
lib/rhashtable.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index f2fdd7a..2000685 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -492,6 +492,19 @@ static void rht_deferred_worker(struct work_struct *work)
mutex_unlock(&ht->mutex);
}
+static void rhashtable_wakeup_worker(struct rhashtable *ht)
+{
+ struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht);
+ struct bucket_table *new_tbl = rht_dereference_rcu(ht->future_tbl, ht);
+ size_t size = tbl->size;
+
+ /* Only adjust the table if no resizing is currently in progress. */
+ if (tbl == new_tbl &&
+ ((ht->p.grow_decision && ht->p.grow_decision(ht, size)) ||
+ (ht->p.shrink_decision && ht->p.shrink_decision(ht, size))))
+ schedule_delayed_work(&ht->run_work, 0);
+}
+
/**
* rhashtable_insert - insert object into hash hash table
* @ht: hash table
@@ -532,10 +545,7 @@ void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj)
atomic_inc(&ht->nelems);
- /* Only grow the table if no resizing is currently in progress. */
- if (ht->tbl != ht->future_tbl &&
- ht->p.grow_decision && ht->p.grow_decision(ht, tbl->size))
- schedule_delayed_work(&ht->run_work, 0);
+ rhashtable_wakeup_worker(ht);
rcu_read_unlock();
}
@@ -584,10 +594,7 @@ restart:
spin_unlock_bh(lock);
- if (ht->tbl != ht->future_tbl &&
- ht->p.shrink_decision &&
- ht->p.shrink_decision(ht, tbl->size))
- schedule_delayed_work(&ht->run_work, 0);
+ rhashtable_wakeup_worker(ht);
rcu_read_unlock();
--
1.7.9.5
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
^ permalink raw reply related
* [PATCH net-next v2 4/7] rhashtable: future table needs to be traversed when remove an object
From: Ying Xue @ 2015-01-07 5:41 UTC (permalink / raw)
To: tgraf; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion, davem
In-Reply-To: <1420609318-3261-1-git-send-email-ying.xue@windriver.com>
When remove an object from hash table, we currently only traverse old
bucket table to check whether the object exists. If the object is not
found in it, we will try again. But in the second search loop, we still
search the object from the old table instead of future table. As a
result, the object may be not removed from hash table especially when
resizing is currently in progress and the object is just saved in the
future table.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Cc: Thomas Graf <tgraf@suug.ch>
---
lib/rhashtable.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 4430233..1aef942 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -608,10 +608,10 @@ restart:
return true;
}
- if (tbl != rht_dereference_rcu(ht->tbl, ht)) {
+ if (tbl != rht_dereference_rcu(ht->future_tbl, ht)) {
spin_unlock_bh(lock);
- tbl = rht_dereference_rcu(ht->tbl, ht);
+ tbl = rht_dereference_rcu(ht->future_tbl, ht);
hash = head_hashfn(ht, tbl, obj);
lock = bucket_lock(tbl, hash);
--
1.7.9.5
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
^ permalink raw reply related
* [PATCH net-next v2 5/7] rhashtable: avoid unnecessary wakeup for worker queue
From: Ying Xue @ 2015-01-07 5:41 UTC (permalink / raw)
To: tgraf; +Cc: jon.maloy, netdev, Paul.Gortmaker, tipc-discussion, davem
In-Reply-To: <1420609318-3261-1-git-send-email-ying.xue@windriver.com>
Move condition statements of verifying whether hash table size exceeds
its maximum threshold or reaches its minimum threshold from resizing
functions to resizing decision functions, avoiding unnecessary wakeup
for worker queue thread.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Cc: Thomas Graf <tgraf@suug.ch>
---
include/linux/rhashtable.h | 2 +-
lib/rhashtable.c | 18 +++++++-----------
2 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 73c913f..326acd8 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -113,7 +113,7 @@ struct rhashtable {
struct bucket_table __rcu *tbl;
struct bucket_table __rcu *future_tbl;
atomic_t nelems;
- size_t shift;
+ atomic_t shift;
struct rhashtable_params p;
struct delayed_work run_work;
struct mutex mutex;
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 1aef942..7fb474b 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -199,7 +199,8 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht,
bool rht_grow_above_75(const struct rhashtable *ht, size_t new_size)
{
/* Expand table when exceeding 75% load */
- return atomic_read(&ht->nelems) > (new_size / 4 * 3);
+ return atomic_read(&ht->nelems) > (new_size / 4 * 3) &&
+ (ht->p.max_shift && atomic_read(&ht->shift) < ht->p.max_shift);
}
EXPORT_SYMBOL_GPL(rht_grow_above_75);
@@ -211,7 +212,8 @@ EXPORT_SYMBOL_GPL(rht_grow_above_75);
bool rht_shrink_below_30(const struct rhashtable *ht, size_t new_size)
{
/* Shrink table beneath 30% load */
- return atomic_read(&ht->nelems) < (new_size * 3 / 10);
+ return atomic_read(&ht->nelems) < (new_size * 3 / 10) &&
+ (atomic_read(&ht->shift) > ht->p.min_shift);
}
EXPORT_SYMBOL_GPL(rht_shrink_below_30);
@@ -318,14 +320,11 @@ int rhashtable_expand(struct rhashtable *ht)
ASSERT_RHT_MUTEX(ht);
- if (ht->p.max_shift && ht->shift >= ht->p.max_shift)
- return 0;
-
new_tbl = bucket_table_alloc(ht, old_tbl->size * 2);
if (new_tbl == NULL)
return -ENOMEM;
- ht->shift++;
+ atomic_inc(&ht->shift);
/* Make insertions go into the new, empty table right away. Deletions
* and lookups will be attempted in both tables until we synchronize.
@@ -421,9 +420,6 @@ int rhashtable_shrink(struct rhashtable *ht)
ASSERT_RHT_MUTEX(ht);
- if (ht->shift <= ht->p.min_shift)
- return 0;
-
new_tbl = bucket_table_alloc(ht, tbl->size / 2);
if (new_tbl == NULL)
return -ENOMEM;
@@ -462,7 +458,7 @@ int rhashtable_shrink(struct rhashtable *ht)
/* Publish the new, valid hash table */
rcu_assign_pointer(ht->tbl, new_tbl);
- ht->shift--;
+ atomic_dec(&ht->shift);
/* Wait for readers. No new readers will have references to the
* old hash table.
@@ -851,7 +847,7 @@ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params)
if (tbl == NULL)
return -ENOMEM;
- ht->shift = ilog2(tbl->size);
+ atomic_set(&ht->shift, ilog2(tbl->size));
RCU_INIT_POINTER(ht->tbl, tbl);
RCU_INIT_POINTER(ht->future_tbl, tbl);
--
1.7.9.5
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
^ permalink raw reply related
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