Re: svn commit: r333690 - in head/sys: dev/hwpmc kern sys

2018-05-16 Thread Jonathan T. Looney
On Wed, May 16, 2018 at 6:29 PM, Matt Macy  wrote:
>
> Author: mmacy
> Date: Wed May 16 22:29:20 2018
> New Revision: 333690
> URL: https://svnweb.freebsd.org/changeset/base/333690
>
> Log:
>   hwpmc: Implement per-thread counters for PMC sampling
>
>   This implements per-thread counters for PMC sampling. The thread
>   descriptors are stored in a list attached to the process descriptor.
>   These thread descriptors can store any per-thread information necessary
>   for current or future features. For the moment, they just store the
counters
>   for sampling.
>
>   The thread descriptors are created when the process descriptor is
created.
>   Additionally, thread descriptors are created or freed when threads
>   are started or stopped. Because the thread exit function is called in a
>   critical section, we can't directly free the thread descriptors. Hence,
>   they are freed to a cache, which is also used as a source of allocations
>   when needed for new threads.
>
>   Approved by:  sbruno
>   Obtained from:jtl
>   Sponsored by: Juniper Networks, Limelight Networks
>   Differential Revision:https://reviews.freebsd.org/D15335


Thanks!

Jonathan
___
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"


svn commit: r333690 - in head/sys: dev/hwpmc kern sys

2018-05-16 Thread Matt Macy
Author: mmacy
Date: Wed May 16 22:29:20 2018
New Revision: 333690
URL: https://svnweb.freebsd.org/changeset/base/333690

Log:
  hwpmc: Implement per-thread counters for PMC sampling
  
  This implements per-thread counters for PMC sampling. The thread
  descriptors are stored in a list attached to the process descriptor.
  These thread descriptors can store any per-thread information necessary
  for current or future features. For the moment, they just store the counters
  for sampling.
  
  The thread descriptors are created when the process descriptor is created.
  Additionally, thread descriptors are created or freed when threads
  are started or stopped. Because the thread exit function is called in a
  critical section, we can't directly free the thread descriptors. Hence,
  they are freed to a cache, which is also used as a source of allocations
  when needed for new threads.
  
  Approved by:  sbruno
  Obtained from:jtl
  Sponsored by: Juniper Networks, Limelight Networks
  Differential Revision:https://reviews.freebsd.org/D15335

Modified:
  head/sys/dev/hwpmc/hwpmc_mod.c
  head/sys/kern/kern_thr.c
  head/sys/kern/kern_thread.c
  head/sys/sys/pmc.h
  head/sys/sys/pmckern.h

Modified: head/sys/dev/hwpmc/hwpmc_mod.c
==
--- head/sys/dev/hwpmc/hwpmc_mod.c  Wed May 16 22:25:47 2018
(r333689)
+++ head/sys/dev/hwpmc/hwpmc_mod.c  Wed May 16 22:29:20 2018
(r333690)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -92,6 +93,7 @@ enum pmc_flags {
PMC_FLAG_NONE = 0x00, /* do nothing */
PMC_FLAG_REMOVE   = 0x01, /* atomically remove entry from hash */
PMC_FLAG_ALLOCATE = 0x02, /* add entry to hash if not found */
+   PMC_FLAG_NOWAIT   = 0x04, /* do not wait for mallocs */
 };
 
 /*
@@ -175,8 +177,22 @@ static LIST_HEAD(pmc_ownerhash, pmc_owner) *pmc_ownerh
 
 static LIST_HEAD(, pmc_owner)  pmc_ss_owners;
 
+/*
+ * List of free thread entries. This is protected by the spin
+ * mutex.
+ */
+static struct mtx pmc_threadfreelist_mtx;  /* spin mutex */
+static LIST_HEAD(, pmc_thread) pmc_threadfreelist;
+static int pmc_threadfreelist_entries=0;
+#defineTHREADENTRY_SIZE
\
+(sizeof(struct pmc_thread) + (md->pmd_npmc * sizeof(struct 
pmc_threadpmcstate)))
 
 /*
+ * Task to free thread descriptors
+ */
+static struct grouptask free_gtask;
+
+/*
  * A map of row indices to classdep structures.
  */
 static struct pmc_classdep **pmc_rowindex_to_classdep;
@@ -191,6 +207,8 @@ static int  pmc_debugflags_parse(char *newstr, char *fe
 #endif
 
 static int load(struct module *module, int cmd, void *arg);
+static voidpmc_add_thread_descriptors_from_proc(struct proc *p,
+struct pmc_process *pp);
 static int pmc_attach_process(struct proc *p, struct pmc *pm);
 static struct pmc *pmc_allocate_pmc_descriptor(void);
 static struct pmc_owner *pmc_allocate_owner_descriptor(struct proc *p);
@@ -205,12 +223,15 @@ static intpmc_detach_one_process(struct proc *p, 
stru
 int flags);
 static voidpmc_destroy_owner_descriptor(struct pmc_owner *po);
 static voidpmc_destroy_pmc_descriptor(struct pmc *pm);
+static voidpmc_destroy_process_descriptor(struct pmc_process *pp);
 static struct pmc_owner *pmc_find_owner_descriptor(struct proc *p);
 static int pmc_find_pmc(pmc_id_t pmcid, struct pmc **pm);
 static struct pmc *pmc_find_pmc_descriptor_in_process(struct pmc_owner *po,
 pmc_id_t pmc);
 static struct pmc_process *pmc_find_process_descriptor(struct proc *p,
 uint32_t mode);
+static struct pmc_thread *pmc_find_thread_descriptor(struct pmc_process *pp,
+struct thread *td, uint32_t mode);
 static voidpmc_force_context_switch(void);
 static voidpmc_link_target_process(struct pmc *pm,
 struct pmc_process *pp);
@@ -225,6 +246,8 @@ static void pmc_process_fork(void *arg, struct proc *p
 struct proc *p2, int n);
 static voidpmc_process_samples(int cpu, int soft);
 static voidpmc_release_pmc_descriptor(struct pmc *pmc);
+static voidpmc_process_thread_add(struct thread *td);
+static voidpmc_process_thread_delete(struct thread *td);
 static voidpmc_remove_owner(struct pmc_owner *po);
 static voidpmc_remove_process_descriptor(struct pmc_process *pp);
 static voidpmc_restore_cpu_binding(struct pmc_binding *pb);
@@ -233,6 +256,9 @@ static void pmc_select_cpu(int cpu);
 static int pmc_start(struct pmc *pm);
 static int pmc_stop(struct pmc *pm);
 static int pmc_syscall_handler(struct thread *td, void *syscall_args);
+static struct pmc_thread *pmc_thread_descriptor_pool_alloc(void);
+static voidpmc_thread_descriptor_pool_drain(void);
+static voidpmc_thread_descriptor_pool_free(struct pmc_thread *pt);
 static void