#ifndef UI_H #define UI_H #define _LGPL_SOURCE #include #include #include enum ui_event_id { UI_EVT_SCROLL_LEFT, UI_EVT_SCROLL_RIGHT, UI_EVT_SCROLL_UP, UI_EVT_SCROLL_DOWN, UI_EVT_SELECT_NEXT, }; enum ui_align { UI_ALIGN_LEFT, UI_ALIGN_RIGHT, }; struct ui_text { chtype *str; size_t slen; size_t len; }; struct ui_col { struct cds_list_head entry; uint32_t id; const char *name; uint32_t len; int pos; int color; enum ui_align align; }; struct ui_table { int y; int x; int rows_y; struct cds_list_head cols; struct ui_text *row; int hdr_color; int col_pad; int width; int height; int scroll_x; int scroll_y; const char *delim; int data_count; void * (* data_iter)(void *data); void (* data_bind)(struct ui_table *tbl, const void *data); }; struct ui_tab; enum ui_tab_event_t { UI_TAB_EVT_OPEN, UI_TAB_EVT_CLOSE, }; typedef void (* ui_tab_event_cb) (struct ui_tab *tab, enum ui_tab_event_t evt, uint32_t id); struct ui_tab { struct ui_col *active; struct ui_table tbl; int color; ui_tab_event_cb on_tab_event; }; extern void ui_table_init(struct ui_table *tbl); extern void ui_table_uninit(struct ui_table *tbl); extern void ui_table_clear(struct ui_table *tbl); extern void ui_table_pos_set(struct ui_table *tbl, int y, int x); extern void ui_table_height_set(struct ui_table *tbl, int height); extern void ui_table_col_add(struct ui_table *tbl, uint32_t id, const char *name, uint32_t len); extern void ui_table_col_color_set(struct ui_table *tbl, int col_id, int color); extern void ui_table_col_align_set(struct ui_table *tbl, int col_id, enum ui_align align); extern void ui_table_col_delim_set(struct ui_table *tbl, const char *delim); extern void ui_table_row_add(struct ui_table *tbl); extern void ui_table_row_show(struct ui_table *tbl); extern void ui_table_row_col_set(struct ui_table *tbl, uint32_t col_id, const char *str); extern void ui_table_header_color_set(struct ui_table *tbl, int color); extern void ui_table_header_print(struct ui_table *tbl); extern void ui_table_event_send(struct ui_table *tbl, enum ui_event_id id); extern void ui_table_data_iter_set(struct ui_table *tbl, void * (* iter)(void *data)); extern void ui_table_data_bind_set(struct ui_table *tbl, void (* bind)(struct ui_table *tbl, const void *data)); extern void ui_table_data_bind(struct ui_table *tbl); extern int ui_table_data_count(struct ui_table *tbl); extern int ui_table_scroll_height(struct ui_table *tbl); extern struct ui_tab *ui_tab_create(void); extern void ui_tab_destroy(struct ui_tab *tab); extern void ui_tab_pos_set(struct ui_tab *tab, int y, int x); extern void ui_tab_event_cb_set(struct ui_tab *tab, ui_tab_event_cb cb); extern void ui_tab_active_color_set(struct ui_tab *tab, int color); extern void ui_tab_show(struct ui_tab *tab); extern void ui_tab_entry_add(struct ui_tab *tab, uint32_t id, const char *name); extern void ui_tab_event_send(struct ui_tab *tab, uint32_t id); #endif /* UI_H */ xt:space:mode:
authorDan Streetman <ddstreet@ieee.org>2017-02-03 13:13:09 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-03 14:13:19 -0800
commitd7b028f56a971a2e4d8d7887540a144eeefcd4ab (patch)
tree511bb3eb86b7589ec0b96ec678df7e978f04766f
parent79c9089f97d37ffac88c3ddb6d359b2cf75058b7 (diff)
zswap: disable changing params if init fails
Add zswap_init_failed bool that prevents changing any of the module params, if init_zswap() fails, and set zswap_enabled to false. Change 'enabled' param to a callback, and check zswap_init_failed before allowing any change to 'enabled', 'zpool', or 'compressor' params. Any driver that is built-in to the kernel will not be unloaded if its init function returns error, and its module params remain accessible for users to change via sysfs. Since zswap uses param callbacks, which assume that zswap has been initialized, changing the zswap params after a failed initialization will result in WARNING due to the param callbacks expecting a pool to already exist. This prevents that by immediately exiting any of the param callbacks if initialization failed. This was reported here: https://marc.info/?l=linux-mm&m=147004228125528&w=4 And fixes this WARNING: [ 429.723476] WARNING: CPU: 0 PID: 5140 at mm/zswap.c:503 __zswap_pool_current+0x56/0x60 The warning is just noise, and not serious. However, when init fails, zswap frees all its percpu dstmem pages and its kmem cache. The kmem cache might be serious, if kmem_cache_alloc(NULL, gfp) has problems; but the percpu dstmem pages are definitely a problem, as they're used as temporary buffer for compressed pages before copying into place in the zpool. If the user does get zswap enabled after an init failure, then zswap will likely Oops on the first page it tries to compress (or worse, start corrupting memory). Fixes: 90b0fc26d5db ("zswap: change zpool/compressor at runtime") Link: http://lkml.kernel.org/r/20170124200259.16191-2-ddstreet@ieee.org Signed-off-by: Dan Streetman <dan.streetman@canonical.com> Reported-by: Marcin Miroslaw <marcin@mejor.pl> Cc: Seth Jennings <sjenning@redhat.com> Cc: Michal Hocko <mhocko@kernel.org> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com> Cc: Minchan Kim <minchan@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/zswap.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/mm/zswap.c b/mm/zswap.c