Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 01/10] rxrpc: Make sure we initialise the peer hash key
From: David Howells @ 2016-09-13 22:21 UTC (permalink / raw)
  To: netdev; +Cc: dhowells, linux-afs, linux-kernel
In-Reply-To: <147380525614.23135.7539695651371953351.stgit@warthog.procyon.org.uk>

Peer records created for incoming connections weren't getting their hash
key set.  This meant that incoming calls wouldn't see more than one DATA
packet - which is not a problem for AFS CM calls with small request data
blobs.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 net/rxrpc/peer_object.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c
index 2efe29a4c232..3e6cd174b53d 100644
--- a/net/rxrpc/peer_object.c
+++ b/net/rxrpc/peer_object.c
@@ -203,6 +203,7 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)
  */
 static void rxrpc_init_peer(struct rxrpc_peer *peer, unsigned long hash_key)
 {
+	peer->hash_key = hash_key;
 	rxrpc_assess_MTU_size(peer);
 	peer->mtu = peer->if_mtu;
 
@@ -238,7 +239,6 @@ static struct rxrpc_peer *rxrpc_create_peer(struct rxrpc_local *local,
 
 	peer = rxrpc_alloc_peer(local, gfp);
 	if (peer) {
-		peer->hash_key = hash_key;
 		memcpy(&peer->srx, srx, sizeof(*srx));
 		rxrpc_init_peer(peer, hash_key);
 	}

^ permalink raw reply related

* [PATCH net-next 00/10] rxrpc: Miscellaneous fixes
From: David Howells @ 2016-09-13 22:20 UTC (permalink / raw)
  To: netdev; +Cc: dhowells, linux-afs, linux-kernel


Here's a set of miscellaneous fix patches.  There are a couple of points of
note:

 (1) There is one non-fix patch that adjusts the call ref tracking
     tracepoint to make kernel API-held refs on calls more obvious.  This
     is a prerequisite for the patch that fixes prealloc refcounting.

 (2) The final patch alters how jumbo packets that partially exceed the
     receive window are handled.  Previously, space was being left in the
     Rx buffer for them, but this significantly hurts performance as the Rx
     window can't be increased to match the OpenAFS Tx window size.

     Instead, the excess subpackets are discarded and an EXCEEDS_WINDOW ACK
     is generated for the first.  To avoid the problem of someone trying to
     run the kernel out of space by feeding the kernel a series of
     overlapping maximal jumbo packets, we stop allowing jumbo packets on a
     call if we encounter more than three jumbo packets with duplicate or
     excessive subpackets.

The patches can be found here also (non-terminally on the branch):

	http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=rxrpc-rewrite

Tagged thusly:

	git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git
	rxrpc-rewrite-20160913-1

David
---
David Howells (10):
      rxrpc: Make sure we initialise the peer hash key
      rxrpc: Add missing wakeup on Tx window rotation
      rxrpc: The IDLE ACK packet should use rxrpc_idle_ack_delay
      rxrpc: Requeue call for recvmsg if more data
      rxrpc: Add missing unlock in rxrpc_call_accept()
      rxrpc: Use skb->len not skb->data_len
      rxrpc: Allow tx_winsize to grow in response to an ACK
      rxrpc: Adjust the call ref tracepoint to show kernel API refs
      rxrpc: Fix prealloc refcounting
      rxrpc: Correctly initialise, limit and transmit call->rx_winsize


 net/rxrpc/af_rxrpc.c    |    2 +-
 net/rxrpc/ar-internal.h |    5 ++++-
 net/rxrpc/call_accept.c |   20 +++++++++++++++-----
 net/rxrpc/call_event.c  |    2 +-
 net/rxrpc/call_object.c |    7 +++----
 net/rxrpc/input.c       |   41 +++++++++++++++++++++++++++--------------
 net/rxrpc/misc.c        |    5 ++++-
 net/rxrpc/output.c      |    4 ++--
 net/rxrpc/peer_object.c |    2 +-
 net/rxrpc/recvmsg.c     |    5 +++++
 net/rxrpc/sysctl.c      |    2 +-
 11 files changed, 64 insertions(+), 31 deletions(-)

^ permalink raw reply

* Re: [PATCH net-next 2/2] net: deprecate eth_change_mtu, remove usage
From: kbuild test robot @ 2016-09-13 21:59 UTC (permalink / raw)
  To: Jarod Wilson
  Cc: kbuild-all, linux-kernel, Jarod Wilson, David S. Miller, netdev
In-Reply-To: <20160912201106.47837-3-jarod@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 3404 bytes --]

Hi Jarod,

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Jarod-Wilson/net-centralize-net_device-min-max-MTU-checking/20160913-042130
config: mips-xway_defconfig (attached as .config)
compiler: mips-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
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=mips 

All error/warnings (new ones prefixed by >>):

   drivers/net/ethernet/lantiq_etop.c: In function 'ltq_etop_change_mtu':
>> drivers/net/ethernet/lantiq_etop.c:524:7: error: 'ret' undeclared (first use in this function)
     if (!ret) {
          ^
   drivers/net/ethernet/lantiq_etop.c:524:7: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/net/ethernet/lantiq_etop.c:534:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^

vim +/ret +524 drivers/net/ethernet/lantiq_etop.c

504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  518  
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  519  static int
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  520  ltq_etop_change_mtu(struct net_device *dev, int new_mtu)
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  521  {
707d312a drivers/net/ethernet/lantiq_etop.c Jarod Wilson 2016-09-12  522  	dev->mtu = new_mtu;
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  523  
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06 @524  	if (!ret) {
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  525  		struct ltq_etop_priv *priv = netdev_priv(dev);
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  526  		unsigned long flags;
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  527  
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  528  		spin_lock_irqsave(&priv->lock, flags);
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  529  		ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu,
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  530  			LTQ_ETOP_IGPLEN);
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  531  		spin_unlock_irqrestore(&priv->lock, flags);
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  532  	}
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  533  	return ret;
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06 @534  }
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  535  
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  536  static int
504d4721 drivers/net/lantiq_etop.c          John Crispin 2011-05-06  537  ltq_etop_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)

:::::: The code at line 524 was first introduced by commit
:::::: 504d4721ee8e432af4b5f196a08af38bc4dac5fe MIPS: Lantiq: Add ethernet driver

:::::: TO: John Crispin <blogic@openwrt.org>
:::::: CC: Ralf Baechle <ralf@linux-mips.org>

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

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 13885 bytes --]

^ permalink raw reply

* Re: [Intel-wired-lan] [net-next PATCH v3 2/3] e1000: add initial XDP support
From: Alexei Starovoitov @ 2016-09-13 21:52 UTC (permalink / raw)
  To: Rustad, Mark D
  Cc: Eric Dumazet, Tom Herbert, Brenden Blanco,
	Linux Kernel Network Developers, intel-wired-lan,
	Jesper Dangaard Brouer, Cong Wang, David S. Miller, William Tu
In-Reply-To: <AB6E7248-F1A3-4C9C-9249-7F25E51BA1E4@intel.com>

On Tue, Sep 13, 2016 at 07:14:27PM +0000, Rustad, Mark D wrote:
> Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> 
> >On Tue, Sep 13, 2016 at 06:28:03PM +0000, Rustad, Mark D wrote:
> >>Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >>
> >>>I've looked through qemu and it appears only emulate e1k and tg3.
> >>>The latter is still used in the field, so the risk of touching
> >>>it is higher.
> >>
> >>I have no idea what makes you think that e1k is *not* "used in the field".
> >>I grant you it probably is used more virtualized than not these days,
> >>but it
> >>certainly exists and is used. You can still buy them new at Newegg for
> >>goodness sakes!
> >
> >the point that it's only used virtualized, since PCI (not PCIE) have
> >been long dead.
> 
> My point is precisely the opposite. It is a real device, it exists in real
> systems and it is used in those systems. I worked on embedded systems that
> ran Linux and used e1000 devices. I am sure they are still out there because
> customers are still paying for support of those systems.
> 
> Yes, PCI(-X) is absent from any current hardware and has been for some years
> now, but there is an installed base that continues. What part of that
> installed base updates software? I don't know, but I would not just assume
> that it is 0. I know that I updated the kernel on those embedded systems
> that I worked on when I was supporting them. Never at the bleeding edge, but
> generally hopping from one LTS kernel to another as needed.

I suspect modern linux won't boot on such old pci only systems for other
reasons not related to networking, since no one really cares to test kernels there.
So I think we mostly agree. There is chance that this xdp e1k code will
find a way to that old system. What are the chances those users will
be using xdp there? I think pretty close to zero.

