@@ -7046,12 +7046,21 @@ static void perf_aux_sample_output(struct perf_event *event,
70467046 ring_buffer_put (rb );
70477047}
70487048
7049+ /*
7050+ * A set of common sample data types saved even for non-sample records
7051+ * when event->attr.sample_id_all is set.
7052+ */
7053+ #define PERF_SAMPLE_ID_ALL (PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \
7054+ PERF_SAMPLE_ID | PERF_SAMPLE_STREAM_ID | \
7055+ PERF_SAMPLE_CPU | PERF_SAMPLE_IDENTIFIER)
7056+
70497057static void __perf_event_header__init_id (struct perf_event_header * header ,
70507058 struct perf_sample_data * data ,
70517059 struct perf_event * event ,
70527060 u64 sample_type )
70537061{
70547062 data -> type = event -> attr .sample_type ;
7063+ data -> sample_flags |= data -> type & PERF_SAMPLE_ID_ALL ;
70557064 header -> size += event -> id_header_size ;
70567065
70577066 if (sample_type & PERF_SAMPLE_TID ) {
@@ -7554,6 +7563,11 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs)
75547563 return callchain ?: & __empty_callchain ;
75557564}
75567565
7566+ static __always_inline u64 __cond_set (u64 flags , u64 s , u64 d )
7567+ {
7568+ return d * !!(flags & s );
7569+ }
7570+
75577571void perf_prepare_sample (struct perf_event_header * header ,
75587572 struct perf_sample_data * data ,
75597573 struct perf_event * event ,
@@ -7569,14 +7583,24 @@ void perf_prepare_sample(struct perf_event_header *header,
75697583 header -> misc |= perf_misc_flags (regs );
75707584
75717585 /*
7572- * Clear the sample flags that have already been done by the
7573- * PMU driver.
7586+ * Add the sample flags that are dependent to others. And clear the
7587+ * sample flags that have already been done by the PMU driver.
75747588 */
7575- filtered_sample_type = sample_type & ~data -> sample_flags ;
7589+ filtered_sample_type = sample_type ;
7590+ filtered_sample_type |= __cond_set (sample_type , PERF_SAMPLE_CODE_PAGE_SIZE ,
7591+ PERF_SAMPLE_IP );
7592+ filtered_sample_type |= __cond_set (sample_type , PERF_SAMPLE_DATA_PAGE_SIZE |
7593+ PERF_SAMPLE_PHYS_ADDR , PERF_SAMPLE_ADDR );
7594+ filtered_sample_type |= __cond_set (sample_type , PERF_SAMPLE_STACK_USER ,
7595+ PERF_SAMPLE_REGS_USER );
7596+ filtered_sample_type &= ~data -> sample_flags ;
7597+
75767598 __perf_event_header__init_id (header , data , event , filtered_sample_type );
75777599
7578- if (sample_type & ( PERF_SAMPLE_IP | PERF_SAMPLE_CODE_PAGE_SIZE ))
7600+ if (filtered_sample_type & PERF_SAMPLE_IP ) {
75797601 data -> ip = perf_instruction_pointer (regs );
7602+ data -> sample_flags |= PERF_SAMPLE_IP ;
7603+ }
75807604
75817605 if (filtered_sample_type & PERF_SAMPLE_CALLCHAIN )
75827606 perf_sample_save_callchain (data , event , regs );
@@ -7593,10 +7617,15 @@ void perf_prepare_sample(struct perf_event_header *header,
75937617 data -> sample_flags |= PERF_SAMPLE_BRANCH_STACK ;
75947618 }
75957619
7596- if (sample_type & ( PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER ) )
7620+ if (filtered_sample_type & PERF_SAMPLE_REGS_USER )
75977621 perf_sample_regs_user (& data -> regs_user , regs );
75987622
7599- if (sample_type & PERF_SAMPLE_REGS_USER ) {
7623+ /*
7624+ * It cannot use the filtered_sample_type here as REGS_USER can be set
7625+ * by STACK_USER (using __cond_set() above) and we don't want to update
7626+ * the dyn_size if it's not requested by users.
7627+ */
7628+ if ((sample_type & ~data -> sample_flags ) & PERF_SAMPLE_REGS_USER ) {
76007629 /* regs dump ABI info */
76017630 int size = sizeof (u64 );
76027631
@@ -7606,9 +7635,10 @@ void perf_prepare_sample(struct perf_event_header *header,
76067635 }
76077636
76087637 data -> dyn_size += size ;
7638+ data -> sample_flags |= PERF_SAMPLE_REGS_USER ;
76097639 }
76107640
7611- if (sample_type & PERF_SAMPLE_STACK_USER ) {
7641+ if (filtered_sample_type & PERF_SAMPLE_STACK_USER ) {
76127642 /*
76137643 * Either we need PERF_SAMPLE_STACK_USER bit to be always
76147644 * processed as the last one or have additional check added
@@ -7631,23 +7661,30 @@ void perf_prepare_sample(struct perf_event_header *header,
76317661
76327662 data -> stack_user_size = stack_size ;
76337663 data -> dyn_size += size ;
7664+ data -> sample_flags |= PERF_SAMPLE_STACK_USER ;
76347665 }
76357666
7636- if (filtered_sample_type & PERF_SAMPLE_WEIGHT_TYPE )
7667+ if (filtered_sample_type & PERF_SAMPLE_WEIGHT_TYPE ) {
76377668 data -> weight .full = 0 ;
7669+ data -> sample_flags |= PERF_SAMPLE_WEIGHT_TYPE ;
7670+ }
76387671
7639- if (filtered_sample_type & PERF_SAMPLE_DATA_SRC )
7672+ if (filtered_sample_type & PERF_SAMPLE_DATA_SRC ) {
76407673 data -> data_src .val = PERF_MEM_NA ;
7674+ data -> sample_flags |= PERF_SAMPLE_DATA_SRC ;
7675+ }
76417676
7642- if (filtered_sample_type & PERF_SAMPLE_TRANSACTION )
7677+ if (filtered_sample_type & PERF_SAMPLE_TRANSACTION ) {
76437678 data -> txn = 0 ;
7679+ data -> sample_flags |= PERF_SAMPLE_TRANSACTION ;
7680+ }
76447681
7645- if (sample_type & ( PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR | PERF_SAMPLE_DATA_PAGE_SIZE ) ) {
7646- if ( filtered_sample_type & PERF_SAMPLE_ADDR )
7647- data -> addr = 0 ;
7682+ if (filtered_sample_type & PERF_SAMPLE_ADDR ) {
7683+ data -> addr = 0 ;
7684+ data -> sample_flags |= PERF_SAMPLE_ADDR ;
76487685 }
76497686
7650- if (sample_type & PERF_SAMPLE_REGS_INTR ) {
7687+ if (filtered_sample_type & PERF_SAMPLE_REGS_INTR ) {
76517688 /* regs dump ABI info */
76527689 int size = sizeof (u64 );
76537690
@@ -7660,19 +7697,22 @@ void perf_prepare_sample(struct perf_event_header *header,
76607697 }
76617698
76627699 data -> dyn_size += size ;
7700+ data -> sample_flags |= PERF_SAMPLE_REGS_INTR ;
76637701 }
76647702
7665- if (sample_type & PERF_SAMPLE_PHYS_ADDR &&
7666- filtered_sample_type & PERF_SAMPLE_PHYS_ADDR )
7703+ if (filtered_sample_type & PERF_SAMPLE_PHYS_ADDR ) {
76677704 data -> phys_addr = perf_virt_to_phys (data -> addr );
7705+ data -> sample_flags |= PERF_SAMPLE_PHYS_ADDR ;
7706+ }
76687707
76697708#ifdef CONFIG_CGROUP_PERF
7670- if (sample_type & PERF_SAMPLE_CGROUP ) {
7709+ if (filtered_sample_type & PERF_SAMPLE_CGROUP ) {
76717710 struct cgroup * cgrp ;
76727711
76737712 /* protected by RCU */
76747713 cgrp = task_css_check (current , perf_event_cgrp_id , 1 )-> cgroup ;
76757714 data -> cgroup = cgroup_id (cgrp );
7715+ data -> sample_flags |= PERF_SAMPLE_CGROUP ;
76767716 }
76777717#endif
76787718
@@ -7681,13 +7721,17 @@ void perf_prepare_sample(struct perf_event_header *header,
76817721 * require PERF_SAMPLE_ADDR, kernel implicitly retrieve the data->addr,
76827722 * but the value will not dump to the userspace.
76837723 */
7684- if (sample_type & PERF_SAMPLE_DATA_PAGE_SIZE )
7724+ if (filtered_sample_type & PERF_SAMPLE_DATA_PAGE_SIZE ) {
76857725 data -> data_page_size = perf_get_page_size (data -> addr );
7726+ data -> sample_flags |= PERF_SAMPLE_DATA_PAGE_SIZE ;
7727+ }
76867728
7687- if (sample_type & PERF_SAMPLE_CODE_PAGE_SIZE )
7729+ if (filtered_sample_type & PERF_SAMPLE_CODE_PAGE_SIZE ) {
76887730 data -> code_page_size = perf_get_page_size (data -> ip );
7731+ data -> sample_flags |= PERF_SAMPLE_CODE_PAGE_SIZE ;
7732+ }
76897733
7690- if (sample_type & PERF_SAMPLE_AUX ) {
7734+ if (filtered_sample_type & PERF_SAMPLE_AUX ) {
76917735 u64 size ;
76927736
76937737 header -> size += sizeof (u64 ); /* size */
@@ -7705,6 +7749,7 @@ void perf_prepare_sample(struct perf_event_header *header,
77057749
77067750 WARN_ON_ONCE (size + header -> size > U16_MAX );
77077751 data -> dyn_size += size + sizeof (u64 ); /* size above */
7752+ data -> sample_flags |= PERF_SAMPLE_AUX ;
77087753 }
77097754
77107755 header -> size += data -> dyn_size ;
0 commit comments