diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/core.c | 8 | ||||
| -rw-r--r-- | kernel/dma/Kconfig | 2 | ||||
| -rw-r--r-- | kernel/dma/contiguous.c | 5 | ||||
| -rw-r--r-- | kernel/dma/debug.c | 20 | ||||
| -rw-r--r-- | kernel/dma/pool.c | 4 | ||||
| -rw-r--r-- | kernel/printk/printk.c | 2 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer.c | 7 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 72 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 32 | ||||
| -rw-r--r-- | kernel/trace/trace_events_inject.c | 3 | ||||
| -rw-r--r-- | kernel/trace/trace_events_synth.c | 2 | 
12 files changed, 110 insertions, 49 deletions
| diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 0f8f036d8bd1..4e3ce0542e31 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -870,7 +870,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins  		       GFP_KERNEL);  	if (!pack)  		return NULL; -	pack->ptr = module_alloc(BPF_PROG_PACK_SIZE); +	pack->ptr = bpf_jit_alloc_exec(BPF_PROG_PACK_SIZE);  	if (!pack->ptr) {  		kfree(pack);  		return NULL; @@ -894,7 +894,7 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)  	mutex_lock(&pack_mutex);  	if (size > BPF_PROG_PACK_SIZE) {  		size = round_up(size, PAGE_SIZE); -		ptr = module_alloc(size); +		ptr = bpf_jit_alloc_exec(size);  		if (ptr) {  			bpf_fill_ill_insns(ptr, size);  			set_vm_flush_reset_perms(ptr); @@ -932,7 +932,7 @@ void bpf_prog_pack_free(struct bpf_binary_header *hdr)  	mutex_lock(&pack_mutex);  	if (hdr->size > BPF_PROG_PACK_SIZE) { -		module_memfree(hdr); +		bpf_jit_free_exec(hdr);  		goto out;  	} @@ -956,7 +956,7 @@ void bpf_prog_pack_free(struct bpf_binary_header *hdr)  	if (bitmap_find_next_zero_area(pack->bitmap, BPF_PROG_CHUNK_COUNT, 0,  				       BPF_PROG_CHUNK_COUNT, 0) == 0) {  		list_del(&pack->list); -		module_memfree(pack->ptr); +		bpf_jit_free_exec(pack->ptr);  		kfree(pack);  	}  out: diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig index 4c1e9a3c0ab6..f488997b0717 100644 --- a/kernel/dma/Kconfig +++ b/kernel/dma/Kconfig @@ -160,7 +160,7 @@ if  DMA_CMA  config DMA_NUMA_CMA  	bool "Enable separate DMA Contiguous Memory Area for NUMA Node" -	default NUMA +	depends on NUMA  	help  	  Enable this option to get numa CMA areas so that NUMA devices  	  can get local memory by DMA coherent APIs. diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c index 88c595e49e34..f005c66f378c 100644 --- a/kernel/dma/contiguous.c +++ b/kernel/dma/contiguous.c @@ -473,11 +473,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)  		return -EBUSY;  	} -	if (memblock_is_region_reserved(rmem->base, rmem->size)) { -		pr_info("Reserved memory: overlap with other memblock reserved region\n"); -		return -EBUSY; -	} -  	if (!of_get_flat_dt_prop(node, "reusable", NULL) ||  	    of_get_flat_dt_prop(node, "no-map", NULL))  		return -EINVAL; diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index f190651bcadd..06366acd27b0 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -637,15 +637,19 @@ static struct dma_debug_entry *__dma_entry_alloc(void)  	return entry;  } -static void __dma_entry_alloc_check_leak(void) +/* + * This should be called outside of free_entries_lock scope to avoid potential + * deadlocks with serial consoles that use DMA. + */ +static void __dma_entry_alloc_check_leak(u32 nr_entries)  { -	u32 tmp = nr_total_entries % nr_prealloc_entries; +	u32 tmp = nr_entries % nr_prealloc_entries;  	/* Shout each time we tick over some multiple of the initial pool */  	if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) {  		pr_info("dma_debug_entry pool grown to %u (%u00%%)\n", -			nr_total_entries, -			(nr_total_entries / nr_prealloc_entries)); +			nr_entries, +			(nr_entries / nr_prealloc_entries));  	}  } @@ -656,8 +660,10 @@ static void __dma_entry_alloc_check_leak(void)   */  static struct dma_debug_entry *dma_entry_alloc(void)  { +	bool alloc_check_leak = false;  	struct dma_debug_entry *entry;  	unsigned long flags; +	u32 nr_entries;  	spin_lock_irqsave(&free_entries_lock, flags);  	if (num_free_entries == 0) { @@ -667,13 +673,17 @@ static struct dma_debug_entry *dma_entry_alloc(void)  			pr_err("debugging out of memory - disabling\n");  			return NULL;  		} -		__dma_entry_alloc_check_leak(); +		alloc_check_leak = true; +		nr_entries = nr_total_entries;  	}  	entry = __dma_entry_alloc();  	spin_unlock_irqrestore(&free_entries_lock, flags); +	if (alloc_check_leak) +		__dma_entry_alloc_check_leak(nr_entries); +  #ifdef CONFIG_STACKTRACE  	entry->stack_len = stack_trace_save(entry->stack_entries,  					    ARRAY_SIZE(entry->stack_entries), diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c index 1acec2e22827..b481c48a31a6 100644 --- a/kernel/dma/pool.c +++ b/kernel/dma/pool.c @@ -135,9 +135,9 @@ encrypt_mapping:  remove_mapping:  #ifdef CONFIG_DMA_DIRECT_REMAP  	dma_common_free_remap(addr, pool_size); -#endif -free_page: __maybe_unused +free_page:  	__free_pages(page, order); +#endif  out:  	return ret;  } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 96fc38cb2e84..7e0b4dd02398 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -538,14 +538,12 @@ char *log_buf_addr_get(void)  {  	return log_buf;  } -EXPORT_SYMBOL_GPL(log_buf_addr_get);  /* Return log buffer size */  u32 log_buf_len_get(void)  {  	return log_buf_len;  } -EXPORT_SYMBOL_GPL(log_buf_len_get);  /*   * Define how much of the log buffer we could take at maximum. The value diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 78502d4c7214..a1651edc48d5 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2198,6 +2198,8 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,  				err = -ENOMEM;  				goto out_err;  			} + +			cond_resched();  		}  		cpus_read_lock(); @@ -2388,6 +2390,11 @@ rb_iter_head_event(struct ring_buffer_iter *iter)  	 */  	commit = rb_page_commit(iter_head_page);  	smp_rmb(); + +	/* An event needs to be at least 8 bytes in size */ +	if (iter->head > commit - 8) +		goto reset; +  	event = __rb_page_index(iter_head_page, iter->head);  	length = rb_event_length(event); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2b4ded753367..abaaf516fcae 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1772,7 +1772,7 @@ static void trace_create_maxlat_file(struct trace_array *tr,  	init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq);  	tr->d_max_latency = trace_create_file("tracing_max_latency",  					      TRACE_MODE_WRITE, -					      d_tracer, &tr->max_latency, +					      d_tracer, tr,  					      &tracing_max_lat_fops);  } @@ -1805,7 +1805,7 @@ void latency_fsnotify(struct trace_array *tr)  #define trace_create_maxlat_file(tr, d_tracer)				\  	trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,	\ -			  d_tracer, &tr->max_latency, &tracing_max_lat_fops) +			  d_tracer, tr, &tracing_max_lat_fops)  #endif @@ -4973,6 +4973,33 @@ int tracing_open_generic_tr(struct inode *inode, struct file *filp)  	return 0;  } +/* + * The private pointer of the inode is the trace_event_file. + * Update the tr ref count associated to it. + */ +int tracing_open_file_tr(struct inode *inode, struct file *filp) +{ +	struct trace_event_file *file = inode->i_private; +	int ret; + +	ret = tracing_check_open_get_tr(file->tr); +	if (ret) +		return ret; + +	filp->private_data = inode->i_private; + +	return 0; +} + +int tracing_release_file_tr(struct inode *inode, struct file *filp) +{ +	struct trace_event_file *file = inode->i_private; + +	trace_array_put(file->tr); + +	return 0; +} +  static int tracing_mark_open(struct inode *inode, struct file *filp)  {  	stream_open(inode, filp); @@ -6691,14 +6718,18 @@ static ssize_t  tracing_max_lat_read(struct file *filp, char __user *ubuf,  		     size_t cnt, loff_t *ppos)  { -	return tracing_nsecs_read(filp->private_data, ubuf, cnt, ppos); +	struct trace_array *tr = filp->private_data; + +	return tracing_nsecs_read(&tr->max_latency, ubuf, cnt, ppos);  }  static ssize_t  tracing_max_lat_write(struct file *filp, const char __user *ubuf,  		      size_t cnt, loff_t *ppos)  { -	return tracing_nsecs_write(filp->private_data, ubuf, cnt, ppos); +	struct trace_array *tr = filp->private_data; + +	return tracing_nsecs_write(&tr->max_latency, ubuf, cnt, ppos);  }  #endif @@ -7752,18 +7783,20 @@ static const struct file_operations tracing_thresh_fops = {  #ifdef CONFIG_TRACER_MAX_TRACE  static const struct file_operations tracing_max_lat_fops = { -	.open		= tracing_open_generic, +	.open		= tracing_open_generic_tr,  	.read		= tracing_max_lat_read,  	.write		= tracing_max_lat_write,  	.llseek		= generic_file_llseek, +	.release	= tracing_release_generic_tr,  };  #endif  static const struct file_operations set_tracer_fops = { -	.open		= tracing_open_generic, +	.open		= tracing_open_generic_tr,  	.read		= tracing_set_trace_read,  	.write		= tracing_set_trace_write,  	.llseek		= generic_file_llseek, +	.release	= tracing_release_generic_tr,  };  static const struct file_operations tracing_pipe_fops = { @@ -8956,12 +8989,33 @@ trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt,  	return cnt;  } +static int tracing_open_options(struct inode *inode, struct file *filp) +{ +	struct trace_option_dentry *topt = inode->i_private; +	int ret; + +	ret = tracing_check_open_get_tr(topt->tr); +	if (ret) +		return ret; + +	filp->private_data = inode->i_private; +	return 0; +} + +static int tracing_release_options(struct inode *inode, struct file *file) +{ +	struct trace_option_dentry *topt = file->private_data; + +	trace_array_put(topt->tr); +	return 0; +}  static const struct file_operations trace_options_fops = { -	.open = tracing_open_generic, +	.open = tracing_open_options,  	.read = trace_options_read,  	.write = trace_options_write,  	.llseek	= generic_file_llseek, +	.release = tracing_release_options,  };  /* @@ -9739,8 +9793,8 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)  			  tr, &tracing_mark_fops);  	file = __find_event_file(tr, "ftrace", "print"); -	if (file && file->dir) -		trace_create_file("trigger", TRACE_MODE_WRITE, file->dir, +	if (file && file->ef) +		eventfs_add_file("trigger", TRACE_MODE_WRITE, file->ef,  				  file, &event_trigger_fops);  	tr->trace_marker_file = file; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 5669dd1f90d9..77debe53f07c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -610,6 +610,8 @@ void tracing_reset_all_online_cpus(void);  void tracing_reset_all_online_cpus_unlocked(void);  int tracing_open_generic(struct inode *inode, struct file *filp);  int tracing_open_generic_tr(struct inode *inode, struct file *filp); +int tracing_open_file_tr(struct inode *inode, struct file *filp); +int tracing_release_file_tr(struct inode *inode, struct file *filp);  bool tracing_is_disabled(void);  bool tracer_tracing_is_on(struct trace_array *tr);  void tracer_tracing_on(struct trace_array *tr); diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index ed367d713be0..91951d038ba4 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -992,19 +992,6 @@ static void remove_subsystem(struct trace_subsystem_dir *dir)  static void remove_event_file_dir(struct trace_event_file *file)  { -	struct dentry *dir = file->dir; -	struct dentry *child; - -	if (dir) { -		spin_lock(&dir->d_lock);	/* probably unneeded */ -		list_for_each_entry(child, &dir->d_subdirs, d_child) { -			if (d_really_is_positive(child))	/* probably unneeded */ -				d_inode(child)->i_private = NULL; -		} -		spin_unlock(&dir->d_lock); - -		tracefs_remove(dir); -	}  	eventfs_remove(file->ef);  	list_del(&file->list);  	remove_subsystem(file->system); @@ -2103,9 +2090,10 @@ static const struct file_operations ftrace_set_event_notrace_pid_fops = {  };  static const struct file_operations ftrace_enable_fops = { -	.open = tracing_open_generic, +	.open = tracing_open_file_tr,  	.read = event_enable_read,  	.write = event_enable_write, +	.release = tracing_release_file_tr,  	.llseek = default_llseek,  }; @@ -2122,9 +2110,10 @@ static const struct file_operations ftrace_event_id_fops = {  };  static const struct file_operations ftrace_event_filter_fops = { -	.open = tracing_open_generic, +	.open = tracing_open_file_tr,  	.read = event_filter_read,  	.write = event_filter_write, +	.release = tracing_release_file_tr,  	.llseek = default_llseek,  }; @@ -2297,6 +2286,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name,  {  	struct event_subsystem *system, *iter;  	struct trace_subsystem_dir *dir; +	struct eventfs_file *ef;  	int res;  	/* First see if we did not already create this dir */ @@ -2329,13 +2319,14 @@ event_subsystem_dir(struct trace_array *tr, const char *name,  	} else  		__get_system(system); -	dir->ef = eventfs_add_subsystem_dir(name, parent); -	if (IS_ERR(dir->ef)) { +	ef = eventfs_add_subsystem_dir(name, parent); +	if (IS_ERR(ef)) {  		pr_warn("Failed to create system directory %s\n", name);  		__put_system(system);  		goto out_free;  	} +	dir->ef = ef;  	dir->tr = tr;  	dir->ref_count = 1;  	dir->nr_events = 1; @@ -2415,6 +2406,7 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)  	struct trace_event_call *call = file->event_call;  	struct eventfs_file *ef_subsystem = NULL;  	struct trace_array *tr = file->tr; +	struct eventfs_file *ef;  	const char *name;  	int ret; @@ -2431,12 +2423,14 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)  		return -ENOMEM;  	name = trace_event_name(call); -	file->ef = eventfs_add_dir(name, ef_subsystem); -	if (IS_ERR(file->ef)) { +	ef = eventfs_add_dir(name, ef_subsystem); +	if (IS_ERR(ef)) {  		pr_warn("Could not create tracefs '%s' directory\n", name);  		return -1;  	} +	file->ef = ef; +  	if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))  		eventfs_add_file("enable", TRACE_MODE_WRITE, file->ef, file,  				  &ftrace_enable_fops); diff --git a/kernel/trace/trace_events_inject.c b/kernel/trace/trace_events_inject.c index abe805d471eb..8650562bdaa9 100644 --- a/kernel/trace/trace_events_inject.c +++ b/kernel/trace/trace_events_inject.c @@ -328,7 +328,8 @@ event_inject_read(struct file *file, char __user *buf, size_t size,  }  const struct file_operations event_inject_fops = { -	.open = tracing_open_generic, +	.open = tracing_open_file_tr,  	.read = event_inject_read,  	.write = event_inject_write, +	.release = tracing_release_file_tr,  }; diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index 9897d0bfcab7..14cb275a0bab 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -337,7 +337,7 @@ static void print_synth_event_num_val(struct trace_seq *s,  		break;  	default: -		trace_seq_printf(s, print_fmt, name, val, space); +		trace_seq_printf(s, print_fmt, name, val->as_u64, space);  		break;  	}  } |