The pci-e nics integrated into motherboards that pretend to be tg3
(though they're not at all build by broadcom) are significantly more common.
That's why I picked e1k instead of tg3.

Also note how this patch is not touching anything in the main e1k path
(because I don't have a hw to test and I suspect Intel's driver team
doesn't have it either) to make sure there is no breakage on those
old systems. I created separate e1000_xmit_raw_frame() routine
instead of adding flags into e1000_xmit_frame() for the same reasons:
to make sure there is no breakage.
Same reasoning for not doing an union of page/skb as Alexander suggested.
I wanted minimal change to e1k that allows development xdp programs in kvm
without affecting e1k main path. If you see the actual bug in the patch,
please point out the line.

^ permalink raw reply

* [PATCH] MAINTAINERS: Remove myself from PA Semi entries
From: Olof Johansson @ 2016-09-13 21:48 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: netdev, linux-i2c, davem, jdelvare, Olof Johansson

The platform is old, very few users and I lack bandwidth to keep after
it these days.

Mark the base platform as well as the drivers as orphans, patches have
been flowing through the fallback maintainers for a while already.

Signed-off-by: Olof Johansson <olof@lixom.net>
---

Jean, Dave,

I was hoping to have Michael merge this since the bulk of the platform is under him,
cc:ing you mostly to be aware that I am orphaning a driver in your subsystems.


Thanks,

-Olof

 MAINTAINERS | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index d8e81b1..411f4f7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7155,9 +7155,8 @@ F:	arch/powerpc/platforms/83xx/
 F:	arch/powerpc/platforms/85xx/
 
 LINUX FOR POWERPC PA SEMI PWRFICIENT
-M:	Olof Johansson <olof@lixom.net>
 L:	linuxppc-dev@lists.ozlabs.org
-S:	Maintained
+S:	Orphan
 F:	arch/powerpc/platforms/pasemi/
 F:	drivers/*/*pasemi*
 F:	drivers/*/*/*pasemi*
@@ -8849,15 +8848,13 @@ S:	Maintained
 F:	drivers/net/wireless/intersil/p54/
 
 PA SEMI ETHERNET DRIVER
-M:	Olof Johansson <olof@lixom.net>
 L:	netdev@vger.kernel.org
-S:	Maintained
+S:	Orphan
 F:	drivers/net/ethernet/pasemi/*
 
 PA SEMI SMBUS DRIVER
-M:	Olof Johansson <olof@lixom.net>
 L:	linux-i2c@vger.kernel.org
-S:	Maintained
+S:	Orphan
 F:	drivers/i2c/busses/i2c-pasemi.c
 
 PADATA PARALLEL EXECUTION MECHANISM
-- 
2.8.0.rc3.29.gb552ff8

^ permalink raw reply related

* Re: [PATCH net-next] openvswitch: avoid deferred execution of recirc actions
From: pravin shelar @ 2016-09-13 20:52 UTC (permalink / raw)
  To: Lance Richardson; +Cc: Linux Kernel Network Developers, ovs dev, sramamur
In-Reply-To: <1473775734-27382-1-git-send-email-lrichard@redhat.com>

On Tue, Sep 13, 2016 at 7:08 AM, Lance Richardson <lrichard@redhat.com> wrote:
> The ovs kernel data path currently defers the execution of all
> recirc actions until stack utilization is at a minimum.
> This is too limiting for some packet forwarding scenarios due to
> the small size of the deferred action FIFO (10 entries). For
> example, broadcast traffic sent out more than 10 ports with
> recirculation results in packet drops when the deferred action
> FIFO becomes full, as reported here:
>
>      http://openvswitch.org/pipermail/dev/2016-March/067672.html
>
> Since the current recursion depth is available (it is already tracked
> by the exec_actions_level pcpu variable), we can use it to determine
> whether to execute recirculation actions immediately (safe when
> recursion depth is low) or defer execution until more stack space is
> available.
>
> With this change, the deferred action fifo size becomes a non-issue
> for currently failing scenarios because it is no longer used when
> there are three or fewer recursions through ovs_execute_actions().
>
> Suggested-by: Pravin Shelar <pshelar@ovn.org>
> Signed-off-by: Lance Richardson <lrichard@redhat.com>

Thanks for working on it.

Acked-by: Pravin B Shelar <pshelar@ovn.org>

^ permalink raw reply

* Re: [PATCH v2 6/6] selftests: move watchdog tests from Documentation/watchdog
From: Timur Tabi @ 2016-09-13 20:52 UTC (permalink / raw)
  To: Shuah Khan, corbet-T1hC0tSOHrs,
	richardcochran-Re5JQEeQqe8AvxtiuMwx3w, wim-IQzOog9fTRqzQB+pC5nmwQ,
	linux-0h96xk9xTtrk1uMJSBkQmQ, nab-IzHhD5pYlfBP7FQvKIMDCQ,
	maheshkhanwalkar-Re5JQEeQqe8AvxtiuMwx3w, arnd-r2nGTMty4D4,
	ghackmann-hpIqsD4AKlfQT0dZR+AlfA, ben-/+tVBieCtBitmTQ+vhA3Yw,
	thuth-H+wXaHxf7aLQT0dZR+AlfA,
	christopher.s.hall-ral2JQCrhuEAvxtiuMwx3w,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8,
	mpe-Gsx/Oe8HsFggBc27wqDAHg, jani.nikula-VuQAYsv1563Yd54FQh9/CA
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	linux-kselftest-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <3eb32f56-eac7-e0ca-0bcf-90488cbff458-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>

Shuah Khan wrote:
> Is watchdog-simple a test or a sample/example? I thought this
> is an example, and planning to move that under examples?
>
> If this is a test, I will re-do the patch to include it.

I guess it's really just a sample.

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 6/6] selftests: move watchdog tests from Documentation/watchdog
From: Shuah Khan @ 2016-09-13 20:48 UTC (permalink / raw)
  To: Timur Tabi, corbet-T1hC0tSOHrs,
	richardcochran-Re5JQEeQqe8AvxtiuMwx3w, wim-IQzOog9fTRqzQB+pC5nmwQ,
	linux-0h96xk9xTtrk1uMJSBkQmQ, nab-IzHhD5pYlfBP7FQvKIMDCQ,
	maheshkhanwalkar-Re5JQEeQqe8AvxtiuMwx3w, arnd-r2nGTMty4D4,
	ghackmann-hpIqsD4AKlfQT0dZR+AlfA, ben-/+tVBieCtBitmTQ+vhA3Yw,
	thuth-H+wXaHxf7aLQT0dZR+AlfA,
	christopher.s.hall-ral2JQCrhuEAvxtiuMwx3w,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8,
	mpe-Gsx/Oe8HsFggBc27wqDAHg, jani.nikula-VuQAYsv1563Yd54FQh9/CA
  Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	linux-kselftest-u79uwXL29TY76Z2rM5mHXA, Shuah Khan
In-Reply-To: <57D8628D.3070507-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

On 09/13/2016 02:33 PM, Timur Tabi wrote:
> Shuah Khan wrote:
>> Remove watchdog-test from Makefile to move the test to selftests.
>>
>> Add Makefile and .gitignore to for watchdog-test. watchdog-test will
> 
> to for?

Thanks - will fix that.

> 
>> not be run as part of selftests suite and will not be included in
>> install targets.  It can be built separately for now.
>>
>> Signed-off-by: Shuah Khan <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
>> ---
>>   Documentation/watchdog/src/.gitignore            |   1 -
>>   Documentation/watchdog/src/Makefile              |   2 +-
>>   Documentation/watchdog/src/watchdog-test.c       | 105 -----------------------
>>   tools/testing/selftests/watchdog/.gitignore      |   1 +
>>   tools/testing/selftests/watchdog/Makefile        |   8 ++
>>   tools/testing/selftests/watchdog/watchdog-test.c | 105 +++++++++++++++++++++++
> 
> Please use -M when calling git-format-patch

okay.

> 
>>   6 files changed, 115 insertions(+), 107 deletions(-)
>>   delete mode 100644 Documentation/watchdog/src/watchdog-test.c
>>   create mode 100644 tools/testing/selftests/watchdog/.gitignore
>>   create mode 100644 tools/testing/selftests/watchdog/Makefile
>>   create mode 100644 tools/testing/selftests/watchdog/watchdog-test.c
>>
>> diff --git a/Documentation/watchdog/src/.gitignore b/Documentation/watchdog/src/.gitignore
>> index ac90997..ff0ebb5 100644
>> --- a/Documentation/watchdog/src/.gitignore
>> +++ b/Documentation/watchdog/src/.gitignore
>> @@ -1,2 +1 @@
>>   watchdog-simple
>> -watchdog-test
> 
> Why not also watchdog-simple?
> 

Is watchdog-simple a test or a sample/example? I thought this
is an example, and planning to move that under examples?

If this is a test, I will re-do the patch to include it.

thanks,
-- Shuah

--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 6/6] selftests: move watchdog tests from Documentation/watchdog
From: Timur Tabi @ 2016-09-13 20:33 UTC (permalink / raw)
  To: Shuah Khan, corbet, richardcochran, wim, linux, nab,
	maheshkhanwalkar, arnd, ghackmann, ben, thuth, christopher.s.hall,
	john.stultz, sergei.shtylyov, mpe, jani.nikula
  Cc: linux-doc, linux-kernel, netdev, linux-watchdog, linux-kselftest
In-Reply-To: <328de4c08ef23fe13cec88b45e3e1725cfc5c33b.1473795601.git.shuahkh@osg.samsung.com>

Shuah Khan wrote:
> Remove watchdog-test from Makefile to move the test to selftests.
>
> Add Makefile and .gitignore to for watchdog-test. watchdog-test will

to for?

> not be run as part of selftests suite and will not be included in
> install targets.  It can be built separately for now.
>
> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
> ---
>   Documentation/watchdog/src/.gitignore            |   1 -
>   Documentation/watchdog/src/Makefile              |   2 +-
>   Documentation/watchdog/src/watchdog-test.c       | 105 -----------------------
>   tools/testing/selftests/watchdog/.gitignore      |   1 +
>   tools/testing/selftests/watchdog/Makefile        |   8 ++
>   tools/testing/selftests/watchdog/watchdog-test.c | 105 +++++++++++++++++++++++

Please use -M when calling git-format-patch

>   6 files changed, 115 insertions(+), 107 deletions(-)
>   delete mode 100644 Documentation/watchdog/src/watchdog-test.c
>   create mode 100644 tools/testing/selftests/watchdog/.gitignore
>   create mode 100644 tools/testing/selftests/watchdog/Makefile
>   create mode 100644 tools/testing/selftests/watchdog/watchdog-test.c
>
> diff --git a/Documentation/watchdog/src/.gitignore b/Documentation/watchdog/src/.gitignore
> index ac90997..ff0ebb5 100644
> --- a/Documentation/watchdog/src/.gitignore
> +++ b/Documentation/watchdog/src/.gitignore
> @@ -1,2 +1 @@
>   watchdog-simple
> -watchdog-test

Why not also watchdog-simple?



-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* Re: [PATCH v3] net: ip, diag -- Add diag interface for raw sockets
From: Greg @ 2016-09-13 20:32 UTC (permalink / raw)
  To: Rustad, Mark D
  Cc: Cyrill Gorcunov, Linux Kernel Network Developers, LKML,
	David Miller, dsa@cumulusnetworks.com, eric.dumazet@gmail.com,
	kuznet@ms2.inr.ac.ru, jmorris@namei.org, yoshfuji@linux-ipv6.org,
	kaber@trash.net, avagin@openvz.org, stephen@networkplumber.org
In-Reply-To: <69DF2AA5-F813-476F-BB10-B3CB35656512@intel.com>

On Tue, 2016-09-13 at 20:18 +0000, Rustad, Mark D wrote:
> Greg <gvrose8192@gmail.com> wrote:
> 
> > Someday Linux will be a modern OS that just includes IPV6 and forces a
> > config option to NOT have it.
> >
> > That'll be great.  All the IS_ENABLED_(CONFIG_IPV6) scattered everywhere
> > is nuts.
> >
> > </editorial comment>
> 
> Better wait until everyone at least *has* IPv6! I have yet to have IPv6  
> deployed on any of my employer's networks or get IPv6 service from any ISP  
> at my home. When I was at Apple in the 90's I was told that Apple needed  
> IPv6 by next year or "we were dead". Well Apple nearly died, but IPv6 had  
> nothing to do with that! And I still haven't experienced an IPv6  
> deployment! Yeah, I have run it a bit point-to-point to resolve technical  
> issues, but that isn't a "deployment" and not very interesting.
> 
> As much as we would like things to move faster, much of the world just  
> doesn't. Witness the e1000 discussion today for example. Hardware doesn't  
> vanish overnight, and I know that my ISP has a network full of CPE that  
> doesn't do IPv6, so I'm not expecting their status to change any time soon.

Well that's why we can have a configuration to turn it off...

But yeah.  /pipedream

- Greg

> 
> It would be great though.
> </pipedream>
> 
> --
> Mark Rustad, Networking Division, Intel Corporation

^ permalink raw reply

* [PATCH v2 3/6] selftests: move ptp tests from Documentation/ptp
From: Shuah Khan @ 2016-09-13 20:18 UTC (permalink / raw)
  To: corbet, richardcochran, wim, linux, nab, maheshkhanwalkar, timur,
	arnd, ghackmann, ben, thuth, christopher.s.hall, john.stultz,
	sergei.shtylyov, mpe, jani.nikula
  Cc: Shuah Khan, linux-doc, linux-kernel, netdev, linux-watchdog,
	linux-kselftest
In-Reply-To: <cover.1473795601.git.shuahkh@osg.samsung.com>

Remove ptp from Makefile to move the test to selftests. Update ptp Makefile
to work under selftests. ptp will not be run as part of selftests suite and
will not be included in install targets. They can be built separately for
now.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 Documentation/Makefile                 |   2 +-
 Documentation/ptp/.gitignore           |   1 -
 Documentation/ptp/Makefile             |   8 -
 Documentation/ptp/testptp.c            | 523 ---------------------------------
 Documentation/ptp/testptp.mk           |  33 ---
 tools/testing/selftests/ptp/.gitignore |   1 +
 tools/testing/selftests/ptp/Makefile   |   8 +
 tools/testing/selftests/ptp/testptp.c  | 523 +++++++++++++++++++++++++++++++++
 tools/testing/selftests/ptp/testptp.mk |  33 +++
 9 files changed, 566 insertions(+), 566 deletions(-)
 delete mode 100644 Documentation/ptp/.gitignore
 delete mode 100644 Documentation/ptp/Makefile
 delete mode 100644 Documentation/ptp/testptp.c
 delete mode 100644 Documentation/ptp/testptp.mk
 create mode 100644 tools/testing/selftests/ptp/.gitignore
 create mode 100644 tools/testing/selftests/ptp/Makefile
 create mode 100644 tools/testing/selftests/ptp/testptp.c
 create mode 100644 tools/testing/selftests/ptp/testptp.mk

diff --git a/Documentation/Makefile b/Documentation/Makefile
index 7a28f6c..8cd6d1a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
 subdir-y := accounting auxdisplay blackfin \
 	ia64 laptops mic misc-devices \
-	networking pcmcia ptp timers vDSO watchdog
+	networking pcmcia timers vDSO watchdog
diff --git a/Documentation/ptp/.gitignore b/Documentation/ptp/.gitignore
deleted file mode 100644
index f562e49..0000000
--- a/Documentation/ptp/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-testptp
diff --git a/Documentation/ptp/Makefile b/Documentation/ptp/Makefile
deleted file mode 100644
index 293d6c0..0000000
--- a/Documentation/ptp/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# List of programs to build
-hostprogs-y := testptp
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_testptp.o += -I$(objtree)/usr/include
-HOSTLOADLIBES_testptp := -lrt
diff --git a/Documentation/ptp/testptp.c b/Documentation/ptp/testptp.c
deleted file mode 100644
index 5d2eae1..0000000
--- a/Documentation/ptp/testptp.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * PTP 1588 clock support - User space test program
- *
- * Copyright (C) 2010 OMICRON electronics GmbH
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#define _GNU_SOURCE
-#define __SANE_USERSPACE_TYPES__        /* For PPC64, to get LL64 types */
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <math.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/timex.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <linux/ptp_clock.h>
-
-#define DEVICE "/dev/ptp0"
-
-#ifndef ADJ_SETOFFSET
-#define ADJ_SETOFFSET 0x0100
-#endif
-
-#ifndef CLOCK_INVALID
-#define CLOCK_INVALID -1
-#endif
-
-/* clock_adjtime is not available in GLIBC < 2.14 */
-#if !__GLIBC_PREREQ(2, 14)
-#include <sys/syscall.h>
-static int clock_adjtime(clockid_t id, struct timex *tx)
-{
-	return syscall(__NR_clock_adjtime, id, tx);
-}
-#endif
-
-static clockid_t get_clockid(int fd)
-{
-#define CLOCKFD 3
-#define FD_TO_CLOCKID(fd)	((~(clockid_t) (fd) << 3) | CLOCKFD)
-
-	return FD_TO_CLOCKID(fd);
-}
-
-static void handle_alarm(int s)
-{
-	printf("received signal %d\n", s);
-}
-
-static int install_handler(int signum, void (*handler)(int))
-{
-	struct sigaction action;
-	sigset_t mask;
-
-	/* Unblock the signal. */
-	sigemptyset(&mask);
-	sigaddset(&mask, signum);
-	sigprocmask(SIG_UNBLOCK, &mask, NULL);
-
-	/* Install the signal handler. */
-	action.sa_handler = handler;
-	action.sa_flags = 0;
-	sigemptyset(&action.sa_mask);
-	sigaction(signum, &action, NULL);
-
-	return 0;
-}
-
-static long ppb_to_scaled_ppm(int ppb)
-{
-	/*
-	 * The 'freq' field in the 'struct timex' is in parts per
-	 * million, but with a 16 bit binary fractional field.
-	 * Instead of calculating either one of
-	 *
-	 *    scaled_ppm = (ppb / 1000) << 16  [1]
-	 *    scaled_ppm = (ppb << 16) / 1000  [2]
-	 *
-	 * we simply use double precision math, in order to avoid the
-	 * truncation in [1] and the possible overflow in [2].
-	 */
-	return (long) (ppb * 65.536);
-}
-
-static int64_t pctns(struct ptp_clock_time *t)
-{
-	return t->sec * 1000000000LL + t->nsec;
-}
-
-static void usage(char *progname)
-{
-	fprintf(stderr,
-		"usage: %s [options]\n"
-		" -a val     request a one-shot alarm after 'val' seconds\n"
-		" -A val     request a periodic alarm every 'val' seconds\n"
-		" -c         query the ptp clock's capabilities\n"
-		" -d name    device to open\n"
-		" -e val     read 'val' external time stamp events\n"
-		" -f val     adjust the ptp clock frequency by 'val' ppb\n"
-		" -g         get the ptp clock time\n"
-		" -h         prints this message\n"
-		" -i val     index for event/trigger\n"
-		" -k val     measure the time offset between system and phc clock\n"
-		"            for 'val' times (Maximum 25)\n"
-		" -l         list the current pin configuration\n"
-		" -L pin,val configure pin index 'pin' with function 'val'\n"
-		"            the channel index is taken from the '-i' option\n"
-		"            'val' specifies the auxiliary function:\n"
-		"            0 - none\n"
-		"            1 - external time stamp\n"
-		"            2 - periodic output\n"
-		" -p val     enable output with a period of 'val' nanoseconds\n"
-		" -P val     enable or disable (val=1|0) the system clock PPS\n"
-		" -s         set the ptp clock time from the system time\n"
-		" -S         set the system time from the ptp clock time\n"
-		" -t val     shift the ptp clock time by 'val' seconds\n"
-		" -T val     set the ptp clock time to 'val' seconds\n",
-		progname);
-}
-
-int main(int argc, char *argv[])
-{
-	struct ptp_clock_caps caps;
-	struct ptp_extts_event event;
-	struct ptp_extts_request extts_request;
-	struct ptp_perout_request perout_request;
-	struct ptp_pin_desc desc;
-	struct timespec ts;
-	struct timex tx;
-
-	static timer_t timerid;
-	struct itimerspec timeout;
-	struct sigevent sigevent;
-
-	struct ptp_clock_time *pct;
-	struct ptp_sys_offset *sysoff;
-
-
-	char *progname;
-	unsigned int i;
-	int c, cnt, fd;
-
-	char *device = DEVICE;
-	clockid_t clkid;
-	int adjfreq = 0x7fffffff;
-	int adjtime = 0;
-	int capabilities = 0;
-	int extts = 0;
-	int gettime = 0;
-	int index = 0;
-	int list_pins = 0;
-	int oneshot = 0;
-	int pct_offset = 0;
-	int n_samples = 0;
-	int periodic = 0;
-	int perout = -1;
-	int pin_index = -1, pin_func;
-	int pps = -1;
-	int seconds = 0;
-	int settime = 0;
-
-	int64_t t1, t2, tp;
-	int64_t interval, offset;
-
-	progname = strrchr(argv[0], '/');
-	progname = progname ? 1+progname : argv[0];
-	while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:lL:p:P:sSt:T:v"))) {
-		switch (c) {
-		case 'a':
-			oneshot = atoi(optarg);
-			break;
-		case 'A':
-			periodic = atoi(optarg);
-			break;
-		case 'c':
-			capabilities = 1;
-			break;
-		case 'd':
-			device = optarg;
-			break;
-		case 'e':
-			extts = atoi(optarg);
-			break;
-		case 'f':
-			adjfreq = atoi(optarg);
-			break;
-		case 'g':
-			gettime = 1;
-			break;
-		case 'i':
-			index = atoi(optarg);
-			break;
-		case 'k':
-			pct_offset = 1;
-			n_samples = atoi(optarg);
-			break;
-		case 'l':
-			list_pins = 1;
-			break;
-		case 'L':
-			cnt = sscanf(optarg, "%d,%d", &pin_index, &pin_func);
-			if (cnt != 2) {
-				usage(progname);
-				return -1;
-			}
-			break;
-		case 'p':
-			perout = atoi(optarg);
-			break;
-		case 'P':
-			pps = atoi(optarg);
-			break;
-		case 's':
-			settime = 1;
-			break;
-		case 'S':
-			settime = 2;
-			break;
-		case 't':
-			adjtime = atoi(optarg);
-			break;
-		case 'T':
-			settime = 3;
-			seconds = atoi(optarg);
-			break;
-		case 'h':
-			usage(progname);
-			return 0;
-		case '?':
-		default:
-			usage(progname);
-			return -1;
-		}
-	}
-
-	fd = open(device, O_RDWR);
-	if (fd < 0) {
-		fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
-		return -1;
-	}
-
-	clkid = get_clockid(fd);
-	if (CLOCK_INVALID == clkid) {
-		fprintf(stderr, "failed to read clock id\n");
-		return -1;
-	}
-
-	if (capabilities) {
-		if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
-			perror("PTP_CLOCK_GETCAPS");
-		} else {
-			printf("capabilities:\n"
-			       "  %d maximum frequency adjustment (ppb)\n"
-			       "  %d programmable alarms\n"
-			       "  %d external time stamp channels\n"
-			       "  %d programmable periodic signals\n"
-			       "  %d pulse per second\n"
-			       "  %d programmable pins\n"
-			       "  %d cross timestamping\n",
-			       caps.max_adj,
-			       caps.n_alarm,
-			       caps.n_ext_ts,
-			       caps.n_per_out,
-			       caps.pps,
-			       caps.n_pins,
-			       caps.cross_timestamping);
-		}
-	}
-
-	if (0x7fffffff != adjfreq) {
-		memset(&tx, 0, sizeof(tx));
-		tx.modes = ADJ_FREQUENCY;
-		tx.freq = ppb_to_scaled_ppm(adjfreq);
-		if (clock_adjtime(clkid, &tx)) {
-			perror("clock_adjtime");
-		} else {
-			puts("frequency adjustment okay");
-		}
-	}
-
-	if (adjtime) {
-		memset(&tx, 0, sizeof(tx));
-		tx.modes = ADJ_SETOFFSET;
-		tx.time.tv_sec = adjtime;
-		tx.time.tv_usec = 0;
-		if (clock_adjtime(clkid, &tx) < 0) {
-			perror("clock_adjtime");
-		} else {
-			puts("time shift okay");
-		}
-	}
-
-	if (gettime) {
-		if (clock_gettime(clkid, &ts)) {
-			perror("clock_gettime");
-		} else {
-			printf("clock time: %ld.%09ld or %s",
-			       ts.tv_sec, ts.tv_nsec, ctime(&ts.tv_sec));
-		}
-	}
-
-	if (settime == 1) {
-		clock_gettime(CLOCK_REALTIME, &ts);
-		if (clock_settime(clkid, &ts)) {
-			perror("clock_settime");
-		} else {
-			puts("set time okay");
-		}
-	}
-
-	if (settime == 2) {
-		clock_gettime(clkid, &ts);
-		if (clock_settime(CLOCK_REALTIME, &ts)) {
-			perror("clock_settime");
-		} else {
-			puts("set time okay");
-		}
-	}
-
-	if (settime == 3) {
-		ts.tv_sec = seconds;
-		ts.tv_nsec = 0;
-		if (clock_settime(clkid, &ts)) {
-			perror("clock_settime");
-		} else {
-			puts("set time okay");
-		}
-	}
-
-	if (extts) {
-		memset(&extts_request, 0, sizeof(extts_request));
-		extts_request.index = index;
-		extts_request.flags = PTP_ENABLE_FEATURE;
-		if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
-			perror("PTP_EXTTS_REQUEST");
-			extts = 0;
-		} else {
-			puts("external time stamp request okay");
-		}
-		for (; extts; extts--) {
-			cnt = read(fd, &event, sizeof(event));
-			if (cnt != sizeof(event)) {
-				perror("read");
-				break;
-			}
-			printf("event index %u at %lld.%09u\n", event.index,
-			       event.t.sec, event.t.nsec);
-			fflush(stdout);
-		}
-		/* Disable the feature again. */
-		extts_request.flags = 0;
-		if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
-			perror("PTP_EXTTS_REQUEST");
-		}
-	}
-
-	if (list_pins) {
-		int n_pins = 0;
-		if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
-			perror("PTP_CLOCK_GETCAPS");
-		} else {
-			n_pins = caps.n_pins;
-		}
-		for (i = 0; i < n_pins; i++) {
-			desc.index = i;
-			if (ioctl(fd, PTP_PIN_GETFUNC, &desc)) {
-				perror("PTP_PIN_GETFUNC");
-				break;
-			}
-			printf("name %s index %u func %u chan %u\n",
-			       desc.name, desc.index, desc.func, desc.chan);
-		}
-	}
-
-	if (oneshot) {
-		install_handler(SIGALRM, handle_alarm);
-		/* Create a timer. */
-		sigevent.sigev_notify = SIGEV_SIGNAL;
-		sigevent.sigev_signo = SIGALRM;
-		if (timer_create(clkid, &sigevent, &timerid)) {
-			perror("timer_create");
-			return -1;
-		}
-		/* Start the timer. */
-		memset(&timeout, 0, sizeof(timeout));
-		timeout.it_value.tv_sec = oneshot;
-		if (timer_settime(timerid, 0, &timeout, NULL)) {
-			perror("timer_settime");
-			return -1;
-		}
-		pause();
-		timer_delete(timerid);
-	}
-
-	if (periodic) {
-		install_handler(SIGALRM, handle_alarm);
-		/* Create a timer. */
-		sigevent.sigev_notify = SIGEV_SIGNAL;
-		sigevent.sigev_signo = SIGALRM;
-		if (timer_create(clkid, &sigevent, &timerid)) {
-			perror("timer_create");
-			return -1;
-		}
-		/* Start the timer. */
-		memset(&timeout, 0, sizeof(timeout));
-		timeout.it_interval.tv_sec = periodic;
-		timeout.it_value.tv_sec = periodic;
-		if (timer_settime(timerid, 0, &timeout, NULL)) {
-			perror("timer_settime");
-			return -1;
-		}
-		while (1) {
-			pause();
-		}
-		timer_delete(timerid);
-	}
-
-	if (perout >= 0) {
-		if (clock_gettime(clkid, &ts)) {
-			perror("clock_gettime");
-			return -1;
-		}
-		memset(&perout_request, 0, sizeof(perout_request));
-		perout_request.index = index;
-		perout_request.start.sec = ts.tv_sec + 2;
-		perout_request.start.nsec = 0;
-		perout_request.period.sec = 0;
-		perout_request.period.nsec = perout;
-		if (ioctl(fd, PTP_PEROUT_REQUEST, &perout_request)) {
-			perror("PTP_PEROUT_REQUEST");
-		} else {
-			puts("periodic output request okay");
-		}
-	}
-
-	if (pin_index >= 0) {
-		memset(&desc, 0, sizeof(desc));
-		desc.index = pin_index;
-		desc.func = pin_func;
-		desc.chan = index;
-		if (ioctl(fd, PTP_PIN_SETFUNC, &desc)) {
-			perror("PTP_PIN_SETFUNC");
-		} else {
-			puts("set pin function okay");
-		}
-	}
-
-	if (pps != -1) {
-		int enable = pps ? 1 : 0;
-		if (ioctl(fd, PTP_ENABLE_PPS, enable)) {
-			perror("PTP_ENABLE_PPS");
-		} else {
-			puts("pps for system time request okay");
-		}
-	}
-
-	if (pct_offset) {
-		if (n_samples <= 0 || n_samples > 25) {
-			puts("n_samples should be between 1 and 25");
-			usage(progname);
-			return -1;
-		}
-
-		sysoff = calloc(1, sizeof(*sysoff));
-		if (!sysoff) {
-			perror("calloc");
-			return -1;
-		}
-		sysoff->n_samples = n_samples;
-
-		if (ioctl(fd, PTP_SYS_OFFSET, sysoff))
-			perror("PTP_SYS_OFFSET");
-		else
-			puts("system and phc clock time offset request okay");
-
-		pct = &sysoff->ts[0];
-		for (i = 0; i < sysoff->n_samples; i++) {
-			t1 = pctns(pct+2*i);
-			tp = pctns(pct+2*i+1);
-			t2 = pctns(pct+2*i+2);
-			interval = t2 - t1;
-			offset = (t2 + t1) / 2 - tp;
-
-			printf("system time: %lld.%u\n",
-				(pct+2*i)->sec, (pct+2*i)->nsec);
-			printf("phc    time: %lld.%u\n",
-				(pct+2*i+1)->sec, (pct+2*i+1)->nsec);
-			printf("system time: %lld.%u\n",
-				(pct+2*i+2)->sec, (pct+2*i+2)->nsec);
-			printf("system/phc clock time offset is %" PRId64 " ns\n"
-			       "system     clock time delay  is %" PRId64 " ns\n",
-				offset, interval);
-		}
-
-		free(sysoff);
-	}
-
-	close(fd);
-	return 0;
-}
diff --git a/Documentation/ptp/testptp.mk b/Documentation/ptp/testptp.mk
deleted file mode 100644
index 4ef2d97..0000000
--- a/Documentation/ptp/testptp.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# PTP 1588 clock support - User space test program
-#
-# Copyright (C) 2010 OMICRON electronics GmbH
-#
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; either version 2 of the License, or
-#  (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-CC        = $(CROSS_COMPILE)gcc
-INC       = -I$(KBUILD_OUTPUT)/usr/include
-CFLAGS    = -Wall $(INC)
-LDLIBS    = -lrt
-PROGS     = testptp
-
-all: $(PROGS)
-
-testptp: testptp.o
-
-clean:
-	rm -f testptp.o
-
-distclean: clean
-	rm -f $(PROGS)
diff --git a/tools/testing/selftests/ptp/.gitignore b/tools/testing/selftests/ptp/.gitignore
new file mode 100644
index 0000000..f562e49
--- /dev/null
+++ b/tools/testing/selftests/ptp/.gitignore
@@ -0,0 +1 @@
+testptp
diff --git a/tools/testing/selftests/ptp/Makefile b/tools/testing/selftests/ptp/Makefile
new file mode 100644
index 0000000..83dd42b
--- /dev/null
+++ b/tools/testing/selftests/ptp/Makefile
@@ -0,0 +1,8 @@
+TEST_PROGS := testptp
+LDLIBS += -lrt
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+	rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
new file mode 100644
index 0000000..5d2eae1
--- /dev/null
+++ b/tools/testing/selftests/ptp/testptp.c
@@ -0,0 +1,523 @@
+/*
+ * PTP 1588 clock support - User space test program
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#define _GNU_SOURCE
+#define __SANE_USERSPACE_TYPES__        /* For PPC64, to get LL64 types */
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/ptp_clock.h>
+
+#define DEVICE "/dev/ptp0"
+
+#ifndef ADJ_SETOFFSET
+#define ADJ_SETOFFSET 0x0100
+#endif
+
+#ifndef CLOCK_INVALID
+#define CLOCK_INVALID -1
+#endif
+
+/* clock_adjtime is not available in GLIBC < 2.14 */
+#if !__GLIBC_PREREQ(2, 14)
+#include <sys/syscall.h>
+static int clock_adjtime(clockid_t id, struct timex *tx)
+{
+	return syscall(__NR_clock_adjtime, id, tx);
+}
+#endif
+
+static clockid_t get_clockid(int fd)
+{
+#define CLOCKFD 3
+#define FD_TO_CLOCKID(fd)	((~(clockid_t) (fd) << 3) | CLOCKFD)
+
+	return FD_TO_CLOCKID(fd);
+}
+
+static void handle_alarm(int s)
+{
+	printf("received signal %d\n", s);
+}
+
+static int install_handler(int signum, void (*handler)(int))
+{
+	struct sigaction action;
+	sigset_t mask;
+
+	/* Unblock the signal. */
+	sigemptyset(&mask);
+	sigaddset(&mask, signum);
+	sigprocmask(SIG_UNBLOCK, &mask, NULL);
+
+	/* Install the signal handler. */
+	action.sa_handler = handler;
+	action.sa_flags = 0;
+	sigemptyset(&action.sa_mask);
+	sigaction(signum, &action, NULL);
+
+	return 0;
+}
+
+static long ppb_to_scaled_ppm(int ppb)
+{
+	/*
+	 * The 'freq' field in the 'struct timex' is in parts per
+	 * million, but with a 16 bit binary fractional field.
+	 * Instead of calculating either one of
+	 *
+	 *    scaled_ppm = (ppb / 1000) << 16  [1]
+	 *    scaled_ppm = (ppb << 16) / 1000  [2]
+	 *
+	 * we simply use double precision math, in order to avoid the
+	 * truncation in [1] and the possible overflow in [2].
+	 */
+	return (long) (ppb * 65.536);
+}
+
+static int64_t pctns(struct ptp_clock_time *t)
+{
+	return t->sec * 1000000000LL + t->nsec;
+}
+
+static void usage(char *progname)
+{
+	fprintf(stderr,
+		"usage: %s [options]\n"
+		" -a val     request a one-shot alarm after 'val' seconds\n"
+		" -A val     request a periodic alarm every 'val' seconds\n"
+		" -c         query the ptp clock's capabilities\n"
+		" -d name    device to open\n"
+		" -e val     read 'val' external time stamp events\n"
+		" -f val     adjust the ptp clock frequency by 'val' ppb\n"
+		" -g         get the ptp clock time\n"
+		" -h         prints this message\n"
+		" -i val     index for event/trigger\n"
+		" -k val     measure the time offset between system and phc clock\n"
+		"            for 'val' times (Maximum 25)\n"
+		" -l         list the current pin configuration\n"
+		" -L pin,val configure pin index 'pin' with function 'val'\n"
+		"            the channel index is taken from the '-i' option\n"
+		"            'val' specifies the auxiliary function:\n"
+		"            0 - none\n"
+		"            1 - external time stamp\n"
+		"            2 - periodic output\n"
+		" -p val     enable output with a period of 'val' nanoseconds\n"
+		" -P val     enable or disable (val=1|0) the system clock PPS\n"
+		" -s         set the ptp clock time from the system time\n"
+		" -S         set the system time from the ptp clock time\n"
+		" -t val     shift the ptp clock time by 'val' seconds\n"
+		" -T val     set the ptp clock time to 'val' seconds\n",
+		progname);
+}
+
+int main(int argc, char *argv[])
+{
+	struct ptp_clock_caps caps;
+	struct ptp_extts_event event;
+	struct ptp_extts_request extts_request;
+	struct ptp_perout_request perout_request;
+	struct ptp_pin_desc desc;
+	struct timespec ts;
+	struct timex tx;
+
+	static timer_t timerid;
+	struct itimerspec timeout;
+	struct sigevent sigevent;
+
+	struct ptp_clock_time *pct;
+	struct ptp_sys_offset *sysoff;
+
+
+	char *progname;
+	unsigned int i;
+	int c, cnt, fd;
+
+	char *device = DEVICE;
+	clockid_t clkid;
+	int adjfreq = 0x7fffffff;
+	int adjtime = 0;
+	int capabilities = 0;
+	int extts = 0;
+	int gettime = 0;
+	int index = 0;
+	int list_pins = 0;
+	int oneshot = 0;
+	int pct_offset = 0;
+	int n_samples = 0;
+	int periodic = 0;
+	int perout = -1;
+	int pin_index = -1, pin_func;
+	int pps = -1;
+	int seconds = 0;
+	int settime = 0;
+
+	int64_t t1, t2, tp;
+	int64_t interval, offset;
+
+	progname = strrchr(argv[0], '/');
+	progname = progname ? 1+progname : argv[0];
+	while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:lL:p:P:sSt:T:v"))) {
+		switch (c) {
+		case 'a':
+			oneshot = atoi(optarg);
+			break;
+		case 'A':
+			periodic = atoi(optarg);
+			break;
+		case 'c':
+			capabilities = 1;
+			break;
+		case 'd':
+			device = optarg;
+			break;
+		case 'e':
+			extts = atoi(optarg);
+			break;
+		case 'f':
+			adjfreq = atoi(optarg);
+			break;
+		case 'g':
+			gettime = 1;
+			break;
+		case 'i':
+			index = atoi(optarg);
+			break;
+		case 'k':
+			pct_offset = 1;
+			n_samples = atoi(optarg);
+			break;
+		case 'l':
+			list_pins = 1;
+			break;
+		case 'L':
+			cnt = sscanf(optarg, "%d,%d", &pin_index, &pin_func);
+			if (cnt != 2) {
+				usage(progname);
+				return -1;
+			}
+			break;
+		case 'p':
+			perout = atoi(optarg);
+			break;
+		case 'P':
+			pps = atoi(optarg);
+			break;
+		case 's':
+			settime = 1;
+			break;
+		case 'S':
+			settime = 2;
+			break;
+		case 't':
+			adjtime = atoi(optarg);
+			break;
+		case 'T':
+			settime = 3;
+			seconds = atoi(optarg);
+			break;
+		case 'h':
+			usage(progname);
+			return 0;
+		case '?':
+		default:
+			usage(progname);
+			return -1;
+		}
+	}
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
+		return -1;
+	}
+
+	clkid = get_clockid(fd);
+	if (CLOCK_INVALID == clkid) {
+		fprintf(stderr, "failed to read clock id\n");
+		return -1;
+	}
+
+	if (capabilities) {
+		if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
+			perror("PTP_CLOCK_GETCAPS");
+		} else {
+			printf("capabilities:\n"
+			       "  %d maximum frequency adjustment (ppb)\n"
+			       "  %d programmable alarms\n"
+			       "  %d external time stamp channels\n"
+			       "  %d programmable periodic signals\n"
+			       "  %d pulse per second\n"
+			       "  %d programmable pins\n"
+			       "  %d cross timestamping\n",
+			       caps.max_adj,
+			       caps.n_alarm,
+			       caps.n_ext_ts,
+			       caps.n_per_out,
+			       caps.pps,
+			       caps.n_pins,
+			       caps.cross_timestamping);
+		}
+	}
+
+	if (0x7fffffff != adjfreq) {
+		memset(&tx, 0, sizeof(tx));
+		tx.modes = ADJ_FREQUENCY;
+		tx.freq = ppb_to_scaled_ppm(adjfreq);
+		if (clock_adjtime(clkid, &tx)) {
+			perror("clock_adjtime");
+		} else {
+			puts("frequency adjustment okay");
+		}
+	}
+
+	if (adjtime) {
+		memset(&tx, 0, sizeof(tx));
+		tx.modes = ADJ_SETOFFSET;
+		tx.time.tv_sec = adjtime;
+		tx.time.tv_usec = 0;
+		if (clock_adjtime(clkid, &tx) < 0) {
+			perror("clock_adjtime");
+		} else {
+			puts("time shift okay");
+		}
+	}
+
+	if (gettime) {
+		if (clock_gettime(clkid, &ts)) {
+			perror("clock_gettime");
+		} else {
+			printf("clock time: %ld.%09ld or %s",
+			       ts.tv_sec, ts.tv_nsec, ctime(&ts.tv_sec));
+		}
+	}
+
+	if (settime == 1) {
+		clock_gettime(CLOCK_REALTIME, &ts);
+		if (clock_settime(clkid, &ts)) {
+			perror("clock_settime");
+		} else {
+			puts("set time okay");
+		}
+	}
+
+	if (settime == 2) {
+		clock_gettime(clkid, &ts);
+		if (clock_settime(CLOCK_REALTIME, &ts)) {
+			perror("clock_settime");
+		} else {
+			puts("set time okay");
+		}
+	}
+
+	if (settime == 3) {
+		ts.tv_sec = seconds;
+		ts.tv_nsec = 0;
+		if (clock_settime(clkid, &ts)) {
+			perror("clock_settime");
+		} else {
+			puts("set time okay");
+		}
+	}
+
+	if (extts) {
+		memset(&extts_request, 0, sizeof(extts_request));
+		extts_request.index = index;
+		extts_request.flags = PTP_ENABLE_FEATURE;
+		if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+			perror("PTP_EXTTS_REQUEST");
+			extts = 0;
+		} else {
+			puts("external time stamp request okay");
+		}
+		for (; extts; extts--) {
+			cnt = read(fd, &event, sizeof(event));
+			if (cnt != sizeof(event)) {
+				perror("read");
+				break;
+			}
+			printf("event index %u at %lld.%09u\n", event.index,
+			       event.t.sec, event.t.nsec);
+			fflush(stdout);
+		}
+		/* Disable the feature again. */
+		extts_request.flags = 0;
+		if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+			perror("PTP_EXTTS_REQUEST");
+		}
+	}
+
+	if (list_pins) {
+		int n_pins = 0;
+		if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
+			perror("PTP_CLOCK_GETCAPS");
+		} else {
+			n_pins = caps.n_pins;
+		}
+		for (i = 0; i < n_pins; i++) {
+			desc.index = i;
+			if (ioctl(fd, PTP_PIN_GETFUNC, &desc)) {
+				perror("PTP_PIN_GETFUNC");
+				break;
+			}
+			printf("name %s index %u func %u chan %u\n",
+			       desc.name, desc.index, desc.func, desc.chan);
+		}
+	}
+
+	if (oneshot) {
+		install_handler(SIGALRM, handle_alarm);
+		/* Create a timer. */
+		sigevent.sigev_notify = SIGEV_SIGNAL;
+		sigevent.sigev_signo = SIGALRM;
+		if (timer_create(clkid, &sigevent, &timerid)) {
+			perror("timer_create");
+			return -1;
+		}
+		/* Start the timer. */
+		memset(&timeout, 0, sizeof(timeout));
+		timeout.it_value.tv_sec = oneshot;
+		if (timer_settime(timerid, 0, &timeout, NULL)) {
+			perror("timer_settime");
+			return -1;
+		}
+		pause();
+		timer_delete(timerid);
+	}
+
+	if (periodic) {
+		install_handler(SIGALRM, handle_alarm);
+		/* Create a timer. */
+		sigevent.sigev_notify = SIGEV_SIGNAL;
+		sigevent.sigev_signo = SIGALRM;
+		if (timer_create(clkid, &sigevent, &timerid)) {
+			perror("timer_create");
+			return -1;
+		}
+		/* Start the timer. */
+		memset(&timeout, 0, sizeof(timeout));
+		timeout.it_interval.tv_sec = periodic;
+		timeout.it_value.tv_sec = periodic;
+		if (timer_settime(timerid, 0, &timeout, NULL)) {
+			perror("timer_settime");
+			return -1;
+		}
+		while (1) {
+			pause();
+		}
+		timer_delete(timerid);
+	}
+
+	if (perout >= 0) {
+		if (clock_gettime(clkid, &ts)) {
+			perror("clock_gettime");
+			return -1;
+		}
+		memset(&perout_request, 0, sizeof(perout_request));
+		perout_request.index = index;
+		perout_request.start.sec = ts.tv_sec + 2;
+		perout_request.start.nsec = 0;
+		perout_request.period.sec = 0;
+		perout_request.period.nsec = perout;
+		if (ioctl(fd, PTP_PEROUT_REQUEST, &perout_request)) {
+			perror("PTP_PEROUT_REQUEST");
+		} else {
+			puts("periodic output request okay");
+		}
+	}
+
+	if (pin_index >= 0) {
+		memset(&desc, 0, sizeof(desc));
+		desc.index = pin_index;
+		desc.func = pin_func;
+		desc.chan = index;
+		if (ioctl(fd, PTP_PIN_SETFUNC, &desc)) {
+			perror("PTP_PIN_SETFUNC");
+		} else {
+			puts("set pin function okay");
+		}
+	}
+
+	if (pps != -1) {
+		int enable = pps ? 1 : 0;
+		if (ioctl(fd, PTP_ENABLE_PPS, enable)) {
+			perror("PTP_ENABLE_PPS");
+		} else {
+			puts("pps for system time request okay");
+		}
+	}
+
+	if (pct_offset) {
+		if (n_samples <= 0 || n_samples > 25) {
+			puts("n_samples should be between 1 and 25");
+			usage(progname);
+			return -1;
+		}
+
+		sysoff = calloc(1, sizeof(*sysoff));
+		if (!sysoff) {
+			perror("calloc");
+			return -1;
+		}
+		sysoff->n_samples = n_samples;
+
+		if (ioctl(fd, PTP_SYS_OFFSET, sysoff))
+			perror("PTP_SYS_OFFSET");
+		else
+			puts("system and phc clock time offset request okay");
+
+		pct = &sysoff->ts[0];
+		for (i = 0; i < sysoff->n_samples; i++) {
+			t1 = pctns(pct+2*i);
+			tp = pctns(pct+2*i+1);
+			t2 = pctns(pct+2*i+2);
+			interval = t2 - t1;
+			offset = (t2 + t1) / 2 - tp;
+
+			printf("system time: %lld.%u\n",
+				(pct+2*i)->sec, (pct+2*i)->nsec);
+			printf("phc    time: %lld.%u\n",
+				(pct+2*i+1)->sec, (pct+2*i+1)->nsec);
+			printf("system time: %lld.%u\n",
+				(pct+2*i+2)->sec, (pct+2*i+2)->nsec);
+			printf("system/phc clock time offset is %" PRId64 " ns\n"
+			       "system     clock time delay  is %" PRId64 " ns\n",
+				offset, interval);
+		}
+
+		free(sysoff);
+	}
+
+	close(fd);
+	return 0;
+}
diff --git a/tools/testing/selftests/ptp/testptp.mk b/tools/testing/selftests/ptp/testptp.mk
new file mode 100644
index 0000000..4ef2d97
--- /dev/null
+++ b/tools/testing/selftests/ptp/testptp.mk
@@ -0,0 +1,33 @@
+# PTP 1588 clock support - User space test program
+#
+# Copyright (C) 2010 OMICRON electronics GmbH
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CC        = $(CROSS_COMPILE)gcc
+INC       = -I$(KBUILD_OUTPUT)/usr/include
+CFLAGS    = -Wall $(INC)
+LDLIBS    = -lrt
+PROGS     = testptp
+
+all: $(PROGS)
+
+testptp: testptp.o
+
+clean:
+	rm -f testptp.o
+
+distclean: clean
+	rm -f $(PROGS)
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/6] selftests: move prctl tests from Documentation/prctl
From: Shuah Khan @ 2016-09-13 20:18 UTC (permalink / raw)
  To: corbet, richardcochran, wim, linux, nab, maheshkhanwalkar, timur,
	arnd, ghackmann, ben, thuth, christopher.s.hall, john.stultz,
	sergei.shtylyov, mpe, jani.nikula
  Cc: Shuah Khan, linux-doc, linux-kernel, netdev, linux-watchdog,
	linux-kselftest
