#include <sched.h>
#include "util.h"
#include "../perf.h"
#include "cloexec.h"
#include "asm/bug.h"
#include "debug.h"
#include <unistd.h>
#include <asm/unistd.h>
#include <sys/syscall.h>

static unsigned long flag = PERF_FLAG_FD_CLOEXEC;

int __weak sched_getcpu(void)
{
#ifdef __NR_getcpu
	unsigned cpu;
	int err = syscall(__NR_getcpu, &cpu, NULL, NULL);
	if (!err)
		return cpu;
#else
	errno = ENOSYS;
#endif
	return -1;
}

static int perf_flag_probe(void)
{
	/* use 'safest' configuration as used in perf_evsel__fallback() */
	struct perf_event_attr attr = {
		.type = PERF_TYPE_SOFTWARE,
		.config = PERF_COUNT_SW_CPU_CLOCK,
		.exclude_kernel = 1,
	};
	int fd;
	int err;
	int cpu;
	pid_t pid = -1;
	char sbuf[STRERR_BUFSIZE];

	cpu = sched_getcpu();
	if (cpu < 0)
		cpu = 0;

	/*
	 * Using -1 for the pid is a workaround to avoid gratuitous jump label
	 * changes.
	 */
	while (1) {
		/* check cloexec flag */
		fd = sys_perf_event_open(&attr, pid, cpu, -1,
					 PERF_FLAG_FD_CLOEXEC);
		if (fd < 0 && pid == -1 && errno == EACCES) {
			pid = 0;
			continue;
		}
		break;
	}
	err = errno;

	if (fd >= 0) {
		close(fd);
		return 1;
	}

	WARN_ONCE(err != EINVAL && err != EBUSY,
		  "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",
		  err, str_error_r(err, sbuf, sizeof(sbuf)));

	/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
	while (1) {
		fd = sys_perf_event_open(&attr, pid, cpu, -1, 0);
		if (fd < 0 && pid == -1 && errno == EACCES) {
			pid = 0;
			continue;
		}
		break;
	}
	err = errno;

	if (fd >= 0)
		close(fd);

	if (WARN_ONCE(fd < 0 && err != EBUSY,
		      "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",
		      err, str_error_r(err, sbuf, sizeof(sbuf))))
		return -1;

	return 0;
}

