diff mbox

[v3,07/13] net: ethernet: ti: cpts: clean up event list if event pool is empty

Message ID 20161202203023.25526-8-grygorii.strashko@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Grygorii Strashko Dec. 2, 2016, 8:30 p.m. UTC
From: WingMan Kwok <w-kwok2@ti.com>

When a CPTS user does not exit gracefully by disabling cpts
timestamping and leaving a joined multicast group, the system
continues to receive and timestamps the ptp packets which eventually
occupy all the event list entries.  When this happns, the added code
tries to remove some list entries which are expired.

Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
 drivers/net/ethernet/ti/cpts.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

Comments

kernel test robot Dec. 4, 2016, 6:09 a.m. UTC | #1
Hi WingMan,

[auto build test ERROR on net/master]
[also build test ERROR on v4.9-rc7 next-20161202]
[cannot apply to net-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Grygorii-Strashko/net-ethernet-ti-cpts-switch-to-readl-writel_relaxed/20161204-010355
config: arm-omap2plus_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

Note: the linux-review/Grygorii-Strashko/net-ethernet-ti-cpts-switch-to-readl-writel_relaxed/20161204-010355 HEAD f938805dce662197c057c75ac67849f60da87c9f builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   In file included from include/linux/dma-mapping.h:6:0,
                    from include/linux/skbuff.h:34,
                    from include/linux/ip.h:20,
                    from include/linux/ptp_classify.h:26,
                    from drivers/net/ethernet/ti/cpts.c:25:
   drivers/net/ethernet/ti/cpts.c: In function 'cpts_purge_events':
>> drivers/net/ethernet/ti/cpts.c:76:15: error: 'struct cpts' has no member named 'dev'
      dev_dbg(cpts->dev, "cpts: event pool cleaned up %d\n", removed);
                  ^
   include/linux/device.h:1209:26: note: in definition of macro 'dev_dbg'
      dev_printk(KERN_DEBUG, dev, format, ##arg); \
                             ^~~
   drivers/net/ethernet/ti/cpts.c: In function 'cpts_fifo_read':
   drivers/net/ethernet/ti/cpts.c:94:16: error: 'struct cpts' has no member named 'dev'
       dev_err(cpts->dev, "cpts: event pool empty\n");
                   ^~

vim +76 drivers/net/ethernet/ti/cpts.c

    19	 */
    20	#include <linux/err.h>
    21	#include <linux/if.h>
    22	#include <linux/hrtimer.h>
    23	#include <linux/module.h>
    24	#include <linux/net_tstamp.h>
  > 25	#include <linux/ptp_classify.h>
    26	#include <linux/time.h>
    27	#include <linux/uaccess.h>
    28	#include <linux/workqueue.h>
    29	#include <linux/if_ether.h>
    30	#include <linux/if_vlan.h>
    31	
    32	#include "cpts.h"
    33	
    34	#define cpts_read32(c, r)	readl_relaxed(&c->reg->r)
    35	#define cpts_write32(c, v, r)	writel_relaxed(v, &c->reg->r)
    36	
    37	static int event_expired(struct cpts_event *event)
    38	{
    39		return time_after(jiffies, event->tmo);
    40	}
    41	
    42	static int event_type(struct cpts_event *event)
    43	{
    44		return (event->high >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
    45	}
    46	
    47	static int cpts_fifo_pop(struct cpts *cpts, u32 *high, u32 *low)
    48	{
    49		u32 r = cpts_read32(cpts, intstat_raw);
    50	
    51		if (r & TS_PEND_RAW) {
    52			*high = cpts_read32(cpts, event_high);
    53			*low  = cpts_read32(cpts, event_low);
    54			cpts_write32(cpts, EVENT_POP, event_pop);
    55			return 0;
    56		}
    57		return -1;
    58	}
    59	
    60	static int cpts_purge_events(struct cpts *cpts)
    61	{
    62		struct list_head *this, *next;
    63		struct cpts_event *event;
    64		int removed = 0;
    65	
    66		list_for_each_safe(this, next, &cpts->events) {
    67			event = list_entry(this, struct cpts_event, list);
    68			if (event_expired(event)) {
    69				list_del_init(&event->list);
    70				list_add(&event->list, &cpts->pool);
    71				++removed;
    72			}
    73		}
    74	
    75		if (removed)
  > 76			dev_dbg(cpts->dev, "cpts: event pool cleaned up %d\n", removed);
    77		return removed ? 0 : -1;
    78	}
    79	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index d3c1ac5..8266459 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -57,6 +57,26 @@  static int cpts_fifo_pop(struct cpts *cpts, u32 *high, u32 *low)
 	return -1;
 }
 
+static int cpts_purge_events(struct cpts *cpts)
+{
+	struct list_head *this, *next;
+	struct cpts_event *event;
+	int removed = 0;
+
+	list_for_each_safe(this, next, &cpts->events) {
+		event = list_entry(this, struct cpts_event, list);
+		if (event_expired(event)) {
+			list_del_init(&event->list);
+			list_add(&event->list, &cpts->pool);
+			++removed;
+		}
+	}
+
+	if (removed)
+		dev_dbg(cpts->dev, "cpts: event pool cleaned up %d\n", removed);
+	return removed ? 0 : -1;
+}
+
 /*
  * Returns zero if matching event type was found.
  */
@@ -69,10 +89,12 @@  static int cpts_fifo_read(struct cpts *cpts, int match)
 	for (i = 0; i < CPTS_FIFO_DEPTH; i++) {
 		if (cpts_fifo_pop(cpts, &hi, &lo))
 			break;
-		if (list_empty(&cpts->pool)) {
-			pr_err("cpts: event pool is empty\n");
+
+		if (list_empty(&cpts->pool) && cpts_purge_events(cpts)) {
+			dev_err(cpts->dev, "cpts: event pool empty\n");
 			return -1;
 		}
+
 		event = list_first_entry(&cpts->pool, struct cpts_event, list);
 		event->tmo = jiffies + 2;
 		event->high = hi;