In-Reply-To: <cover.1473795601.git.shuahkh@osg.samsung.com>

Move prctl tests from Documentation/prctl to selftests/prctl.

Remove prctl from Makefile to move the test. Update prctl Makefile to work
under selftests. prctl will not be run as part of selftests suite and will
not be included in install targets. They can be built separately for now.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 Documentation/Makefile                             |  2 +-
 Documentation/prctl/.gitignore                     |  3 -
 Documentation/prctl/Makefile                       | 10 ---
 .../prctl/disable-tsc-ctxt-sw-stress-test.c        | 97 ----------------------
 .../prctl/disable-tsc-on-off-stress-test.c         | 96 ---------------------
 Documentation/prctl/disable-tsc-test.c             | 95 ---------------------
 tools/testing/selftests/prctl/.gitignore           |  3 +
 tools/testing/selftests/prctl/Makefile             | 15 ++++
 .../prctl/disable-tsc-ctxt-sw-stress-test.c        | 97 ++++++++++++++++++++++
 .../prctl/disable-tsc-on-off-stress-test.c         | 96 +++++++++++++++++++++
 tools/testing/selftests/prctl/disable-tsc-test.c   | 95 +++++++++++++++++++++
 11 files changed, 307 insertions(+), 302 deletions(-)
 delete mode 100644 Documentation/prctl/.gitignore
 delete mode 100644 Documentation/prctl/Makefile
 delete mode 100644 Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c
 delete mode 100644 Documentation/prctl/disable-tsc-on-off-stress-test.c
 delete mode 100644 Documentation/prctl/disable-tsc-test.c
 create mode 100644 tools/testing/selftests/prctl/.gitignore
 create mode 100644 tools/testing/selftests/prctl/Makefile
 create mode 100644 tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c
 create mode 100644 tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c
 create mode 100644 tools/testing/selftests/prctl/disable-tsc-test.c

diff --git a/Documentation/Makefile b/Documentation/Makefile
index 0473710..7a28f6c 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
 subdir-y := accounting auxdisplay blackfin \
 	ia64 laptops mic misc-devices \