unsigned long perf_event_open_cloexec_flag(void)
{
	static bool probed;

	if (!probed) {
		if (perf_flag_probe() <= 0)
			flag = 0;
		probed = true;
	}

	return flag;
}
0160ee9938'>diff</a></td><td class='form'><form class='right' method='get' action='/cgit.cgi/linux/net-next.git/log/net'>
<input type='hidden' name='id' value='c6d30e8391b85e00eb544e6cf047ee0160ee9938'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/cgit.cgi/linux/net-next.git/log/?id=c6d30e8391b85e00eb544e6cf047ee0160ee9938'>root</a>/<a href='/cgit.cgi/linux/net-next.git/log/net?id=c6d30e8391b85e00eb544e6cf047ee0160ee9938'>net</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th class='left'>Age</th><th class='left'>Commit message (<a href='/cgit.cgi/linux/net-next.git/log/net?id=c6d30e8391b85e00eb544e6cf047ee0160ee9938&amp;showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Files</th><th class='left'>Lines</th></tr>
<tr><td><span title='2017-02-07 13:07:47 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=51ce8bd4d17a761e1a90a34a1b5c9b762cce7553'>net: pending_confirm is not used anymore</a></td><td>Julian Anastasov</td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+0</span></td></tr>
<tr><td><span title='2017-02-07 13:07:47 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=0dec879f636f11b0ffda1cb5fd96a1754c59ead3'>net: use dst_confirm_neigh for UDP, RAW, ICMP, L2TP</a></td><td>Julian Anastasov</td><td>9</td><td><span class='deletions'>-19</span>/<span class='insertions'>+44</span></td></tr>
<tr><td><span title='2017-02-07 13:07:46 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=63fca65d08632fbec9d9b655f671cf08aa1aeeb8'>net: add confirm_neigh method to dst_ops</a></td><td>Julian Anastasov</td><td>3</td><td><span class='deletions'>-0</span>/<span class='insertions'>+54</span></td></tr>
<tr><td><span title='2017-02-07 13:07:46 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=c3a2e8370534f810cac6050169db0ed3e0f94f0b'>tcp: replace dst_confirm with sk_dst_confirm</a></td><td>Julian Anastasov</td><td>3</td><td><span class='deletions'>-14</span>/<span class='insertions'>+7</span></td></tr>
<tr><td><span title='2017-02-07 13:07:46 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=c86a773c78025f5b825bacd7b846f4fa60dc0317'>sctp: add dst_pending_confirm flag</a></td><td>Julian Anastasov</td><td>7</td><td><span class='deletions'>-12</span>/<span class='insertions'>+31</span></td></tr>
<tr><td><span title='2017-02-07 13:07:46 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=4ff0620354f2b39b9fe2a91c22c4de9d1fba0c8e'>net: add dst_pending_confirm flag to skbuff</a></td><td>Julian Anastasov</td><td>2</td><td><span class='deletions'>-1</span>/<span class='insertions'>+5</span></td></tr>
<tr><td><span title='2017-02-07 13:07:46 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=9b8805a325591cf5b6b9df71200de25a2bd721fd'>sock: add sk_dst_pending_confirm flag</a></td><td>Julian Anastasov</td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+2</span></td></tr>
<tr><td><span title='2017-02-07 11:42:35 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=bb4005bae3dab0dd21b239b1da193053151c07ba'>ipv6: sr: fix non static symbol warnings</a></td><td>Wei Yongjun</td><td>1</td><td><span class='deletions'>-4</span>/<span class='insertions'>+4</span></td></tr>
<tr><td><span title='2017-02-07 11:42:34 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=89d82452d1fd283bb1e313bc7a1f7c324362cf02'>net/sched: act_mirred: remove duplicated include from act_mirred.c</a></td><td>Wei Yongjun</td><td>1</td><td><span class='deletions'>-2</span>/<span class='insertions'>+0</span></td></tr>
<tr><td><span title='2017-02-07 10:51:45 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=71e0bbde0d88047f66b25721f69a441d46083748'>net: dsa: Add support for platform data</a></td><td>Florian Fainelli</td><td>1</td><td><span class='deletions'>-18</span>/<span class='insertions'>+84</span></td></tr>
<tr><td><span title='2017-02-07 10:51:45 -0500'>2017-02-07</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=14b89f36eed2993670906a3991bca496a5ebf1a6'>net: dsa: Rename and export dev_to_net_device()</a></td><td>Florian Fainelli</td><td>1</td><td><span class='deletions'>-2</span>/<span class='insertions'>+3</span></td></tr>
<tr><td><span title='2017-02-06 22:53:13 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=83a718d6294964fd1b227fa5f1ad001bc1fe7656'>bridge: fdb: write to used and updated at most once per jiffy</a></td><td>Nikolay Aleksandrov</td><td>2</td><td><span class='deletions'>-2</span>/<span class='insertions'>+4</span></td></tr>
<tr><td><span title='2017-02-06 22:53:13 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=1214628cb1868254e107230c9052f28ff9899b6a'>bridge: move write-heavy fdb members in their own cache line</a></td><td>Nikolay Aleksandrov</td><td>1</td><td><span class='deletions'>-4</span>/<span class='insertions'>+6</span></td></tr>
<tr><td><span title='2017-02-06 22:53:13 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=f7cdee8a79a1cb03fa9ca71b825e72f880b344e1'>bridge: move to workqueue gc</a></td><td>Nikolay Aleksandrov</td><td>10</td><td><span class='deletions'>-23</span>/<span class='insertions'>+29</span></td></tr>
<tr><td><span title='2017-02-06 22:53:13 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=1f90c7f3470580e24da25f6a6c1fb480ed9371ac'>bridge: modify bridge and port to have often accessed fields in one cache line</a></td><td>Nikolay Aleksandrov</td><td>1</td><td><span class='deletions'>-23</span>/<span class='insertions'>+20</span></td></tr>
<tr><td><span title='2017-02-06 16:53:29 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=04d3a4c6af52a58370795bc9f70dc15f51f8bb84'>net: dsa: introduce bridge notifier</a></td><td>Vivien Didelot</td><td>2</td><td><span class='deletions'>-11</span>/<span class='insertions'>+61</span></td></tr>
<tr><td><span title='2017-02-06 16:53:29 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=f515f192ab4f45bb695146b82432d63d98775787'>net: dsa: add switch notifier</a></td><td>Vivien Didelot</td><td>5</td><td><span class='deletions'>-0</span>/<span class='insertions'>+70</span></td></tr>
<tr><td><span title='2017-02-06 16:53:29 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=c5d35cb32cffa6e4c2db1cbd9a544e10a8d6fda9'>net: dsa: change state setter scope</a></td><td>Vivien Didelot</td><td>1</td><td><span class='deletions'>-6</span>/<span class='insertions'>+9</span></td></tr>
<tr><td><span title='2017-02-06 16:53:28 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=9c26542685130ef3b55cdb4e04eec0ac33376b41'>net: dsa: rollback bridging on error</a></td><td>Vivien Didelot</td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+13</span></td></tr>
<tr><td><span title='2017-02-06 16:53:28 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=8e92ab3a426e04dc355b196e3b4474f633025a3b'>net: dsa: simplify netdevice events handling</a></td><td>Vivien Didelot</td><td>1</td><td><span class='deletions'>-28</span>/<span class='insertions'>+16</span></td></tr>
<tr><td><span title='2017-02-06 16:53:28 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=88e4f0ca4e4e7760e4aad544789c5408219886d5'>net: dsa: move netdevice notifier registration</a></td><td>Vivien Didelot</td><td>3</td><td><span class='deletions'>-10</span>/<span class='insertions'>+26</span></td></tr>
<tr><td><span title='2017-02-06 16:33:29 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=d0d7b10b05945f40fefd4e60f457c61aefa3e9a9'>net-next: treewide use is_vlan_dev() helper function.</a></td><td>Parav Pandit</td><td>1</td><td><span class='deletions'>-1</span>/<span class='insertions'>+2</span></td></tr>
<tr><td><span title='2017-02-06 11:57:15 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=d15c9ede6123dbce14c17eb9ced229e488002735'>sctp: process fwd tsn chunk only when prsctp is enabled</a></td><td>Xin Long</td><td>1</td><td><span class='deletions'>-0</span>/<span class='insertions'>+6</span></td></tr>
<tr><td><span title='2017-02-06 11:25:57 -0500'>2017-02-06</span></td><td><a href='/cgit.cgi/linux/net-next.git/commit/net?id=a8eca326151ee1beac82a4fd86d9edad3a37aaed'>net: remove ndo_neigh_{construct, destroy} from stacked devices</a></td><td>Ido Schimmel