-	networking pcmcia prctl ptp timers vDSO watchdog
+	networking pcmcia ptp timers vDSO watchdog
diff --git a/Documentation/prctl/.gitignore b/Documentation/prctl/.gitignore
deleted file mode 100644
index 0b5c274..0000000
--- a/Documentation/prctl/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-disable-tsc-ctxt-sw-stress-test
-disable-tsc-on-off-stress-test
-disable-tsc-test
diff --git a/Documentation/prctl/Makefile b/Documentation/prctl/Makefile
deleted file mode 100644
index 44de308..0000000
--- a/Documentation/prctl/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-ifndef CROSS_COMPILE
-# List of programs to build
-hostprogs-$(CONFIG_X86) := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test disable-tsc-test
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS_disable-tsc-ctxt-sw-stress-test.o += -I$(objtree)/usr/include
-HOSTCFLAGS_disable-tsc-on-off-stress-test.o += -I$(objtree)/usr/include
-HOSTCFLAGS_disable-tsc-test.o += -I$(objtree)/usr/include
-endif
diff --git a/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c b/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c
deleted file mode 100644
index f7499d1..0000000
--- a/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
- *
- * Tests if the control register is updated correctly
- * at context switches
- *
- * Warning: this test will cause a very high load for a few seconds
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <inttypes.h>
-#include <wait.h>
-
-
-#include <sys/prctl.h>
-#include <linux/prctl.h>
-
-/* Get/set the process' ability to use the timestamp counter instruction */
-#ifndef PR_GET_TSC
-#define PR_GET_TSC 25
-#define PR_SET_TSC 26
-# define PR_TSC_ENABLE		1   /* allow the use of the timestamp counter */
-# define PR_TSC_SIGSEGV		2   /* throw a SIGSEGV instead of reading the TSC */
-#endif
-
-static uint64_t rdtsc(void)
-{
-uint32_t lo, hi;
-/* We cannot use "=A", since this would use %rax on x86_64 */
-__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-return (uint64_t)hi << 32 | lo;
-}
-
-static void sigsegv_expect(int sig)
-{
-	/* */
-}
-
-static void segvtask(void)
-{
-	if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
-	{
-		perror("prctl");
-		exit(0);
-	}
-	signal(SIGSEGV, sigsegv_expect);
-	alarm(10);
-	rdtsc();
-	fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
-	exit(0);
-}
-
-
-static void sigsegv_fail(int sig)
-{
-	fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
-	exit(0);
-}
-
-static void rdtsctask(void)
-{
-	if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
-	{
-		perror("prctl");
-		exit(0);
-	}
-	signal(SIGSEGV, sigsegv_fail);
-	alarm(10);
-	for(;;) rdtsc();
-}
-
-
-int main(void)
-{
-	int n_tasks = 100, i;
-
-	fprintf(stderr, "[No further output means we're allright]\n");
-
-	for (i=0; i<n_tasks; i++)
-		if (fork() == 0)
-		{
-			if (i & 1)
-				segvtask();
-			else
-				rdtsctask();
-		}
-
-	for (i=0; i<n_tasks; i++)
-		wait(NULL);
-
-	exit(0);
-}
-
diff --git a/Documentation/prctl/disable-tsc-on-off-stress-test.c b/Documentation/prctl/disable-tsc-on-off-stress-test.c
deleted file mode 100644
index a06f027..0000000
--- a/Documentation/prctl/disable-tsc-on-off-stress-test.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
- *
- * Tests if the control register is updated correctly
- * when set with prctl()
- *
- * Warning: this test will cause a very high load for a few seconds
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <inttypes.h>
-#include <wait.h>
-
-
-#include <sys/prctl.h>
-#include <linux/prctl.h>
-
-/* Get/set the process' ability to use the timestamp counter instruction */
-#ifndef PR_GET_TSC
-#define PR_GET_TSC 25
-#define PR_SET_TSC 26
-# define PR_TSC_ENABLE		1   /* allow the use of the timestamp counter */
-# define PR_TSC_SIGSEGV		2   /* throw a SIGSEGV instead of reading the TSC */
-#endif
-
-/* snippet from wikipedia :-) */
-
-static uint64_t rdtsc(void)
-{
-uint32_t lo, hi;
-/* We cannot use "=A", since this would use %rax on x86_64 */
-__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-return (uint64_t)hi << 32 | lo;
-}
-
-int should_segv = 0;
-
-static void sigsegv_cb(int sig)
-{
-	if (!should_segv)
-	{
-		fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
-		exit(0);
-	}
-	if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
-	{
-		perror("prctl");
-		exit(0);
-	}
-	should_segv = 0;
-
-	rdtsc();
-}
-
-static void task(void)
-{
-	signal(SIGSEGV, sigsegv_cb);
-	alarm(10);
-	for(;;)
-	{
-		rdtsc();
-		if (should_segv)
-		{
-			fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
-			exit(0);
-		}
-		if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
-		{
-			perror("prctl");
-			exit(0);
-		}
-		should_segv = 1;
-	}
-}
-
-
-int main(void)
-{
-	int n_tasks = 100, i;
-
-	fprintf(stderr, "[No further output means we're allright]\n");
-
-	for (i=0; i<n_tasks; i++)
-		if (fork() == 0)
-			task();
-
-	for (i=0; i<n_tasks; i++)
-		wait(NULL);
-
-	exit(0);
-}
-
diff --git a/Documentation/prctl/disable-tsc-test.c b/Documentation/prctl/disable-tsc-test.c
deleted file mode 100644
index 8d494f7..0000000
--- a/Documentation/prctl/disable-tsc-test.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
- *
- * Basic test to test behaviour of PR_GET_TSC and PR_SET_TSC
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <inttypes.h>
-
-
-#include <sys/prctl.h>
-#include <linux/prctl.h>
-
-/* Get/set the process' ability to use the timestamp counter instruction */
-#ifndef PR_GET_TSC
-#define PR_GET_TSC 25
-#define PR_SET_TSC 26
-# define PR_TSC_ENABLE		1   /* allow the use of the timestamp counter */
-# define PR_TSC_SIGSEGV		2   /* throw a SIGSEGV instead of reading the TSC */
-#endif
-
-const char *tsc_names[] =
-{
-	[0] = "[not set]",
-	[PR_TSC_ENABLE] = "PR_TSC_ENABLE",
-	[PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
-};
-
-static uint64_t rdtsc(void)
-{
-uint32_t lo, hi;
-/* We cannot use "=A", since this would use %rax on x86_64 */
-__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-return (uint64_t)hi << 32 | lo;
-}
-
-static void sigsegv_cb(int sig)
-{
-	int tsc_val = 0;
-
-	printf("[ SIG_SEGV ]\n");
-	printf("prctl(PR_GET_TSC, &tsc_val); ");
-	fflush(stdout);
-
-	if ( prctl(PR_GET_TSC, &tsc_val) == -1)
-		perror("prctl");
-
-	printf("tsc_val == %s\n", tsc_names[tsc_val]);
-	printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
-	fflush(stdout);
-	if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
-		perror("prctl");
-
-	printf("rdtsc() == ");
-}
-
-int main(void)
-{
-	int tsc_val = 0;
-
-	signal(SIGSEGV, sigsegv_cb);
-
-	printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
-	printf("prctl(PR_GET_TSC, &tsc_val); ");
-	fflush(stdout);
-
-	if ( prctl(PR_GET_TSC, &tsc_val) == -1)
-		perror("prctl");
-
-	printf("tsc_val == %s\n", tsc_names[tsc_val]);
-	printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
-	printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
-	fflush(stdout);
-
-	if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
-		perror("prctl");
-
-	printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
-	printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
-	fflush(stdout);
-
-	if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
-		perror("prctl");
-
-	printf("rdtsc() == ");
-	fflush(stdout);
-	printf("%llu\n", (unsigned long long)rdtsc());
-	fflush(stdout);
-
-	exit(EXIT_SUCCESS);
-}
-
diff --git a/tools/testing/selftests/prctl/.gitignore b/tools/testing/selftests/prctl/.gitignore
new file mode 100644
index 0000000..0b5c274
--- /dev/null
+++ b/tools/testing/selftests/prctl/.gitignore
@@ -0,0 +1,3 @@
+disable-tsc-ctxt-sw-stress-test
+disable-tsc-on-off-stress-test
+disable-tsc-test
diff --git a/tools/testing/selftests/prctl/Makefile b/tools/testing/selftests/prctl/Makefile
new file mode 100644
index 0000000..35aa1c8
--- /dev/null
+++ b/tools/testing/selftests/prctl/Makefile
@@ -0,0 +1,15 @@
+ifndef CROSS_COMPILE
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+ifeq ($(ARCH),x86)
+TEST_PROGS := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test \
+		disable-tsc-test
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+	rm -fr $(TEST_PROGS)
+endif
+endif
diff --git a/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c b/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c
new file mode 100644
index 0000000..f7499d1
--- /dev/null
+++ b/tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c
@@ -0,0 +1,97 @@
+/*
+ * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
+ *
+ * Tests if the control register is updated correctly
+ * at context switches
+ *
+ * Warning: this test will cause a very high load for a few seconds
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <wait.h>
+
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/* Get/set the process' ability to use the timestamp counter instruction */
+#ifndef PR_GET_TSC
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+# define PR_TSC_ENABLE		1   /* allow the use of the timestamp counter */
+# define PR_TSC_SIGSEGV		2   /* throw a SIGSEGV instead of reading the TSC */
+#endif
+
+static uint64_t rdtsc(void)
+{
+uint32_t lo, hi;
+/* We cannot use "=A", since this would use %rax on x86_64 */
+__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+return (uint64_t)hi << 32 | lo;
+}
+
+static void sigsegv_expect(int sig)
+{
+	/* */
+}
+
+static void segvtask(void)
+{
+	if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
+	{
+		perror("prctl");
+		exit(0);
+	}
+	signal(SIGSEGV, sigsegv_expect);
+	alarm(10);
+	rdtsc();
+	fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
+	exit(0);
+}
+
+
+static void sigsegv_fail(int sig)
+{
+	fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
+	exit(0);
+}
+
+static void rdtsctask(void)
+{
+	if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
+	{
+		perror("prctl");
+		exit(0);
+	}
+	signal(SIGSEGV, sigsegv_fail);
+	alarm(10);
+	for(;;) rdtsc();
+}
+
+
+int main(void)
+{
+	int n_tasks = 100, i;
+
+	fprintf(stderr, "[No further output means we're allright]\n");
+
+	for (i=0; i<n_tasks; i++)
+		if (fork() == 0)
+		{
+			if (i & 1)
+				segvtask();
+			else
+				rdtsctask();
+		}
+
+	for (i=0; i<n_tasks; i++)
+		wait(NULL);
+
+	exit(0);
+}
+
diff --git a/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c b/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c
new file mode 100644
index 0000000..a06f027
--- /dev/null
+++ b/tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c
@@ -0,0 +1,96 @@
+/*
+ * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
+ *
+ * Tests if the control register is updated correctly
+ * when set with prctl()
+ *
+ * Warning: this test will cause a very high load for a few seconds
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <wait.h>
+
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/* Get/set the process' ability to use the timestamp counter instruction */
+#ifndef PR_GET_TSC
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+# define PR_TSC_ENABLE		1   /* allow the use of the timestamp counter */
+# define PR_TSC_SIGSEGV		2   /* throw a SIGSEGV instead of reading the TSC */
+#endif
+
+/* snippet from wikipedia :-) */
+
+static uint64_t rdtsc(void)
+{
+uint32_t lo, hi;
+/* We cannot use "=A", since this would use %rax on x86_64 */
+__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+return (uint64_t)hi << 32 | lo;
+}
+
+int should_segv = 0;
+
+static void sigsegv_cb(int sig)
+{
+	if (!should_segv)
+	{
+		fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n");
+		exit(0);
+	}
+	if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0)
+	{
+		perror("prctl");
+		exit(0);
+	}
+	should_segv = 0;
+
+	rdtsc();
+}
+
+static void task(void)
+{
+	signal(SIGSEGV, sigsegv_cb);
+	alarm(10);
+	for(;;)
+	{
+		rdtsc();
+		if (should_segv)
+		{
+			fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n");
+			exit(0);
+		}
+		if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0)
+		{
+			perror("prctl");
+			exit(0);
+		}
+		should_segv = 1;
+	}
+}
+
+
+int main(void)
+{
+	int n_tasks = 100, i;
+
+	fprintf(stderr, "[No further output means we're allright]\n");
+
+	for (i=0; i<n_tasks; i++)
+		if (fork() == 0)
+			task();
+
+	for (i=0; i<n_tasks; i++)
+		wait(NULL);
+
+	exit(0);
+}
+
diff --git a/tools/testing/selftests/prctl/disable-tsc-test.c b/tools/testing/selftests/prctl/disable-tsc-test.c
new file mode 100644
index 0000000..8d494f7
--- /dev/null
+++ b/tools/testing/selftests/prctl/disable-tsc-test.c
@@ -0,0 +1,95 @@
+/*
+ * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...)
+ *
+ * Basic test to test behaviour of PR_GET_TSC and PR_SET_TSC
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/* Get/set the process' ability to use the timestamp counter instruction */
+#ifndef PR_GET_TSC
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+# define PR_TSC_ENABLE		1   /* allow the use of the timestamp counter */
+# define PR_TSC_SIGSEGV		2   /* throw a SIGSEGV instead of reading the TSC */
+#endif
+
+const char *tsc_names[] =
+{
+	[0] = "[not set]",
+	[PR_TSC_ENABLE] = "PR_TSC_ENABLE",
+	[PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV",
+};
+
+static uint64_t rdtsc(void)
+{
+uint32_t lo, hi;
+/* We cannot use "=A", since this would use %rax on x86_64 */
+__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+return (uint64_t)hi << 32 | lo;
+}
+
+static void sigsegv_cb(int sig)
+{
+	int tsc_val = 0;
+
+	printf("[ SIG_SEGV ]\n");
+	printf("prctl(PR_GET_TSC, &tsc_val); ");
+	fflush(stdout);
+
+	if ( prctl(PR_GET_TSC, &tsc_val) == -1)
+		perror("prctl");
+
+	printf("tsc_val == %s\n", tsc_names[tsc_val]);
+	printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
+	fflush(stdout);
+	if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
+		perror("prctl");
+
+	printf("rdtsc() == ");
+}
+
+int main(void)
+{
+	int tsc_val = 0;
+
+	signal(SIGSEGV, sigsegv_cb);
+
+	printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
+	printf("prctl(PR_GET_TSC, &tsc_val); ");
+	fflush(stdout);
+
+	if ( prctl(PR_GET_TSC, &tsc_val) == -1)
+		perror("prctl");
+
+	printf("tsc_val == %s\n", tsc_names[tsc_val]);
+	printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
+	printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n");
+	fflush(stdout);
+
+	if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1)
+		perror("prctl");
+
+	printf("rdtsc() == %llu\n", (unsigned long long)rdtsc());
+	printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n");
+	fflush(stdout);
+
+	if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1)
+		perror("prctl");
+
+	printf("rdtsc() == ");
+	fflush(stdout);
+	printf("%llu\n", (unsigned long long)rdtsc());
+	fflush(stdout);
+
+	exit(EXIT_SUCCESS);
+}
+
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 6/6] selftests: move watchdog tests from Documentation/watchdog
From: Shuah Khan @ 2016-09-13 20:18 UTC (permalink / raw)
  To: corbet, richardcochran, wim, linux, nab, maheshkhanwalkar, timur,
	arnd, ghackmann, ben, thuth, christopher.s.hall, john.stultz,
	sergei.shtylyov, mpe, jani.nikula
  Cc: Shuah Khan, linux-doc, linux-kernel, netdev, linux-watchdog,
	linux-kselftest
In-Reply-To: <cover.1473795601.git.shuahkh@osg.samsung.com>

Remove watchdog-test from Makefile to move the test to selftests.

Add Makefile and .gitignore to for watchdog-test. watchdog-test will
not be run as part of selftests suite and will not be included in
install targets.  It can be built separately for now.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 Documentation/watchdog/src/.gitignore            |   1 -
 Documentation/watchdog/src/Makefile              |   2 +-
 Documentation/watchdog/src/watchdog-test.c       | 105 -----------------------
 tools/testing/selftests/watchdog/.gitignore      |   1 +
 tools/testing/selftests/watchdog/Makefile        |   8 ++
 tools/testing/selftests/watchdog/watchdog-test.c | 105 +++++++++++++++++++++++
 6 files changed, 115 insertions(+), 107 deletions(-)
 delete mode 100644 Documentation/watchdog/src/watchdog-test.c
 create mode 100644 tools/testing/selftests/watchdog/.gitignore
 create mode 100644 tools/testing/selftests/watchdog/Makefile
 create mode 100644 tools/testing/selftests/watchdog/watchdog-test.c

diff --git a/Documentation/watchdog/src/.gitignore b/Documentation/watchdog/src/.gitignore
index ac90997..ff0ebb5 100644
--- a/Documentation/watchdog/src/.gitignore
+++ b/Documentation/watchdog/src/.gitignore
@@ -1,2 +1 @@
 watchdog-simple
-watchdog-test
diff --git a/Documentation/watchdog/src/Makefile b/Documentation/watchdog/src/Makefile
index 4a892c3..47be791 100644
--- a/Documentation/watchdog/src/Makefile
+++ b/Documentation/watchdog/src/Makefile
@@ -1,5 +1,5 @@
 # List of programs to build
-hostprogs-y := watchdog-simple watchdog-test
+hostprogs-y := watchdog-simple
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
diff --git a/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c
deleted file mode 100644
index 6983d05..0000000
--- a/Documentation/watchdog/src/watchdog-test.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Watchdog Driver Test Program
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/watchdog.h>
-
-int fd;
-const char v = 'V';
-
-/*
- * This function simply sends an IOCTL to the driver, which in turn ticks
- * the PC Watchdog card to reset its internal timer so it doesn't trigger
- * a computer reset.
- */
-static void keep_alive(void)
-{
-    int dummy;
-
-    printf(".");
-    ioctl(fd, WDIOC_KEEPALIVE, &dummy);
-}
-
-/*
- * The main program.  Run the program with "-d" to disable the card,
- * or "-e" to enable the card.
- */
-
-static void term(int sig)
-{
-    int ret = write(fd, &v, 1);
-
-    close(fd);
-    if (ret < 0)
-	printf("\nStopping watchdog ticks failed (%d)...\n", errno);
-    else
-	printf("\nStopping watchdog ticks...\n");
-    exit(0);
-}
-
-int main(int argc, char *argv[])
-{
-    int flags;
-    unsigned int ping_rate = 1;
-    int ret;
-
-    setbuf(stdout, NULL);
-
-    fd = open("/dev/watchdog", O_WRONLY);
-
-    if (fd == -1) {
-	printf("Watchdog device not enabled.\n");
-	exit(-1);
-    }
-
-    if (argc > 1) {
-	if (!strncasecmp(argv[1], "-d", 2)) {
-	    flags = WDIOS_DISABLECARD;
-	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
-	    printf("Watchdog card disabled.\n");
-	    goto end;
-	} else if (!strncasecmp(argv[1], "-e", 2)) {
-	    flags = WDIOS_ENABLECARD;
-	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
-	    printf("Watchdog card enabled.\n");
-	    goto end;
-	} else if (!strncasecmp(argv[1], "-t", 2) && argv[2]) {
-	    flags = atoi(argv[2]);
-	    ioctl(fd, WDIOC_SETTIMEOUT, &flags);
-	    printf("Watchdog timeout set to %u seconds.\n", flags);
-	    goto end;
-	} else if (!strncasecmp(argv[1], "-p", 2) && argv[2]) {
-	    ping_rate = strtoul(argv[2], NULL, 0);
-	    printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
-	} else {
-	    printf("-d to disable, -e to enable, -t <n> to set " \
-		"the timeout,\n-p <n> to set the ping rate, and \n");
-	    printf("run by itself to tick the card.\n");
-	    goto end;
-	}
-    }
-
-    printf("Watchdog Ticking Away!\n");
-
-    signal(SIGINT, term);
-
-    while(1) {
-	keep_alive();
-	sleep(ping_rate);
-    }
-end:
-    ret = write(fd, &v, 1);
-    if (ret < 0)
-	printf("Stopping watchdog ticks failed (%d)...\n", errno);
-    close(fd);
-    return 0;
-}
diff --git a/tools/testing/selftests/watchdog/.gitignore b/tools/testing/selftests/watchdog/.gitignore
new file mode 100644
index 0000000..5aac515
--- /dev/null
+++ b/tools/testing/selftests/watchdog/.gitignore
@@ -0,0 +1 @@
+watchdog-test
diff --git a/tools/testing/selftests/watchdog/Makefile b/tools/testing/selftests/watchdog/Makefile
new file mode 100644
index 0000000..f863c66
--- /dev/null
+++ b/tools/testing/selftests/watchdog/Makefile
@@ -0,0 +1,8 @@
+TEST_PROGS := watchdog-test
+
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+	rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/watchdog/watchdog-test.c b/tools/testing/selftests/watchdog/watchdog-test.c
new file mode 100644
index 0000000..6983d05
--- /dev/null
+++ b/tools/testing/selftests/watchdog/watchdog-test.c
@@ -0,0 +1,105 @@
+/*
+ * Watchdog Driver Test Program
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+int fd;
+const char v = 'V';
+
+/*
+ * This function simply sends an IOCTL to the driver, which in turn ticks
+ * the PC Watchdog card to reset its internal timer so it doesn't trigger
+ * a computer reset.
+ */
+static void keep_alive(void)
+{
+    int dummy;
+
+    printf(".");
+    ioctl(fd, WDIOC_KEEPALIVE, &dummy);
+}
+
+/*
+ * The main program.  Run the program with "-d" to disable the card,
+ * or "-e" to enable the card.
+ */
+
+static void term(int sig)
+{
+    int ret = write(fd, &v, 1);
+
+    close(fd);
+    if (ret < 0)
+	printf("\nStopping watchdog ticks failed (%d)...\n", errno);
+    else
+	printf("\nStopping watchdog ticks...\n");
+    exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+    int flags;
+    unsigned int ping_rate = 1;
+    int ret;
+
+    setbuf(stdout, NULL);
+
+    fd = open("/dev/watchdog", O_WRONLY);
+
+    if (fd == -1) {
+	printf("Watchdog device not enabled.\n");
+	exit(-1);
+    }
+
+    if (argc > 1) {
+	if (!strncasecmp(argv[1], "-d", 2)) {
+	    flags = WDIOS_DISABLECARD;
+	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
+	    printf("Watchdog card disabled.\n");
+	    goto end;
+	} else if (!strncasecmp(argv[1], "-e", 2)) {
+	    flags = WDIOS_ENABLECARD;
+	    ioctl(fd, WDIOC_SETOPTIONS, &flags);
+	    printf("Watchdog card enabled.\n");
+	    goto end;
+	} else if (!strncasecmp(argv[1], "-t", 2) && argv[2]) {
+	    flags = atoi(argv[2]);
+	    ioctl(fd, WDIOC_SETTIMEOUT, &flags);
+	    printf("Watchdog timeout set to %u seconds.\n", flags);
+	    goto end;
+	} else if (!strncasecmp(argv[1], "-p", 2) && argv[2]) {
+	    ping_rate = strtoul(argv[2], NULL, 0);
+	    printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
+	} else {
+	    printf("-d to disable, -e to enable, -t <n> to set " \
+		"the timeout,\n-p <n> to set the ping rate, and \n");
+	    printf("run by itself to tick the card.\n");
+	    goto end;
+	}
+    }
+
+    printf("Watchdog Ticking Away!\n");
+
+    signal(SIGINT, term);
+
+    while(1) {
+	keep_alive();
+	sleep(ping_rate);
+    }
+end:
+    ret = write(fd, &v, 1);
+    if (ret < 0)
+	printf("Stopping watchdog ticks failed (%d)...\n", errno);
+    close(fd);
+    return 0;
+}
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 5/6] selftests: move ia64 tests from Documentation/ia64
From: Shuah Khan @ 2016-09-13 20:18 UTC (permalink / raw)
  To: corbet, richardcochran, wim, linux, nab, maheshkhanwalkar, timur,
	arnd, ghackmann, ben, thuth, christopher.s.hall, john.stultz,
	sergei.shtylyov, mpe, jani.nikula
  Cc: Shuah Khan, linux-doc, linux-kernel, netdev, linux-watchdog,
	linux-kselftest
In-Reply-To: <cover.1473795601.git.shuahkh@osg.samsung.com>

Remove ia64 from Makefile to move the test to selftests.

Update ia64 Makefile to work under selftests. ia64 will not be run as part
of selftests suite and will not be included in install targets. They can be
built separately for now.

The original Makefile built this test on all archirectures and this update
doesn't change that.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 Documentation/Makefile                       |   2 +-
 Documentation/ia64/.gitignore                |   1 -
 Documentation/ia64/Makefile                  |   5 -
 Documentation/ia64/aliasing-test.c           | 263 ---------------------------
 tools/testing/selftests/ia64/.gitignore      |   1 +
 tools/testing/selftests/ia64/Makefile        |   8 +
 tools/testing/selftests/ia64/aliasing-test.c | 263 +++++++++++++++++++++++++++
 7 files changed, 273 insertions(+), 270 deletions(-)
 delete mode 100644 Documentation/ia64/.gitignore
 delete mode 100644 Documentation/ia64/Makefile
 delete mode 100644 Documentation/ia64/aliasing-test.c
 create mode 100644 tools/testing/selftests/ia64/.gitignore
 create mode 100644 tools/testing/selftests/ia64/Makefile
 create mode 100644 tools/testing/selftests/ia64/aliasing-test.c

diff --git a/Documentation/Makefile b/Documentation/Makefile
index 085b917..572e9b7 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
 subdir-y := accounting auxdisplay blackfin \
-	ia64 laptops mic misc-devices \
+	laptops mic misc-devices \
 	networking pcmcia timers watchdog
diff --git a/Documentation/ia64/.gitignore b/Documentation/ia64/.gitignore
deleted file mode 100644
index ab806ed..0000000
--- a/Documentation/ia64/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-aliasing-test
diff --git a/Documentation/ia64/Makefile b/Documentation/ia64/Makefile
deleted file mode 100644
index d493163..0000000
--- a/Documentation/ia64/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-y := aliasing-test
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/ia64/aliasing-test.c b/Documentation/ia64/aliasing-test.c
deleted file mode 100644
index 62a190d..0000000
--- a/Documentation/ia64/aliasing-test.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Exercise /dev/mem mmap cases that have been troublesome in the past
- *
- * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
- *	Bjorn Helgaas <bjorn.helgaas@hp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <fnmatch.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <linux/pci.h>
-
-int sum;
-
-static int map_mem(char *path, off_t offset, size_t length, int touch)
-{
-	int fd, rc;
-	void *addr;
-	int *c;
-
-	fd = open(path, O_RDWR);
-	if (fd == -1) {
-		perror(path);
-		return -1;
-	}
-
-	if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
-		rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
-		if (rc == -1)
-			perror("PCIIOC_MMAP_IS_MEM ioctl");
-	}
-
-	addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
-	if (addr == MAP_FAILED)
-		return 1;
-
-	if (touch) {
-		c = (int *) addr;
-		while (c < (int *) (addr + length))
-			sum += *c++;
-	}
-
-	rc = munmap(addr, length);
-	if (rc == -1) {
-		perror("munmap");
-		return -1;
-	}
-
-	close(fd);
-	return 0;
-}
-
-static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
-{
-	struct dirent **namelist;
-	char *name, *path2;
-	int i, n, r, rc = 0, result = 0;
-	struct stat buf;
-
-	n = scandir(path, &namelist, 0, alphasort);
-	if (n < 0) {
-		perror("scandir");
-		return -1;
-	}
-
-	for (i = 0; i < n; i++) {
-		name = namelist[i]->d_name;
-
-		if (fnmatch(".", name, 0) == 0)
-			goto skip;
-		if (fnmatch("..", name, 0) == 0)
-			goto skip;
-
-		path2 = malloc(strlen(path) + strlen(name) + 3);
-		strcpy(path2, path);
-		strcat(path2, "/");
-		strcat(path2, name);
-
-		if (fnmatch(file, name, 0) == 0) {
-			rc = map_mem(path2, offset, length, touch);
-			if (rc == 0)
-				fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
-			else if (rc > 0)
-				fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
-			else {
-				fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
-				return rc;
-			}
-		} else {
-			r = lstat(path2, &buf);
-			if (r == 0 && S_ISDIR(buf.st_mode)) {
-				rc = scan_tree(path2, file, offset, length, touch);
-				if (rc < 0)
-					return rc;
-			}
-		}
-
-		result |= rc;
-		free(path2);
-
-skip:
-		free(namelist[i]);
-	}
-	free(namelist);
-	return result;
-}
-
-char buf[1024];
-
-static int read_rom(char *path)
-{
-	int fd, rc;
-	size_t size = 0;
-
-	fd = open(path, O_RDWR);
-	if (fd == -1) {
-		perror(path);
-		return -1;
-	}
-
-	rc = write(fd, "1", 2);
-	if (rc <= 0) {
-		close(fd);
-		perror("write");
-		return -1;
-	}
-
-	do {
-		rc = read(fd, buf, sizeof(buf));
-		if (rc > 0)
-			size += rc;
-	} while (rc > 0);
-
-	close(fd);
-	return size;
-}
-
-static int scan_rom(char *path, char *file)
-{
-	struct dirent **namelist;
-	char *name, *path2;
-	int i, n, r, rc = 0, result = 0;
-	struct stat buf;
-
-	n = scandir(path, &namelist, 0, alphasort);
-	if (n < 0) {
-		perror("scandir");
-		return -1;
-	}
-
-	for (i = 0; i < n; i++) {
-		name = namelist[i]->d_name;
-
-		if (fnmatch(".", name, 0) == 0)
-			goto skip;
-		if (fnmatch("..", name, 0) == 0)
-			goto skip;
-
-		path2 = malloc(strlen(path) + strlen(name) + 3);
-		strcpy(path2, path);
-		strcat(path2, "/");
-		strcat(path2, name);
-
-		if (fnmatch(file, name, 0) == 0) {
-			rc = read_rom(path2);
-
-			/*
-			 * It's OK if the ROM is unreadable.  Maybe there
-			 * is no ROM, or some other error occurred.  The
-			 * important thing is that no MCA happened.
-			 */
-			if (rc > 0)
-				fprintf(stderr, "PASS: %s read %d bytes\n", path2, rc);
-			else {
-				fprintf(stderr, "PASS: %s not readable\n", path2);
-				return rc;
-			}
-		} else {
-			r = lstat(path2, &buf);
-			if (r == 0 && S_ISDIR(buf.st_mode)) {
-				rc = scan_rom(path2, file);
-				if (rc < 0)
-					return rc;
-			}
-		}
-
-		result |= rc;
-		free(path2);
-
-skip:
-		free(namelist[i]);
-	}
-	free(namelist);
-	return result;
-}
-
-int main(void)
-{
-	int rc;
-
-	if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
-		fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
-	else
-		fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
-
-	/*
-	 * It's not safe to blindly read the VGA frame buffer.  If you know
-	 * how to poke the card the right way, it should respond, but it's
-	 * not safe in general.  Many machines, e.g., Intel chipsets, cover
-	 * up a non-responding card by just returning -1, but others will
-	 * report the failure as a machine check.
-	 */
-	if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
-		fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
-	else
-		fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
-
-	if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
-		fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
-	else
-		fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
-
-	/*
-	 * Often you can map all the individual pieces above (0-0xA0000,
-	 * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
-	 * thing at once.  This is because the individual pieces use different
-	 * attributes, and there's no single attribute supported over the
-	 * whole region.
-	 */
-	rc = map_mem("/dev/mem", 0, 1024*1024, 0);
-	if (rc == 0)
-		fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
-	else if (rc > 0)
-		fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
-	else
-		fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
-
-	scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
-	scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
-	scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
-	scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
-
-	scan_rom("/sys/devices", "rom");
-
-	scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
-	scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
-	scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
-	scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
-
-	return rc;
-}
diff --git a/tools/testing/selftests/ia64/.gitignore b/tools/testing/selftests/ia64/.gitignore
new file mode 100644
index 0000000..ab806ed
--- /dev/null
+++ b/tools/testing/selftests/ia64/.gitignore
@@ -0,0 +1 @@
+aliasing-test
diff --git a/tools/testing/selftests/ia64/Makefile b/tools/testing/selftests/ia64/Makefile
new file mode 100644
index 0000000..2b3de2d
--- /dev/null
+++ b/tools/testing/selftests/ia64/Makefile
@@ -0,0 +1,8 @@
+TEST_PROGS := aliasing-test
+
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+	rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/ia64/aliasing-test.c b/tools/testing/selftests/ia64/aliasing-test.c
new file mode 100644
index 0000000..62a190d
--- /dev/null
+++ b/tools/testing/selftests/ia64/aliasing-test.c
@@ -0,0 +1,263 @@
+/*
+ * Exercise /dev/mem mmap cases that have been troublesome in the past
+ *
+ * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <linux/pci.h>
+
+int sum;
+
+static int map_mem(char *path, off_t offset, size_t length, int touch)
+{
+	int fd, rc;
+	void *addr;
+	int *c;
+
+	fd = open(path, O_RDWR);
+	if (fd == -1) {
+		perror(path);
+		return -1;
+	}
+
+	if (fnmatch("/proc/bus/pci/*", path, 0) == 0) {
+		rc = ioctl(fd, PCIIOC_MMAP_IS_MEM);
+		if (rc == -1)
+			perror("PCIIOC_MMAP_IS_MEM ioctl");
+	}
+
+	addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
+	if (addr == MAP_FAILED)
+		return 1;
+
+	if (touch) {
+		c = (int *) addr;
+		while (c < (int *) (addr + length))
+			sum += *c++;
+	}
+
+	rc = munmap(addr, length);
+	if (rc == -1) {
+		perror("munmap");
+		return -1;
+	}
+
+	close(fd);
+	return 0;
+}
+
+static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
+{
+	struct dirent **namelist;
+	char *name, *path2;
+	int i, n, r, rc = 0, result = 0;
+	struct stat buf;
+
+	n = scandir(path, &namelist, 0, alphasort);
+	if (n < 0) {
+		perror("scandir");
+		return -1;
+	}
+
+	for (i = 0; i < n; i++) {
+		name = namelist[i]->d_name;
+
+		if (fnmatch(".", name, 0) == 0)
+			goto skip;
+		if (fnmatch("..", name, 0) == 0)
+			goto skip;
+
+		path2 = malloc(strlen(path) + strlen(name) + 3);
+		strcpy(path2, path);
+		strcat(path2, "/");
+		strcat(path2, name);
+
+		if (fnmatch(file, name, 0) == 0) {
+			rc = map_mem(path2, offset, length, touch);
+			if (rc == 0)
+				fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
+			else if (rc > 0)
+				fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
+			else {
+				fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
+				return rc;
+			}
+		} else {
+			r = lstat(path2, &buf);
+			if (r == 0 && S_ISDIR(buf.st_mode)) {
+				rc = scan_tree(path2, file, offset, length, touch);
+				if (rc < 0)
+					return rc;
+			}
+		}
+
+		result |= rc;
+		free(path2);
+
+skip:
+		free(namelist[i]);
+	}
+	free(namelist);
+	return result;
+}
+
+char buf[1024];
+
+static int read_rom(char *path)
+{
+	int fd, rc;
+	size_t size = 0;
+
+	fd = open(path, O_RDWR);
+	if (fd == -1) {
+		perror(path);
+		return -1;
+	}
+
+	rc = write(fd, "1", 2);
+	if (rc <= 0) {
+		close(fd);
+		perror("write");
+		return -1;
+	}
+
+	do {
+		rc = read(fd, buf, sizeof(buf));
+		if (rc > 0)
+			size += rc;
+	} while (rc > 0);
+
+	close(fd);
+	return size;
+}
+
+static int scan_rom(char *path, char *file)
+{
+	struct dirent **namelist;
+	char *name, *path2;
+	int i, n, r, rc = 0, result = 0;
+	struct stat buf;
+
+	n = scandir(path, &namelist, 0, alphasort);
+	if (n < 0) {
+		perror("scandir");
+		return -1;
+	}
+
+	for (i = 0; i < n; i++) {
+		name = namelist[i]->d_name;
+
+		if (fnmatch(".", name, 0) == 0)
+			goto skip;
+		if (fnmatch("..", name, 0) == 0)
+			goto skip;
+
+		path2 = malloc(strlen(path) + strlen(name) + 3);
+		strcpy(path2, path);
+		strcat(path2, "/");
+		strcat(path2, name);
+
+		if (fnmatch(file, name, 0) == 0) {
+			rc = read_rom(path2);
+
+			/*
+			 * It's OK if the ROM is unreadable.  Maybe there
+			 * is no ROM, or some other error occurred.  The
+			 * important thing is that no MCA happened.
+			 */
+			if (rc > 0)
+				fprintf(stderr, "PASS: %s read %d bytes\n", path2, rc);
+			else {
+				fprintf(stderr, "PASS: %s not readable\n", path2);
+				return rc;
+			}
+		} else {
+			r = lstat(path2, &buf);
+			if (r == 0 && S_ISDIR(buf.st_mode)) {
+				rc = scan_rom(path2, file);
+				if (rc < 0)
+					return rc;
+			}
+		}
+
+		result |= rc;
+		free(path2);
+
+skip:
+		free(namelist[i]);
+	}
+	free(namelist);
+	return result;
+}
+
+int main(void)
+{
+	int rc;
+
+	if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
+		fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
+	else
+		fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
+
+	/*
+	 * It's not safe to blindly read the VGA frame buffer.  If you know
+	 * how to poke the card the right way, it should respond, but it's
+	 * not safe in general.  Many machines, e.g., Intel chipsets, cover
+	 * up a non-responding card by just returning -1, but others will
+	 * report the failure as a machine check.
+	 */
+	if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
+		fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
+	else
+		fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
+
+	if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
+		fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
+	else
+		fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
+
+	/*
+	 * Often you can map all the individual pieces above (0-0xA0000,
+	 * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
+	 * thing at once.  This is because the individual pieces use different
+	 * attributes, and there's no single attribute supported over the
+	 * whole region.
+	 */
+	rc = map_mem("/dev/mem", 0, 1024*1024, 0);
+	if (rc == 0)
+		fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
+	else if (rc > 0)
+		fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
+	else
+		fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
+
+	scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
+	scan_tree("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
+	scan_tree("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
+	scan_tree("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
+
+	scan_rom("/sys/devices", "rom");
+
+	scan_tree("/proc/bus/pci", "??.?", 0, 0xA0000, 1);
+	scan_tree("/proc/bus/pci", "??.?", 0xA0000, 0x20000, 0);
+	scan_tree("/proc/bus/pci", "??.?", 0xC0000, 0x40000, 1);
+	scan_tree("/proc/bus/pci", "??.?", 0, 1024*1024, 0);
+
+	return rc;
+}
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 4/6] selftests: move vDSO tests from Documentation/vDSO
From: Shuah Khan @ 2016-09-13 20:18 UTC (permalink / raw)
  To: corbet, richardcochran, wim, linux, nab, maheshkhanwalkar, timur,
	arnd, ghackmann, ben, thuth, christopher.s.hall, john.stultz,
	sergei.shtylyov, mpe, jani.nikula
  Cc: Shuah Khan, linux-doc, linux-kernel, netdev, linux-watchdog,
	linux-kselftest
In-Reply-To: <cover.1473795601.git.shuahkh@osg.samsung.com>

Remove vDSO from Makefile to move the to selftests. Update vDSO Makefile
to work under selftests. vDSO will not be run as part of selftests suite
and will not be included in install targets. They can be built separately
for now.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 Documentation/Makefile                             |   2 +-
 Documentation/vDSO/.gitignore                      |   2 -
 Documentation/vDSO/Makefile                        |  17 --
 Documentation/vDSO/parse_vdso.c                    | 269 ---------------------
 Documentation/vDSO/vdso_standalone_test_x86.c      | 128 ----------
 Documentation/vDSO/vdso_test.c                     |  52 ----
 tools/testing/selftests/vDSO/.gitignore            |   2 +
 tools/testing/selftests/vDSO/Makefile              |  20 ++
 tools/testing/selftests/vDSO/parse_vdso.c          | 269 +++++++++++++++++++++
 .../selftests/vDSO/vdso_standalone_test_x86.c      | 128 ++++++++++
 tools/testing/selftests/vDSO/vdso_test.c           |  52 ++++
 11 files changed, 472 insertions(+), 469 deletions(-)
 delete mode 100644 Documentation/vDSO/.gitignore
 delete mode 100644 Documentation/vDSO/Makefile
 delete mode 100644 Documentation/vDSO/parse_vdso.c
 delete mode 100644 Documentation/vDSO/vdso_standalone_test_x86.c
 delete mode 100644 Documentation/vDSO/vdso_test.c
 create mode 100644 tools/testing/selftests/vDSO/.gitignore
 create mode 100644 tools/testing/selftests/vDSO/Makefile
 create mode 100644 tools/testing/selftests/vDSO/parse_vdso.c
 create mode 100644 tools/testing/selftests/vDSO/vdso_standalone_test_x86.c
 create mode 100644 tools/testing/selftests/vDSO/vdso_test.c

diff --git a/Documentation/Makefile b/Documentation/Makefile
index 8cd6d1a..085b917 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
 subdir-y := accounting auxdisplay blackfin \
 	ia64 laptops mic misc-devices \
-	networking pcmcia timers vDSO watchdog
+	networking pcmcia timers watchdog
diff --git a/Documentation/vDSO/.gitignore b/Documentation/vDSO/.gitignore
deleted file mode 100644
index 133bf9e..0000000
--- a/Documentation/vDSO/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-vdso_test
-vdso_standalone_test_x86
diff --git a/Documentation/vDSO/Makefile b/Documentation/vDSO/Makefile
deleted file mode 100644
index b12e987..0000000
--- a/Documentation/vDSO/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-ifndef CROSS_COMPILE
-# vdso_test won't build for glibc < 2.16, so disable it
-# hostprogs-y := vdso_test
-hostprogs-$(CONFIG_X86) := vdso_standalone_test_x86
-vdso_standalone_test_x86-objs := vdso_standalone_test_x86.o parse_vdso.o
-vdso_test-objs := parse_vdso.o vdso_test.o
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
-
-HOSTCFLAGS := -I$(objtree)/usr/include -std=gnu99
-HOSTCFLAGS_vdso_standalone_test_x86.o := -fno-asynchronous-unwind-tables -fno-stack-protector
-HOSTLOADLIBES_vdso_standalone_test_x86 := -nostdlib
-ifeq ($(CONFIG_X86_32),y)
-HOSTLOADLIBES_vdso_standalone_test_x86 += -lgcc_s
-endif
-endif
diff --git a/Documentation/vDSO/parse_vdso.c b/Documentation/vDSO/parse_vdso.c
deleted file mode 100644
index 1dbb4b8..0000000
--- a/Documentation/vDSO/parse_vdso.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * parse_vdso.c: Linux reference vDSO parser
- * Written by Andrew Lutomirski, 2011-2014.
- *
- * This code is meant to be linked in to various programs that run on Linux.
- * As such, it is available with as few restrictions as possible.  This file
- * is licensed under the Creative Commons Zero License, version 1.0,
- * available at http://creativecommons.org/publicdomain/zero/1.0/legalcode
- *
- * The vDSO is a regular ELF DSO that the kernel maps into user space when
- * it starts a program.  It works equally well in statically and dynamically
- * linked binaries.
- *
- * This code is tested on x86.  In principle it should work on any
- * architecture that has a vDSO.
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <limits.h>
-#include <elf.h>
-
-/*
- * To use this vDSO parser, first call one of the vdso_init_* functions.
- * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
- * to vdso_init_from_sysinfo_ehdr.  Otherwise pass auxv to vdso_init_from_auxv.
- * Then call vdso_sym for each symbol you want.  For example, to look up
- * gettimeofday on x86_64, use:
- *
- *     <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday");
- * or
- *     <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
- *
- * vdso_sym will return 0 if the symbol doesn't exist or if the init function
- * failed or was not called.  vdso_sym is a little slow, so its return value
- * should be cached.
- *
- * vdso_sym is threadsafe; the init functions are not.
- *
- * These are the prototypes:
- */
-extern void vdso_init_from_auxv(void *auxv);
-extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
-extern void *vdso_sym(const char *version, const char *name);
-
-
-/* And here's the code. */
-#ifndef ELF_BITS
-# if ULONG_MAX > 0xffffffffUL
-#  define ELF_BITS 64
-# else
-#  define ELF_BITS 32
-# endif
-#endif
-
-#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x
-#define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x)
-#define ELF(x) ELF_BITS_XFORM(ELF_BITS, x)
-
-static struct vdso_info
-{
-	bool valid;
-
-	/* Load information */
-	uintptr_t load_addr;
-	uintptr_t load_offset;  /* load_addr - recorded vaddr */
-
-	/* Symbol table */
-	ELF(Sym) *symtab;
-	const char *symstrings;
-	ELF(Word) *bucket, *chain;
-	ELF(Word) nbucket, nchain;
-
-	/* Version table */
-	ELF(Versym) *versym;
-	ELF(Verdef) *verdef;
-} vdso_info;
-
-/* Straight from the ELF specification. */
-static unsigned long elf_hash(const unsigned char *name)
-{
-	unsigned long h = 0, g;
-	while (*name)
-	{
-		h = (h << 4) + *name++;
-		if (g = h & 0xf0000000)
-			h ^= g >> 24;
-		h &= ~g;
-	}
-	return h;
-}
-
-void vdso_init_from_sysinfo_ehdr(uintptr_t base)
-{
-	size_t i;
-	bool found_vaddr = false;
-
-	vdso_info.valid = false;
-
-	vdso_info.load_addr = base;
-
-	ELF(Ehdr) *hdr = (ELF(Ehdr)*)base;
-	if (hdr->e_ident[EI_CLASS] !=
-	    (ELF_BITS == 32 ? ELFCLASS32 : ELFCLASS64)) {
-		return;  /* Wrong ELF class -- check ELF_BITS */
-	}
-
-	ELF(Phdr) *pt = (ELF(Phdr)*)(vdso_info.load_addr + hdr->e_phoff);
-	ELF(Dyn) *dyn = 0;
-
-	/*
-	 * We need two things from the segment table: the load offset
-	 * and the dynamic table.
-	 */
-	for (i = 0; i < hdr->e_phnum; i++)
-	{
-		if (pt[i].p_type == PT_LOAD && !found_vaddr) {
-			found_vaddr = true;
-			vdso_info.load_offset =	base
-				+ (uintptr_t)pt[i].p_offset
-				- (uintptr_t)pt[i].p_vaddr;
-		} else if (pt[i].p_type == PT_DYNAMIC) {
-			dyn = (ELF(Dyn)*)(base + pt[i].p_offset);
-		}
-	}
-
-	if (!found_vaddr || !dyn)
-		return;  /* Failed */
-
-	/*
-	 * Fish out the useful bits of the dynamic table.
-	 */
-	ELF(Word) *hash = 0;
-	vdso_info.symstrings = 0;
-	vdso_info.symtab = 0;
-	vdso_info.versym = 0;
-	vdso_info.verdef = 0;
-	for (i = 0; dyn[i].d_tag != DT_NULL; i++) {
-		switch (dyn[i].d_tag) {
-		case DT_STRTAB:
-			vdso_info.symstrings = (const char *)
-				((uintptr_t)dyn[i].d_un.d_ptr
-				 + vdso_info.load_offset);
-			break;
-		case DT_SYMTAB:
-			vdso_info.symtab = (ELF(Sym) *)
-				((uintptr_t)dyn[i].d_un.d_ptr
-				 + vdso_info.load_offset);
-			break;
-		case DT_HASH:
-			hash = (ELF(Word) *)
-				((uintptr_t)dyn[i].d_un.d_ptr
-				 + vdso_info.load_offset);
-			break;
-		case DT_VERSYM:
-			vdso_info.versym = (ELF(Versym) *)
-				((uintptr_t)dyn[i].d_un.d_ptr
-				 + vdso_info.load_offset);
-			break;
-		case DT_VERDEF:
-			vdso_info.verdef = (ELF(Verdef) *)
-				((uintptr_t)dyn[i].d_un.d_ptr
-				 + vdso_info.load_offset);
-			break;
-		}
-	}
-	if (!vdso_info.symstrings || !vdso_info.symtab || !hash)
-		return;  /* Failed */
-
-	if (!vdso_info.verdef)
-		vdso_info.versym = 0;
-
-	/* Parse the hash table header. */
-	vdso_info.nbucket = hash[0];
-	vdso_info.nchain = hash[1];
-	vdso_info.bucket = &hash[2];
-	vdso_info.chain = &hash[vdso_info.nbucket + 2];
-
-	/* That's all we need. */
-	vdso_info.valid = true;
-}
-
-static bool vdso_match_version(ELF(Versym) ver,
-			       const char *name, ELF(Word) hash)
-{
-	/*
-	 * This is a helper function to check if the version indexed by
-	 * ver matches name (which hashes to hash).
-	 *
-	 * The version definition table is a mess, and I don't know how
-	 * to do this in better than linear time without allocating memory
-	 * to build an index.  I also don't know why the table has
-	 * variable size entries in the first place.
-	 *
-	 * For added fun, I can't find a comprehensible specification of how
-	 * to parse all the weird flags in the table.
-	 *
-	 * So I just parse the whole table every time.
-	 */
-
-	/* First step: find the version definition */
-	ver &= 0x7fff;  /* Apparently bit 15 means "hidden" */
-	ELF(Verdef) *def = vdso_info.verdef;
-	while(true) {
-		if ((def->vd_flags & VER_FLG_BASE) == 0
-		    && (def->vd_ndx & 0x7fff) == ver)
-			break;
-
-		if (def->vd_next == 0)
-			return false;  /* No definition. */
-
-		def = (ELF(Verdef) *)((char *)def + def->vd_next);
-	}
-
-	/* Now figure out whether it matches. */
-	ELF(Verdaux) *aux = (ELF(Verdaux)*)((char *)def + def->vd_aux);
-	return def->vd_hash == hash
-		&& !strcmp(name, vdso_info.symstrings + aux->vda_name);
-}
-
-void *vdso_sym(const char *version, const char *name)
-{
-	unsigned long ver_hash;
-	if (!vdso_info.valid)
-		return 0;
-
-	ver_hash = elf_hash(version);
-	ELF(Word) chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
-
-	for (; chain != STN_UNDEF; chain = vdso_info.chain[chain]) {
-		ELF(Sym) *sym = &vdso_info.symtab[chain];
-
-		/* Check for a defined global or weak function w/ right name. */
-		if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
-			continue;
-		if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
-		    ELF64_ST_BIND(sym->st_info) != STB_WEAK)
-			continue;
-		if (sym->st_shndx == SHN_UNDEF)
-			continue;
-		if (strcmp(name, vdso_info.symstrings + sym->st_name))
-			continue;
-
-		/* Check symbol version. */
-		if (vdso_info.versym
-		    && !vdso_match_version(vdso_info.versym[chain],
-					   version, ver_hash))
-			continue;
-
-		return (void *)(vdso_info.load_offset + sym->st_value);
-	}
-
-	return 0;
-}
-
-void vdso_init_from_auxv(void *auxv)
-{
-	ELF(auxv_t) *elf_auxv = auxv;
-	for (int i = 0; elf_auxv[i].a_type != AT_NULL; i++)
-	{
-		if (elf_auxv[i].a_type == AT_SYSINFO_EHDR) {
-			vdso_init_from_sysinfo_ehdr(elf_auxv[i].a_un.a_val);
-			return;
-		}
-	}
-
-	vdso_info.valid = false;
-}
diff --git a/Documentation/vDSO/vdso_standalone_test_x86.c b/Documentation/vDSO/vdso_standalone_test_x86.c
deleted file mode 100644
index 93b0ebf..0000000
--- a/Documentation/vDSO/vdso_standalone_test_x86.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * vdso_test.c: Sample code to test parse_vdso.c on x86
- * Copyright (c) 2011-2014 Andy Lutomirski
- * Subject to the GNU General Public License, version 2
- *
- * You can amuse yourself by compiling with:
- * gcc -std=gnu99 -nostdlib
- *     -Os -fno-asynchronous-unwind-tables -flto -lgcc_s
- *      vdso_standalone_test_x86.c parse_vdso.c
- * to generate a small binary.  On x86_64, you can omit -lgcc_s
- * if you want the binary to be completely standalone.
- */
-
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdint.h>
-
-extern void *vdso_sym(const char *version, const char *name);
-extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
-extern void vdso_init_from_auxv(void *auxv);
-
-/* We need a libc functions... */
-int strcmp(const char *a, const char *b)
-{
-	/* This implementation is buggy: it never returns -1. */
-	while (*a || *b) {
-		if (*a != *b)
-			return 1;
-		if (*a == 0 || *b == 0)
-			return 1;
-		a++;
-		b++;
-	}
-
-	return 0;
-}
-
-/* ...and two syscalls.  This is x86-specific. */
-static inline long x86_syscall3(long nr, long a0, long a1, long a2)
-{
-	long ret;
-#ifdef __x86_64__
-	asm volatile ("syscall" : "=a" (ret) : "a" (nr),
-		      "D" (a0), "S" (a1), "d" (a2) :
-		      "cc", "memory", "rcx",
-		      "r8", "r9", "r10", "r11" );
-#else
-	asm volatile ("int $0x80" : "=a" (ret) : "a" (nr),
-		      "b" (a0), "c" (a1), "d" (a2) :
-		      "cc", "memory" );
-#endif
-	return ret;
-}
-
-static inline long linux_write(int fd, const void *data, size_t len)
-{
-	return x86_syscall3(__NR_write, fd, (long)data, (long)len);
-}
-
-static inline void linux_exit(int code)
-{
-	x86_syscall3(__NR_exit, code, 0, 0);
-}
-
-void to_base10(char *lastdig, time_t n)
-{
-	while (n) {
-		*lastdig = (n % 10) + '0';
-		n /= 10;
-		lastdig--;
-	}
-}
-
-__attribute__((externally_visible)) void c_main(void **stack)
-{
-	/* Parse the stack */
-	long argc = (long)*stack;
-	stack += argc + 2;
-
-	/* Now we're pointing at the environment.  Skip it. */
-	while(*stack)
-		stack++;
-	stack++;
-
-	/* Now we're pointing at auxv.  Initialize the vDSO parser. */
-	vdso_init_from_auxv((void *)stack);
-
-	/* Find gettimeofday. */
-	typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
-	gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
-
-	if (!gtod)
-		linux_exit(1);
-
-	struct timeval tv;
-	long ret = gtod(&tv, 0);
-
-	if (ret == 0) {
-		char buf[] = "The time is                     .000000\n";
-		to_base10(buf + 31, tv.tv_sec);
-		to_base10(buf + 38, tv.tv_usec);
-		linux_write(1, buf, sizeof(buf) - 1);
-	} else {
-		linux_exit(ret);
-	}
-
-	linux_exit(0);
-}
-
-/*
- * This is the real entry point.  It passes the initial stack into
- * the C entry point.
- */
-asm (
-	".text\n"
-	".global _start\n"
-	".type _start,@function\n"
-	"_start:\n\t"
-#ifdef __x86_64__
-	"mov %rsp,%rdi\n\t"
-	"jmp c_main"
-#else
-	"push %esp\n\t"
-	"call c_main\n\t"
-	"int $3"
-#endif
-	);
diff --git a/Documentation/vDSO/vdso_test.c b/Documentation/vDSO/vdso_test.c
deleted file mode 100644
index 8daeb7d7..0000000
--- a/Documentation/vDSO/vdso_test.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * vdso_test.c: Sample code to test parse_vdso.c
- * Copyright (c) 2014 Andy Lutomirski
- * Subject to the GNU General Public License, version 2
- *
- * Compile with:
- * gcc -std=gnu99 vdso_test.c parse_vdso.c
- *
- * Tested on x86, 32-bit and 64-bit.  It may work on other architectures, too.
- */
-
-#include <stdint.h>
-#include <elf.h>
-#include <stdio.h>
-#include <sys/auxv.h>
-#include <sys/time.h>
-
-extern void *vdso_sym(const char *version, const char *name);
-extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
-extern void vdso_init_from_auxv(void *auxv);
-
-int main(int argc, char **argv)
-{
-	unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
-	if (!sysinfo_ehdr) {
-		printf("AT_SYSINFO_EHDR is not present!\n");
-		return 0;
-	}
-
-	vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
-
-	/* Find gettimeofday. */
-	typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
-	gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
-
-	if (!gtod) {
-		printf("Could not find __vdso_gettimeofday\n");
-		return 1;
-	}
-
-	struct timeval tv;
-	long ret = gtod(&tv, 0);
-
-	if (ret == 0) {
-		printf("The time is %lld.%06lld\n",
-		       (long long)tv.tv_sec, (long long)tv.tv_usec);
-	} else {
-		printf("__vdso_gettimeofday failed\n");
-	}
-
-	return 0;
-}
diff --git a/tools/testing/selftests/vDSO/.gitignore b/tools/testing/selftests/vDSO/.gitignore
new file mode 100644
index 0000000..133bf9e
--- /dev/null
+++ b/tools/testing/selftests/vDSO/.gitignore
@@ -0,0 +1,2 @@
+vdso_test
+vdso_standalone_test_x86
diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile
new file mode 100644
index 0000000..706b68b
--- /dev/null
+++ b/tools/testing/selftests/vDSO/Makefile
@@ -0,0 +1,20 @@
+ifndef CROSS_COMPILE
+CFLAGS := -std=gnu99
+CFLAGS_vdso_standalone_test_x86 := -nostdlib -fno-asynchronous-unwind-tables -fno-stack-protector
+ifeq ($(CONFIG_X86_32),y)
+LDLIBS += -lgcc_s
+endif
+
+TEST_PROGS := vdso_test vdso_standalone_test_x86
+
+all: $(TEST_PROGS)
+vdso_test: parse_vdso.c vdso_test.c
+vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
+	$(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
+		vdso_standalone_test_x86.c parse_vdso.c \
+		-o vdso_standalone_test_x86
+
+include ../lib.mk
+clean:
+	rm -fr $(TEST_PROGS)
+endif
diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
new file mode 100644
index 0000000..1dbb4b8
--- /dev/null
+++ b/tools/testing/selftests/vDSO/parse_vdso.c
@@ -0,0 +1,269 @@
+/*
+ * parse_vdso.c: Linux reference vDSO parser
+ * Written by Andrew Lutomirski, 2011-2014.
+ *
+ * This code is meant to be linked in to various programs that run on Linux.
+ * As such, it is available with as few restrictions as possible.  This file
+ * is licensed under the Creative Commons Zero License, version 1.0,
+ * available at http://creativecommons.org/publicdomain/zero/1.0/legalcode
+ *
+ * The vDSO is a regular ELF DSO that the kernel maps into user space when
+ * it starts a program.  It works equally well in statically and dynamically
+ * linked binaries.
+ *
+ * This code is tested on x86.  In principle it should work on any
+ * architecture that has a vDSO.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include <elf.h>
+
+/*
+ * To use this vDSO parser, first call one of the vdso_init_* functions.
+ * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
+ * to vdso_init_from_sysinfo_ehdr.  Otherwise pass auxv to vdso_init_from_auxv.
+ * Then call vdso_sym for each symbol you want.  For example, to look up
+ * gettimeofday on x86_64, use:
+ *
+ *     <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday");
+ * or
+ *     <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
+ *
+ * vdso_sym will return 0 if the symbol doesn't exist or if the init function
+ * failed or was not called.  vdso_sym is a little slow, so its return value
+ * should be cached.
+ *
+ * vdso_sym is threadsafe; the init functions are not.
+ *
+ * These are the prototypes:
+ */
+extern void vdso_init_from_auxv(void *auxv);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void *vdso_sym(const char *version, const char *name);
+
+
+/* And here's the code. */
+#ifndef ELF_BITS
+# if ULONG_MAX > 0xffffffffUL
+#  define ELF_BITS 64
+# else
+#  define ELF_BITS 32
+# endif
+#endif
+
+#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x
+#define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x)
+#define ELF(x) ELF_BITS_XFORM(ELF_BITS, x)
+
+static struct vdso_info
+{
+	bool valid;
+
+	/* Load information */
+	uintptr_t load_addr;
+	uintptr_t load_offset;  /* load_addr - recorded vaddr */
+
+	/* Symbol table */
+	ELF(Sym) *symtab;
+	const char *symstrings;
+	ELF(Word) *bucket, *chain;
+	ELF(Word) nbucket, nchain;
+
+	/* Version table */
+	ELF(Versym) *versym;
+	ELF(Verdef) *verdef;
+} vdso_info;
+
+/* Straight from the ELF specification. */
+static unsigned long elf_hash(const unsigned char *name)
+{
+	unsigned long h = 0, g;
+	while (*name)
+	{
+		h = (h << 4) + *name++;
+		if (g = h & 0xf0000000)
+			h ^= g >> 24;
+		h &= ~g;
+	}
+	return h;
+}
+
+void vdso_init_from_sysinfo_ehdr(uintptr_t base)
+{
+	size_t i;
+	bool found_vaddr = false;
+
+	vdso_info.valid = false;
+
+	vdso_info.load_addr = base;
+
+	ELF(Ehdr) *hdr = (ELF(Ehdr)*)base;
+	if (hdr->e_ident[EI_CLASS] !=
+	    (ELF_BITS == 32 ? ELFCLASS32 : ELFCLASS64)) {
+		return;  /* Wrong ELF class -- check ELF_BITS */
+	}
+
+	ELF(Phdr) *pt = (ELF(Phdr)*)(vdso_info.load_addr + hdr->e_phoff);
+	ELF(Dyn) *dyn = 0;
+
+	/*
+	 * We need two things from the segment table: the load offset
+	 * and the dynamic table.
+	 */
+	for (i = 0; i < hdr->e_phnum; i++)
+	{
+		if (pt[i].p_type == PT_LOAD && !found_vaddr) {
+			found_vaddr = true;
+			vdso_info.load_offset =	base
+				+ (uintptr_t)pt[i].p_offset
+				- (uintptr_t)pt[i].p_vaddr;
+		} else if (pt[i].p_type == PT_DYNAMIC) {
+			dyn = (ELF(Dyn)*)(base + pt[i].p_offset);
+		}
+	}
+
+	if (!found_vaddr || !dyn)
+		return;  /* Failed */
+
+	/*
+	 * Fish out the useful bits of the dynamic table.
+	 */
+	ELF(Word) *hash = 0;
+	vdso_info.symstrings = 0;
+	vdso_info.symtab = 0;
+	vdso_info.versym = 0;
+	vdso_info.verdef = 0;
+	for (i = 0; dyn[i].d_tag != DT_NULL; i++) {
+		switch (dyn[i].d_tag) {
+		case DT_STRTAB:
+			vdso_info.symstrings = (const char *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_SYMTAB:
+			vdso_info.symtab = (ELF(Sym) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_HASH:
+			hash = (ELF(Word) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_VERSYM:
+			vdso_info.versym = (ELF(Versym) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_VERDEF:
+			vdso_info.verdef = (ELF(Verdef) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		}
+	}
+	if (!vdso_info.symstrings || !vdso_info.symtab || !hash)
+		return;  /* Failed */
+
+	if (!vdso_info.verdef)
+		vdso_info.versym = 0;
+
+	/* Parse the hash table header. */
+	vdso_info.nbucket = hash[0];
+	vdso_info.nchain = hash[1];
+	vdso_info.bucket = &hash[2];
+	vdso_info.chain = &hash[vdso_info.nbucket + 2];
+
+	/* That's all we need. */
+	vdso_info.valid = true;
+}
+
+static bool vdso_match_version(ELF(Versym) ver,
+			       const char *name, ELF(Word) hash)
+{
+	/*
+	 * This is a helper function to check if the version indexed by
+	 * ver matches name (which hashes to hash).
+	 *
+	 * The version definition table is a mess, and I don't know how
+	 * to do this in better than linear time without allocating memory
+	 * to build an index.  I also don't know why the table has
+	 * variable size entries in the first place.
+	 *
+	 * For added fun, I can't find a comprehensible specification of how
+	 * to parse all the weird flags in the table.
+	 *
+	 * So I just parse the whole table every time.
+	 */
+
+	/* First step: find the version definition */
+	ver &= 0x7fff;  /* Apparently bit 15 means "hidden" */
+	ELF(Verdef) *def = vdso_info.verdef;
+	while(true) {
+		if ((def->vd_flags & VER_FLG_BASE) == 0
+		    && (def->vd_ndx & 0x7fff) == ver)
+			break;
+
+		if (def->vd_next == 0)
+			return false;  /* No definition. */
+
+		def = (ELF(Verdef) *)((char *)def + def->vd_next);
+	}
+
+	/* Now figure out whether it matches. */
+	ELF(Verdaux) *aux = (ELF(Verdaux)*)((char *)def + def->vd_aux);
+	return def->vd_hash == hash
+		&& !strcmp(name, vdso_info.symstrings + aux->vda_name);
+}
+
+void *vdso_sym(const char *version, const char *name)
+{
+	unsigned long ver_hash;
+	if (!vdso_info.valid)
+		return 0;
+
+	ver_hash = elf_hash(version);
+	ELF(Word) chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
+
+	for (; chain != STN_UNDEF; chain = vdso_info.chain[chain]) {
+		ELF(Sym) *sym = &vdso_info.symtab[chain];
+
+		/* Check for a defined global or weak function w/ right name. */
+		if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
+			continue;
+		if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
+		    ELF64_ST_BIND(sym->st_info) != STB_WEAK)
+			continue;
+		if (sym->st_shndx == SHN_UNDEF)
+			continue;
+		if (strcmp(name, vdso_info.symstrings + sym->st_name))
+			continue;
+
+		/* Check symbol version. */
+		if (vdso_info.versym
+		    && !vdso_match_version(vdso_info.versym[chain],
+					   version, ver_hash))
+			continue;
+
+		return (void *)(vdso_info.load_offset + sym->st_value);
+	}
+
+	return 0;
+}
+
+void vdso_init_from_auxv(void *auxv)
+{
+	ELF(auxv_t) *elf_auxv = auxv;
+	for (int i = 0; elf_auxv[i].a_type != AT_NULL; i++)
+	{
+		if (elf_auxv[i].a_type == AT_SYSINFO_EHDR) {
+			vdso_init_from_sysinfo_ehdr(elf_auxv[i].a_un.a_val);
+			return;
+		}
+	}
+
+	vdso_info.valid = false;
+}
diff --git a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c
new file mode 100644
index 0000000..93b0ebf
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c
@@ -0,0 +1,128 @@
+/*
+ * vdso_test.c: Sample code to test parse_vdso.c on x86
+ * Copyright (c) 2011-2014 Andy Lutomirski
+ * Subject to the GNU General Public License, version 2
+ *
+ * You can amuse yourself by compiling with:
+ * gcc -std=gnu99 -nostdlib
+ *     -Os -fno-asynchronous-unwind-tables -flto -lgcc_s
+ *      vdso_standalone_test_x86.c parse_vdso.c
+ * to generate a small binary.  On x86_64, you can omit -lgcc_s
+ * if you want the binary to be completely standalone.
+ */
+
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdint.h>
+
+extern void *vdso_sym(const char *version, const char *name);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void vdso_init_from_auxv(void *auxv);
+
+/* We need a libc functions... */
+int strcmp(const char *a, const char *b)
+{
+	/* This implementation is buggy: it never returns -1. */
+	while (*a || *b) {
+		if (*a != *b)
+			return 1;
+		if (*a == 0 || *b == 0)
+			return 1;
+		a++;
+		b++;
+	}
+
+	return 0;
+}
+
+/* ...and two syscalls.  This is x86-specific. */
+static inline long x86_syscall3(long nr, long a0, long a1, long a2)
+{
+	long ret;
+#ifdef __x86_64__
+	asm volatile ("syscall" : "=a" (ret) : "a" (nr),
+		      "D" (a0), "S" (a1), "d" (a2) :
+		      "cc", "memory", "rcx",
+		      "r8", "r9", "r10", "r11" );
+#else
+	asm volatile ("int $0x80" : "=a" (ret) : "a" (nr),
+		      "b" (a0), "c" (a1), "d" (a2) :
+		      "cc", "memory" );
+#endif
+	return ret;
+}
+
+static inline long linux_write(int fd, const void *data, size_t len)
+{
+	return x86_syscall3(__NR_write, fd, (long)data, (long)len);
+}
+
+static inline void linux_exit(int code)
+{
+	x86_syscall3(__NR_exit, code, 0, 0);
+}
+
+void to_base10(char *lastdig, time_t n)
+{
+	while (n) {
+		*lastdig = (n % 10) + '0';
+		n /= 10;
+		lastdig--;
+	}
+}
+
+__attribute__((externally_visible)) void c_main(void **stack)
+{
+	/* Parse the stack */
+	long argc = (long)*stack;
+	stack += argc + 2;
+
+	/* Now we're pointing at the environment.  Skip it. */
+	while(*stack)
+		stack++;
+	stack++;
+
+	/* Now we're pointing at auxv.  Initialize the vDSO parser. */
+	vdso_init_from_auxv((void *)stack);
+
+	/* Find gettimeofday. */
+	typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
+	gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
+
+	if (!gtod)
+		linux_exit(1);
+
+	struct timeval tv;
+	long ret = gtod(&tv, 0);
+
+	if (ret == 0) {
+		char buf[] = "The time is                     .000000\n";
+		to_base10(buf + 31, tv.tv_sec);
+		to_base10(buf + 38, tv.tv_usec);
+		linux_write(1, buf, sizeof(buf) - 1);
+	} else {
+		linux_exit(ret);
+	}
+
+	linux_exit(0);
+}
+
+/*
+ * This is the real entry point.  It passes the initial stack into
+ * the C entry point.
+ */
+asm (
+	".text\n"
+	".global _start\n"
+	".type _start,@function\n"
+	"_start:\n\t"
+#ifdef __x86_64__
+	"mov %rsp,%rdi\n\t"
+	"jmp c_main"
+#else
+	"push %esp\n\t"
+	"call c_main\n\t"
+	"int $3"
+#endif
+	);
diff --git a/tools/testing/selftests/vDSO/vdso_test.c b/tools/testing/selftests/vDSO/vdso_test.c
new file mode 100644
index 0000000..8daeb7d7
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_test.c
@@ -0,0 +1,52 @@
+/*
+ * vdso_test.c: Sample code to test parse_vdso.c
+ * Copyright (c) 2014 Andy Lutomirski
+ * Subject to the GNU General Public License, version 2
+ *
+ * Compile with:
+ * gcc -std=gnu99 vdso_test.c parse_vdso.c
+ *
+ * Tested on x86, 32-bit and 64-bit.  It may work on other architectures, too.
+ */
+
+#include <stdint.h>
+#include <elf.h>
+#include <stdio.h>
+#include <sys/auxv.h>
+#include <sys/time.h>
+
+extern void *vdso_sym(const char *version, const char *name);
+extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
+extern void vdso_init_from_auxv(void *auxv);
+
+int main(int argc, char **argv)
+{
+	unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
+	if (!sysinfo_ehdr) {
+		printf("AT_SYSINFO_EHDR is not present!\n");
+		return 0;
+	}
+
+	vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
+
+	/* Find gettimeofday. */
+	typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
+	gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
+
+	if (!gtod) {
+		printf("Could not find __vdso_gettimeofday\n");
+		return 1;
+	}
+
+	struct timeval tv;
+	long ret = gtod(&tv, 0);
+
+	if (ret == 0) {
+		printf("The time is %lld.%06lld\n",
+		       (long long)tv.tv_sec, (long long)tv.tv_usec);
+	} else {
+		printf("__vdso_gettimeofday failed\n");
+	}
+
+	return 0;
+}
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 1/6] selftests: move dnotify_test from Documentation/filesystems
From: Shuah Khan @ 2016-09-13 20:18 UTC (permalink / raw)
  To: corbet, richardcochran, wim, linux, nab, maheshkhanwalkar, timur,
	arnd, ghackmann, ben, thuth, christopher.s.hall, john.stultz,
	sergei.shtylyov, mpe, jani.nikula
  Cc: Shuah Khan, linux-doc, linux-kernel, netdev, linux-watchdog,
	linux-kselftest
In-Reply-To: <cover.1473795601.git.shuahkh@osg.samsung.com>

Move dnotify_test.c, Makefile, and .gitignore from Documentation/filesystems
to selftests/filesystems.

Remove filesystems build target from Documentation/Makefile and update
selftests/filesystems/Makefile to work under selftests. dnotify_test will
not be run as part of selftests suite and will not be included in install
targets. It can be built separately for now.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 Documentation/Makefile                             |  2 +-
 Documentation/filesystems/.gitignore               |  1 -
 Documentation/filesystems/Makefile                 |  5 ----
 Documentation/filesystems/dnotify_test.c           | 34 ----------------------
 tools/testing/selftests/filesystems/.gitignore     |  1 +
 tools/testing/selftests/filesystems/Makefile       |  7 +++++
 tools/testing/selftests/filesystems/dnotify_test.c | 34 ++++++++++++++++++++++
 7 files changed, 43 insertions(+), 41 deletions(-)
 delete mode 100644 Documentation/filesystems/.gitignore
 delete mode 100644 Documentation/filesystems/Makefile
 delete mode 100644 Documentation/filesystems/dnotify_test.c
 create mode 100644 tools/testing/selftests/filesystems/.gitignore
 create mode 100644 tools/testing/selftests/filesystems/Makefile
 create mode 100644 tools/testing/selftests/filesystems/dnotify_test.c

diff --git a/Documentation/Makefile b/Documentation/Makefile
index de955e1..0473710 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
 subdir-y := accounting auxdisplay blackfin \
-	filesystems filesystems ia64 laptops mic misc-devices \
+	ia64 laptops mic misc-devices \
 	networking pcmcia prctl ptp timers vDSO watchdog
diff --git a/Documentation/filesystems/.gitignore b/Documentation/filesystems/.gitignore
deleted file mode 100644
index 31d6e42..0000000
--- a/Documentation/filesystems/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-dnotify_test
diff --git a/Documentation/filesystems/Makefile b/Documentation/filesystems/Makefile
deleted file mode 100644
index 883010c..0000000
--- a/Documentation/filesystems/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of programs to build
-hostprogs-y := dnotify_test
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/filesystems/dnotify_test.c b/Documentation/filesystems/dnotify_test.c
deleted file mode 100644
index 8b37b4a..0000000
--- a/Documentation/filesystems/dnotify_test.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#define _GNU_SOURCE	/* needed to get the defines */
-#include <fcntl.h>	/* in glibc 2.2 this has the needed
-				   values defined */
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
-
-static volatile int event_fd;
-
-static void handler(int sig, siginfo_t *si, void *data)
-{
-	event_fd = si->si_fd;
-}
-
-int main(void)
-{
-	struct sigaction act;
-	int fd;
-
-	act.sa_sigaction = handler;
-	sigemptyset(&act.sa_mask);
-	act.sa_flags = SA_SIGINFO;
-	sigaction(SIGRTMIN + 1, &act, NULL);
-
-	fd = open(".", O_RDONLY);
-	fcntl(fd, F_SETSIG, SIGRTMIN + 1);
-	fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
-	/* we will now be notified if any of the files
-	   in "." is modified or new files are created */
-	while (1) {
-		pause();
-		printf("Got event on fd=%d\n", event_fd);
-	}
-}
diff --git a/tools/testing/selftests/filesystems/.gitignore b/tools/testing/selftests/filesystems/.gitignore
new file mode 100644
index 0000000..31d6e42
--- /dev/null
+++ b/tools/testing/selftests/filesystems/.gitignore
@@ -0,0 +1 @@
+dnotify_test
diff --git a/tools/testing/selftests/filesystems/Makefile b/tools/testing/selftests/filesystems/Makefile
new file mode 100644
index 0000000..0ab1130
--- /dev/null
+++ b/tools/testing/selftests/filesystems/Makefile
@@ -0,0 +1,7 @@
+TEST_PROGS := dnotify_test
+all: $(TEST_PROGS)
+
+include ../lib.mk
+
+clean:
+	rm -fr $(TEST_PROGS)
diff --git a/tools/testing/selftests/filesystems/dnotify_test.c b/tools/testing/selftests/filesystems/dnotify_test.c
new file mode 100644
index 0000000..8b37b4a
--- /dev/null
+++ b/tools/testing/selftests/filesystems/dnotify_test.c
@@ -0,0 +1,34 @@
+#define _GNU_SOURCE	/* needed to get the defines */
+#include <fcntl.h>	/* in glibc 2.2 this has the needed
+				   values defined */
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static volatile int event_fd;
+
+static void handler(int sig, siginfo_t *si, void *data)
+{
+	event_fd = si->si_fd;
+}
+
+int main(void)
+{
+	struct sigaction act;
+	int fd;
+
+	act.sa_sigaction = handler;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = SA_SIGINFO;
+	sigaction(SIGRTMIN + 1, &act, NULL);
+
+	fd = open(".", O_RDONLY);
+	fcntl(fd, F_SETSIG, SIGRTMIN + 1);
+	fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
+	/* we will now be notified if any of the files
+	   in "." is modified or new files are created */
+	while (1) {
+		pause();
+		printf("Got event on fd=%d\n", event_fd);
+	}
+}
-- 
2.7.4

^ permalink raw reply related

* RE: [net-next PATCH 00/11] iw_cxgb4,cxgbit: remove duplicate code
From: Steve Wise @ 2016-09-13 20:18 UTC (permalink / raw)
  To: 'Varun Prakash', davem
  Cc: netdev, linux-rdma, target-devel, nab, dledford, gerlitz.or,
	indranil
In-Reply-To: <cover.1473781521.git.varun@chelsio.com>

> This patch series removes duplicate code from
> iw_cxgb4 and cxgbit by adding common function
> definitions in libcxgb.
> 
> Please review.
> 
> Thanks
> Varun
> 
> Varun Prakash (11):
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_get_4tuple()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_find_route()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_find_route6()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_is_neg_adv()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_best_mtu()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_compute_wscale()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_mk_tid_release()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_mk_close_con_req()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_mk_abort_req()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_mk_abort_rpl()
>   libcxgb,iw_cxgb4,cxgbit: add cxgb_mk_rx_data_ack()
> 
>  drivers/infiniband/hw/cxgb4/Kconfig               |   1 +
>  drivers/infiniband/hw/cxgb4/Makefile              |   1 +
>  drivers/infiniband/hw/cxgb4/cm.c                  | 288
++++++----------------
>  drivers/infiniband/hw/cxgb4/iw_cxgb4.h            |   9 -
>  drivers/net/ethernet/chelsio/libcxgb/Makefile     |   4 +-
>  drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c | 149 +++++++++++
>  drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.h | 160 ++++++++++++
>  drivers/target/iscsi/cxgbit/cxgbit_cm.c           | 234 +++---------------
>  8 files changed, 428 insertions(+), 418 deletions(-)
>  create mode 100644 drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c
>  create mode 100644 drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.h
> 

This series looks good.

Reviewed-by: Steve Wise <swise@opengridcomputing.com>

Thanks Varun!

Steve

^ permalink raw reply

* [PATCH v2 0/6] Move runnable code (tests) from Documentation to selftests
From: Shuah Khan @ 2016-09-13 20:18 UTC (permalink / raw)
  To: corbet, richardcochran, wim, linux, nab, maheshkhanwalkar, timur,
	arnd, ghackmann, ben, thuth, christopher.s.hall, john.stultz,
	sergei.shtylyov, mpe, jani.nikula
  Cc: Shuah Khan, linux-doc, linux-kernel, netdev, linux-watchdog,
	linux-kselftest

Move runnable code (tests) from Documentation to selftests and update
Makefiles to work under selftests.

Jon Corbet and I discussed this in an email thread and as per that
discussion, this patch series moves all the tests that are under the
Documentation directory to selftests. There is more runnable code in
the form of examples and utils and that is going to be another patch
series. I moved just the tests and left the documentation files as is.

Checkpatch isn't happy with a few of the patches as some of the
renamed files have existing checkpatch errors and warnings. I am
working another patch series that will address those.

Changes since v1:
- Changes to Documentation/Makefile to remove test targets as the tests
  get moved.
- Combined patches based on Michael Ellerman's comments.
- Fixed change log errors based on Sergei Shtylyov's comments.
- Expanded to list to wider audience and people that responded
  with comments and ideas.
- Included ia64 and watchdog which I missed in the v1 series.

Shuah Khan (6):
  selftests: move dnotify_test from Documentation/filesystems
  selftests: move prctl tests from Documentation/prctl
  selftests: move ptp tests from Documentation/ptp
  selftests: move vDSO tests from Documentation/vDSO
  selftests: move ia64 tests from Documentation/ia64
  selftests: move watchdog tests from Documentation/watchdog

 Documentation/Makefile                             |   4 +-
 Documentation/filesystems/.gitignore               |   1 -
 Documentation/filesystems/Makefile                 |   5 -
 Documentation/filesystems/dnotify_test.c           |  34 --
 Documentation/ia64/.gitignore                      |   1 -
 Documentation/ia64/Makefile                        |   5 -
 Documentation/ia64/aliasing-test.c                 | 263 -----------
 Documentation/prctl/.gitignore                     |   3 -
 Documentation/prctl/Makefile                       |  10 -
 .../prctl/disable-tsc-ctxt-sw-stress-test.c        |  97 ----
 .../prctl/disable-tsc-on-off-stress-test.c         |  96 ----
 Documentation/prctl/disable-tsc-test.c             |  95 ----
 Documentation/ptp/.gitignore                       |   1 -
 Documentation/ptp/Makefile                         |   8 -
 Documentation/ptp/testptp.c                        | 523 ---------------------
 Documentation/ptp/testptp.mk                       |  33 --
 Documentation/vDSO/.gitignore                      |   2 -
 Documentation/vDSO/Makefile                        |  17 -
 Documentation/vDSO/parse_vdso.c                    | 269 -----------
 Documentation/vDSO/vdso_standalone_test_x86.c      | 128 -----
 Documentation/vDSO/vdso_test.c                     |  52 --
 Documentation/watchdog/src/.gitignore              |   1 -
 Documentation/watchdog/src/Makefile                |   2 +-
 Documentation/watchdog/src/watchdog-test.c         | 105 -----
 tools/testing/selftests/filesystems/.gitignore     |   1 +
 tools/testing/selftests/filesystems/Makefile       |   7 +
 tools/testing/selftests/filesystems/dnotify_test.c |  34 ++
 tools/testing/selftests/ia64/.gitignore            |   1 +
 tools/testing/selftests/ia64/Makefile              |   8 +
 tools/testing/selftests/ia64/aliasing-test.c       | 263 +++++++++++
 tools/testing/selftests/prctl/.gitignore           |   3 +
 tools/testing/selftests/prctl/Makefile             |  15 +
 .../prctl/disable-tsc-ctxt-sw-stress-test.c        |  97 ++++
 .../prctl/disable-tsc-on-off-stress-test.c         |  96 ++++
 tools/testing/selftests/prctl/disable-tsc-test.c   |  95 ++++
 tools/testing/selftests/ptp/.gitignore             |   1 +
 tools/testing/selftests/ptp/Makefile               |   8 +
 tools/testing/selftests/ptp/testptp.c              | 523 +++++++++++++++++++++
 tools/testing/selftests/ptp/testptp.mk             |  33 ++
 tools/testing/selftests/vDSO/.gitignore            |   2 +
 tools/testing/selftests/vDSO/Makefile              |  20 +
 tools/testing/selftests/vDSO/parse_vdso.c          | 269 +++++++++++
 .../selftests/vDSO/vdso_standalone_test_x86.c      | 128 +++++
 tools/testing/selftests/vDSO/vdso_test.c           |  52 ++
 tools/testing/selftests/watchdog/.gitignore        |   1 +
 tools/testing/selftests/watchdog/Makefile          |   8 +
 tools/testing/selftests/watchdog/watchdog-test.c   | 105 +++++
 47 files changed, 1773 insertions(+), 1752 deletions(-)
 delete mode 100644 Documentation/filesystems/.gitignore
 delete mode 100644 Documentation/filesystems/Makefile
 delete mode 100644 Documentation/filesystems/dnotify_test.c
 delete mode 100644 Documentation/ia64/.gitignore
 delete mode 100644 Documentation/ia64/Makefile
 delete mode 100644 Documentation/ia64/aliasing-test.c
 delete mode 100644 Documentation/prctl/.gitignore
 delete mode 100644 Documentation/prctl/Makefile
 delete mode 100644 Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c
 delete mode 100644 Documentation/prctl/disable-tsc-on-off-stress-test.c
 delete mode 100644 Documentation/prctl/disable-tsc-test.c
 delete mode 100644 Documentation/ptp/.gitignore
 delete mode 100644 Documentation/ptp/Makefile
 delete mode 100644 Documentation/ptp/testptp.c
 delete mode 100644 Documentation/ptp/testptp.mk
 delete mode 100644 Documentation/vDSO/.gitignore
 delete mode 100644 Documentation/vDSO/Makefile
 delete mode 100644 Documentation/vDSO/parse_vdso.c
 delete mode 100644 Documentation/vDSO/vdso_standalone_test_x86.c
 delete mode 100644 Documentation/vDSO/vdso_test.c
 delete mode 100644 Documentation/watchdog/src/watchdog-test.c
 create mode 100644 tools/testing/selftests/filesystems/.gitignore
 create mode 100644 tools/testing/selftests/filesystems/Makefile
 create mode 100644 tools/testing/selftests/filesystems/dnotify_test.c
 create mode 100644 tools/testing/selftests/ia64/.gitignore
 create mode 100644 tools/testing/selftests/ia64/Makefile
 create mode 100644 tools/testing/selftests/ia64/aliasing-test.c
 create mode 100644 tools/testing/selftests/prctl/.gitignore
 create mode 100644 tools/testing/selftests/prctl/Makefile
 create mode 100644 tools/testing/selftests/prctl/disable-tsc-ctxt-sw-stress-test.c
 create mode 100644 tools/testing/selftests/prctl/disable-tsc-on-off-stress-test.c
 create mode 100644 tools/testing/selftests/prctl/disable-tsc-test.c
 create mode 100644 tools/testing/selftests/ptp/.gitignore
 create mode 100644 tools/testing/selftests/ptp/Makefile
 create mode 100644 tools/testing/selftests/ptp/testptp.c
 create mode 100644 tools/testing/selftests/ptp/testptp.mk
 create mode 100644 tools/testing/selftests/vDSO/.gitignore
 create mode 100644 tools/testing/selftests/vDSO/Makefile
 create mode 100644 tools/testing/selftests/vDSO/parse_vdso.c
 create mode 100644 tools/testing/selftests/vDSO/vdso_standalone_test_x86.c
 create mode 100644 tools/testing/selftests/vDSO/vdso_test.c
 create mode 100644 tools/testing/selftests/watchdog/.gitignore
 create mode 100644 tools/testing/selftests/watchdog/Makefile
 create mode 100644 tools/testing/selftests/watchdog/watchdog-test.c

-- 
2.7.4

^ permalink raw reply

* Re: [PATCH v3] net: ip, diag -- Add diag interface for raw sockets
From: Rustad, Mark D @ 2016-09-13 20:18 UTC (permalink / raw)
  To: Greg
  Cc: Cyrill Gorcunov, Linux Kernel Network Developers, LKML,
	David Miller, dsa@cumulusnetworks.com, eric.dumazet@gmail.com,
	kuznet@ms2.inr.ac.ru, jmorris@namei.org, yoshfuji@linux-ipv6.org,
	kaber@trash.net, avagin@openvz.org, stephen@networkplumber.org
In-Reply-To: <1473791620.14269.2.camel@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]

Greg <gvrose8192@gmail.com> wrote:

> Someday Linux will be a modern OS that just includes IPV6 and forces a
> config option to NOT have it.
>
> That'll be great.  All the IS_ENABLED_(CONFIG_IPV6) scattered everywhere
> is nuts.
>
> </editorial comment>

Better wait until everyone at least *has* IPv6! I have yet to have IPv6  
deployed on any of my employer's networks or get IPv6 service from any ISP  
at my home. When I was at Apple in the 90's I was told that Apple needed  
IPv6 by next year or "we were dead". Well Apple nearly died, but IPv6 had  
nothing to do with that! And I still haven't experienced an IPv6  
deployment! Yeah, I have run it a bit point-to-point to resolve technical  
issues, but that isn't a "deployment" and not very interesting.

As much as we would like things to move faster, much of the world just  
doesn't. Witness the e1000 discussion today for example. Hardware doesn't  
vanish overnight, and I know that my ISP has a network full of CPE that  
doesn't do IPv6, so I'm not expecting their status to change any time soon.

It would be great though.
</pipedream>

--
Mark Rustad, Networking Division, Intel Corporation

[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 841 bytes --]

^ permalink raw reply

* pull-request: mac80211 2016-09-13
From: Johannes Berg @ 2016-09-13 20:03 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-wireless

Hi Dave,

We found a few more issues, I'm sending you small fixes here. The diffstat
would be even shorter, but one of Felix's patches has to move about 30 lines
of code, which makes it seem much bigger than it really is.

Let me know if there's any problem.

Thanks,
johannes



The following changes since commit 15543692a010192b4264ade0d45390e8bb3dc639:

  Merge tag 'mac80211-for-davem-2016-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 (2016-08-30 21:34:48 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2016-09-13

for you to fetch changes up to ad5987b47e96a0fb6d13fea250e936aed000093c:

  nl80211: validate number of probe response CSA counters (2016-09-13 20:19:27 +0200)

----------------------------------------------------------------
A few more fixes:
 * better mesh path fixing, from Thomas
 * fix TIM IE recalculation after sending frames
   to a sleeping station, from Felix
 * fix sequence number assignment while sending
   frames to a sleeping station, also from Felix
 * validate number of probe response CSA counter
   offsets, fixing a copy/paste bug (from myself)

----------------------------------------------------------------
Felix Fietkau (2):
      mac80211: fix tim recalculation after PS response
      mac80211: fix sequence number assignment for PS response frames

Johannes Berg (1):
      nl80211: validate number of probe response CSA counters

Pedersen, Thomas (1):
      mac80211: make mpath path fixing more robust

 net/mac80211/mesh_hwmp.c    |  3 ++-
 net/mac80211/mesh_pathtbl.c |  2 +-
 net/mac80211/sta_info.c     |  4 +--
 net/mac80211/tx.c           | 65 +++++++++++++++++++++++----------------------
 net/wireless/nl80211.c      |  2 +-
 5 files changed, 39 insertions(+), 37 deletions(-)

^ permalink raw reply

* Re: [PATCH v3 net 1/1] net sched actions: fix GETing actions
From: Jamal Hadi Salim @ 2016-09-13 19:47 UTC (permalink / raw)
  To: Cong Wang; +Cc: David Miller, Linux Kernel Network Developers
In-Reply-To: <CAM_iQpWDNzceBLqzVibyyqExk5MXajJCt6Yu3KkC2r2poU0DQQ@mail.gmail.com>

On 16-09-13 12:20 PM, Cong Wang wrote:
> On Mon, Sep 12, 2016 at 4:07 PM, Jamal Hadi Salim <jhs@mojatatu.com> wrote:
>> From: Jamal Hadi Salim <jhs@mojatatu.com>
>>
>> With the batch changes that translated transient actions into
>> a temporary list lost in the translation was the fact that
>> tcf_action_destroy() will eventually delete the action from
>> the permanent location if the refcount is zero.
>>
>> Example of what broke:
>> ...add a gact action to drop
>> sudo $TC actions add action drop index 10
>> ...now retrieve it, looks good
>> sudo $TC actions get action gact index 10
>> ...retrieve it again and find it is gone!
>> sudo $TC actions get action gact index 10
>>
>> Fixes:
>> commit 22dc13c837c3 ("net_sched: convert tcf_exts from list to pointer array"),
>> commit 824a7e8863b3 ("net_sched: remove an unnecessary list_del()")
>> commit f07fed82ad79 ("net_sched: remove the leftover cleanup_a()")
>>
>> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
>> ---
>>  net/sched/act_api.c | 19 +++++++++++++++++++
>>  1 file changed, 19 insertions(+)
>>
>> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
>> index d09d068..50720b1 100644
>> --- a/net/sched/act_api.c
>> +++ b/net/sched/act_api.c
>> @@ -592,6 +592,16 @@ err_out:
>>         return ERR_PTR(err);
>>  }
>>
>> +static void cleanup_a(struct list_head *actions, int ovr)
>> +{
>> +       struct tc_action *a;
>> +
>> +       list_for_each_entry(a, actions, list) {
>> +               if (ovr)
>> +                       a->tcfa_refcnt -= 1;
>> +       }
>> +}
>> +
>>  int tcf_action_init(struct net *net, struct nlattr *nla,
>>                                   struct nlattr *est, char *name, int ovr,
>>                                   int bind, struct list_head *actions)
>> @@ -612,8 +622,15 @@ int tcf_action_init(struct net *net, struct nlattr *nla,
>>                         goto err;
>>                 }
>>                 act->order = i;
>> +               if (ovr)
>> +                       act->tcfa_refcnt += 1;
>>                 list_add_tail(&act->list, actions);
>>         }
>> +
>> +       /* Remove the temp refcnt which was necessary to protect against
>> +        * destroying an existing action which was being replaced
>> +        */
>> +       cleanup_a(actions, ovr);
>>         return 0;
>
> I am still trying to understand this piece, so here you hold the refcnt
> for the same action used by the later iteration? Otherwise there is
> almost none user inbetween hold and release...
>
> The comment you add is not clear to me, we use RTNL/RCU to
> sync destroy and replace, so how could that happen?
>

I was worried about the destroy() hitting an error in that function.
If an action already existed and all we asked for was to
replace some attribute it would be deleted. It was the way the code was
before your changes so i just restored it to its original form.

cheers,
jamal

^ permalink raw reply

* Re: [Intel-wired-lan] [net-next PATCH v3 2/3] e1000: add initial XDP support
From: Rustad, Mark D @ 2016-09-13 19:14 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Eric Dumazet, Tom Herbert, Brenden Blanco,
	Linux Kernel Network Developers, intel-wired-lan,
	Jesper Dangaard Brouer, Cong Wang, David S. Miller, William Tu
In-Reply-To: <20160913182959.GA38950@ast-mbp.thefacebook.com>

[-- Attachment #1: Type: text/plain, Size: 1549 bytes --]

Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:

> On Tue, Sep 13, 2016 at 06:28:03PM +0000, Rustad, Mark D wrote:
>> Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>>
>>> I've looked through qemu and it appears only emulate e1k and tg3.
>>> The latter is still used in the field, so the risk of touching
>>> it is higher.
>>
>> I have no idea what makes you think that e1k is *not* "used in the field".
>> I grant you it probably is used more virtualized than not these days,  
>> but it
>> certainly exists and is used. You can still buy them new at Newegg for
>> goodness sakes!
>
> the point that it's only used virtualized, since PCI (not PCIE) have
> been long dead.

My point is precisely the opposite. It is a real device, it exists in real  
systems and it is used in those systems. I worked on embedded systems that  
ran Linux and used e1000 devices. I am sure they are still out there  
because customers are still paying for support of those systems.

Yes, PCI(-X) is absent from any current hardware and has been for some  
years now, but there is an installed base that continues. What part of that  
installed base updates software? I don't know, but I would not just assume  
that it is 0. I know that I updated the kernel on those embedded systems  
that I worked on when I was supporting them. Never at the bleeding edge,  
but generally hopping from one LTS kernel to another as needed.

The day is coming when all the motherboards with PCI(-X) will be gone, but  
I think it is still at least a few years off.

^ permalink raw reply

* Re: [PATCH net-next] MAINTAINERS: Add an entry for the core network DSA code
From: Andrew Lunn @ 2016-09-13 19:11 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: David Miller, Vivien Didelot, netdev
In-Reply-To: <b83db123-e76a-0f27-39f9-5352899b5346@gmail.com>

> F:	drivers/net/dsa/
> 
> Other than that, LGTM

I was a bit hesitant to go that far. We have individual entries for
b53 and mv88e6xxx, but not for bcm_sf2. But O.K, v2 on the way.

    Andrew

^ permalink raw reply

* Re: [PATCH 3/3] net-next: dsa: add new driver for qca8xxx family
From: John Crispin @ 2016-09-13 19:10 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot
  Cc: David S. Miller, Florian Fainelli, netdev, linux-kernel,
	qsdk-review
In-Reply-To: <20160913190708.GA26181@lunn.ch>



On 13/09/2016 21:07, Andrew Lunn wrote:
>> Since the former alternative is prefered, we may want to remove the
>> latter soon from DSA. If this phy_port_map is needed for that case, it'd
>> be preferable not to add it.
> 
> O.K, so maybe we should solve it the device tree way:
> 
> 
>        &mdio0 {
>        	      	phy_port1: phy@0 {
> 	      		reg = <0>;
> 		};
> 
>        	      	phy_port2: phy@1 {
> 	      		reg = <1>;
> 		};
> 
>        	      	phy_port3: phy@2 {
> 	      		reg = <2>;
> 		};
> 
>        	      	phy_port4: phy@3 {
> 	      		reg = <3>;
> 		};
> 
>        	      	phy_port5: phy@4 {
> 	      		reg = <4>;
> 		};
> 
> 		switch@0 {
>                        compatible = "qca,qca8337";
> 
>                        #address-cells = <1>;
>                        #size-cells = <0>;
>                        reg = <30>;
> 
>                        ports {
>                                port@11 {
>                                        reg = <11>;
>                                        label = "cpu";
>                                        ethernet = <&gmac1>;
>                                        phy-mode = "rgmii";
>                                };
> 
>                                port@1 {
>                                        reg = <1>;
>                                        label = "lan1";
> 				       phy-handle = <&phy_port1>;
>                                };
> 
>                                port@2 {
>                                        reg = <2>;
>                                        label = "lan2";
> 				       phy-handle = <&phy_port2>;
>                                };
> 
>                                port@3 {
>                                        reg = <3>;
>                                        label = "lan3";
> 				       phy-handle = <&phy_port3>;
>                                };
> 
>                                port@4 {
>                                        reg = <4>;
>                                        label = "lan4";
> 				       phy-handle = <&phy_port4>;
>                                };
>                        };
>                };
>        };
> 
> and remove the phy_read() and phy_write() functions.
> 
> 
>        Andrew
> 

Hi Andrew

ok, will give it a spin in the morning and add a note to the binding doc
explaining this. thanks for taking the time !

	John

^ permalink raw reply

* Re: [PATCH 3/3] net-next: dsa: add new driver for qca8xxx family
From: Andrew Lunn @ 2016-09-13 19:07 UTC (permalink / raw)
  To: Vivien Didelot
  Cc: John Crispin, David S. Miller, Florian Fainelli, netdev,
	linux-kernel, qsdk-review
In-Reply-To: <87twdjafmr.fsf@ketchup.mtl.sfl>

> Since the former alternative is prefered, we may want to remove the
> latter soon from DSA. If this phy_port_map is needed for that case, it'd
> be preferable not to add it.

O.K, so maybe we should solve it the device tree way:


       &mdio0 {
       	      	phy_port1: phy@0 {
	      		reg = <0>;
		};

       	      	phy_port2: phy@1 {
	      		reg = <1>;
		};

       	      	phy_port3: phy@2 {
	      		reg = <2>;
		};

       	      	phy_port4: phy@3 {
	      		reg = <3>;
		};

       	      	phy_port5: phy@4 {
	      		reg = <4>;
		};

		switch@0 {
                       compatible = "qca,qca8337";

                       #address-cells = <1>;
                       #size-cells = <0>;
                       reg = <30>;

                       ports {
                               port@11 {
                                       reg = <11>;
                                       label = "cpu";
                                       ethernet = <&gmac1>;
                                       phy-mode = "rgmii";
                               };

                               port@1 {
                                       reg = <1>;
                                       label = "lan1";
				       phy-handle = <&phy_port1>;
                               };

                               port@2 {
                                       reg = <2>;
                                       label = "lan2";
				       phy-handle = <&phy_port2>;
                               };

                               port@3 {
                                       reg = <3>;
                                       label = "lan3";
				       phy-handle = <&phy_port3>;
                               };

                               port@4 {
                                       reg = <4>;
                                       label = "lan4";
				       phy-handle = <&phy_port4>;
                               };
                       };
               };
       };

and remove the phy_read() and phy_write() functions.


       Andrew

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox