From 52771d979226607a8e1cc730f2d5c9e4ef9a5807 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 17 Apr 2023 00:34:54 +0000 Subject: [PATCH 01/27] BACKPORT: ASoC: expand snd_soc_dapm_mutex_lock/unlock() soc.h has snd_soc_dapm_mutex_lock/unlock() definition and many drivers are using it, but soc-dapm.c is not. 1st reason is snd_soc_dapm_mutex_lock/unlock() requests snd_soc_dapm_context pointer as parameter (A), but sometimes soc-dapm.c needs to use snd_soc_card (B). (A) static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm) { mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); } ^^^^^^^^^^ (B) mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); ^^^^ 2nd reason is it want to use SND_SOC_DAPM_CLASS_INIT for mutex_lock_nested(), but helper is using _RUNTIME (A). The conclusion is we want to use "dapm vs card" and "_RUNTIME vs _INIT" for dapm lock/unlock. To enable this selfish request, this patch uses _Generic macro. We can use snd_soc_dapm_mutex_lock/unlock() for both dapm and card case. snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_mutex_unlock(dapm); snd_soc_dapm_mutex_lock(card); snd_soc_dapm_mutex_unlock(card); Current soc-dapm.c is using both mutex_lock() and mutex_lock_nested(). This patch handles mutex_lock() as mutex_lock_nested(..., 0), in other words, handles below as same. mutex_lock(&card->dapm_mutex); mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); Because people might misunderstand that _init() is mutex initialization, this patch renames _INIT to _ROOT and adds new snd_soc_dapm_mutex_lock_root() for it. This patch also moves snd_soc_dapm_subclass definition from soc-dapm.h to soc.h to keep related code together. Because very complex soc.h vs soc-dapm.h relationship, it is difficult/impossible to define these helper into soc-dapm.h. Change-Id: I064718bbad9d053a0c84549be0a5e942f29a5dee Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87cz4hx3v0.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown Bug: 303236405 (cherry picked from commit 4a778bdc7afbc422bd513c4f1cd7a9faf4bebaab) [ Yixuan Jiang: Fix minor conflict ] Change-Id: I0fa12ec9272847c320ccdb0d69eceb2a03853d4e Signed-off-by: Yixuan Jiang --- include/sound/soc-dapm.h | 5 -- include/sound/soc.h | 60 ++++++++++++++++++-- sound/soc/soc-dapm.c | 119 +++++++++++++++++++-------------------- 3 files changed, 113 insertions(+), 71 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 9f2b1e6d858f..c0ad8e5158fe 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -560,11 +560,6 @@ enum snd_soc_dapm_type { SND_SOC_DAPM_TYPE_COUNT }; -enum snd_soc_dapm_subclass { - SND_SOC_DAPM_CLASS_INIT = 0, - SND_SOC_DAPM_CLASS_RUNTIME = 1, -}; - /* * DAPM audio route definition. * diff --git a/include/sound/soc.h b/include/sound/soc.h index bdb95cfceb75..93be66f34585 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1384,17 +1384,67 @@ extern struct dentry *snd_soc_debugfs_root; extern const struct dev_pm_ops snd_soc_pm_ops; -/* Helper functions */ -static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm) +/* + * DAPM helper functions + */ +enum snd_soc_dapm_subclass { + SND_SOC_DAPM_CLASS_ROOT = 0, + SND_SOC_DAPM_CLASS_RUNTIME = 1, +}; + +static inline void _snd_soc_dapm_mutex_lock_root_c(struct snd_soc_card *card) { - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_ROOT); } -static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm) +static inline void _snd_soc_dapm_mutex_lock_c(struct snd_soc_card *card) { - mutex_unlock(&dapm->card->dapm_mutex); + mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); } +static inline void _snd_soc_dapm_mutex_unlock_c(struct snd_soc_card *card) +{ + mutex_unlock(&card->dapm_mutex); +} + +static inline void _snd_soc_dapm_mutex_assert_held_c(struct snd_soc_card *card) +{ + lockdep_assert_held(&card->dapm_mutex); +} + +static inline void _snd_soc_dapm_mutex_lock_root_d(struct snd_soc_dapm_context *dapm) +{ + _snd_soc_dapm_mutex_lock_root_c(dapm->card); +} + +static inline void _snd_soc_dapm_mutex_lock_d(struct snd_soc_dapm_context *dapm) +{ + _snd_soc_dapm_mutex_lock_c(dapm->card); +} + +static inline void _snd_soc_dapm_mutex_unlock_d(struct snd_soc_dapm_context *dapm) +{ + _snd_soc_dapm_mutex_unlock_c(dapm->card); +} + +static inline void _snd_soc_dapm_mutex_assert_held_d(struct snd_soc_dapm_context *dapm) +{ + _snd_soc_dapm_mutex_assert_held_c(dapm->card); +} + +#define snd_soc_dapm_mutex_lock_root(x) _Generic((x), \ + struct snd_soc_card * : _snd_soc_dapm_mutex_lock_root_c, \ + struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_lock_root_d)(x) +#define snd_soc_dapm_mutex_lock(x) _Generic((x), \ + struct snd_soc_card * : _snd_soc_dapm_mutex_lock_c, \ + struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_lock_d)(x) +#define snd_soc_dapm_mutex_unlock(x) _Generic((x), \ + struct snd_soc_card * : _snd_soc_dapm_mutex_unlock_c, \ + struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_unlock_d)(x) +#define snd_soc_dapm_mutex_assert_held(x) _Generic((x), \ + struct snd_soc_card * : _snd_soc_dapm_mutex_assert_held_c, \ + struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_assert_held_d)(x) + #include #include #include diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 879cf1be67a9..05939c8aa237 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -150,7 +150,7 @@ static int dapm_down_seq[] = { static void dapm_assert_locked(struct snd_soc_dapm_context *dapm) { if (dapm->card && dapm->card->instantiated) - lockdep_assert_held(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_assert_held(dapm); } static void pop_wait(u32 pop_time) @@ -302,7 +302,7 @@ void dapm_mark_endpoints_dirty(struct snd_soc_card *card) { struct snd_soc_dapm_widget *w; - mutex_lock(&card->dapm_mutex); + snd_soc_dapm_mutex_lock_root(card); for_each_card_widgets(card, w) { if (w->is_ep) { @@ -314,7 +314,7 @@ void dapm_mark_endpoints_dirty(struct snd_soc_card *card) } } - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); } EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty); @@ -604,7 +604,7 @@ static void dapm_reset(struct snd_soc_card *card) { struct snd_soc_dapm_widget *w; - lockdep_assert_held(&card->dapm_mutex); + snd_soc_dapm_mutex_assert_held(card); memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); @@ -1310,7 +1310,7 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, int paths; int ret; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); if (stream == SNDRV_PCM_STREAM_PLAYBACK) { w = dai->playback_widget; @@ -1332,7 +1332,7 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, paths = ret; trace_snd_soc_dapm_connected(paths, stream); - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); return paths; } @@ -1968,7 +1968,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) enum snd_soc_bias_level bias; int ret; - lockdep_assert_held(&card->dapm_mutex); + snd_soc_dapm_mutex_assert_held(card); trace_snd_soc_dapm_start(card); @@ -2106,7 +2106,6 @@ static ssize_t dapm_widget_power_read_file(struct file *file, size_t count, loff_t *ppos) { struct snd_soc_dapm_widget *w = file->private_data; - struct snd_soc_card *card = w->dapm->card; enum snd_soc_dapm_direction dir, rdir; char *buf; int in, out; @@ -2117,7 +2116,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file, if (!buf) return -ENOMEM; - mutex_lock(&card->dapm_mutex); + snd_soc_dapm_mutex_lock_root(w->dapm); /* Supply widgets are not handled by is_connected_{input,output}_ep() */ if (w->is_supply) { @@ -2161,7 +2160,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file, } } - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(w->dapm); ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); @@ -2282,7 +2281,7 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card, int found = 0; bool connect; - lockdep_assert_held(&card->dapm_mutex); + snd_soc_dapm_mutex_assert_held(card); /* find dapm widget path assoc with kcontrol */ dapm_kcontrol_for_each_path(path, kcontrol) { @@ -2309,11 +2308,11 @@ int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm, struct snd_soc_card *card = dapm->card; int ret; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); card->update = update; ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); card->update = NULL; - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); if (ret > 0) snd_soc_dpcm_runtime_update(card); return ret; @@ -2328,7 +2327,7 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card, struct snd_soc_dapm_path *path; int found = 0; - lockdep_assert_held(&card->dapm_mutex); + snd_soc_dapm_mutex_assert_held(card); /* find dapm widget path assoc with kcontrol */ dapm_kcontrol_for_each_path(path, kcontrol) { @@ -2374,11 +2373,11 @@ int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm, struct snd_soc_card *card = dapm->card; int ret; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); card->update = update; ret = soc_dapm_mixer_update_power(card, kcontrol, connect, -1); card->update = NULL; - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); if (ret > 0) snd_soc_dpcm_runtime_update(card); return ret; @@ -2457,7 +2456,7 @@ static ssize_t dapm_widget_show(struct device *dev, struct snd_soc_dai *codec_dai; int i, count = 0; - mutex_lock(&rtd->card->dapm_mutex); + snd_soc_dapm_mutex_lock_root(rtd->card); for_each_rtd_codec_dais(rtd, i, codec_dai) { struct snd_soc_component *cmpnt = codec_dai->component; @@ -2465,7 +2464,7 @@ static ssize_t dapm_widget_show(struct device *dev, count = dapm_widget_show_component(cmpnt, buf, count); } - mutex_unlock(&rtd->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(rtd->card); return count; } @@ -2649,9 +2648,9 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) { int ret; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); ret = snd_soc_dapm_sync_unlocked(dapm); - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); @@ -2720,9 +2719,9 @@ int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); int ret; - mutex_lock_nested(&rtd->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(rtd->card); ret = dapm_update_dai_unlocked(substream, params, dai); - mutex_unlock(&rtd->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(rtd->card); return ret; } @@ -3112,7 +3111,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, { int i, ret = 0; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); for (i = 0; i < num; i++) { int r = snd_soc_dapm_add_route(dapm, route); if (r < 0) { @@ -3124,7 +3123,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, } route++; } - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } @@ -3143,12 +3142,12 @@ int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm, { int i; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); for (i = 0; i < num; i++) { snd_soc_dapm_del_route(dapm, route); route++; } - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return 0; } @@ -3221,14 +3220,14 @@ int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm, int i; int ret = 0; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); + snd_soc_dapm_mutex_lock_root(dapm); for (i = 0; i < num; i++) { int err = snd_soc_dapm_weak_route(dapm, route); if (err) ret = err; route++; } - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } @@ -3247,7 +3246,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) struct snd_soc_dapm_widget *w; unsigned int val; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); + snd_soc_dapm_mutex_lock_root(card); for_each_card_widgets(card, w) { @@ -3259,7 +3258,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) sizeof(struct snd_kcontrol *), GFP_KERNEL); if (!w->kcontrols) { - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); return -ENOMEM; } } @@ -3302,7 +3301,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) } dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP); - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); return 0; } EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); @@ -3320,7 +3319,6 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct snd_soc_card *card = dapm->card; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int reg = mc->reg; @@ -3331,7 +3329,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, unsigned int invert = mc->invert; unsigned int reg_val, val, rval = 0; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM) { reg_val = soc_dapm_read(dapm, reg); val = (reg_val >> shift) & mask; @@ -3348,7 +3346,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, if (snd_soc_volsw_is_stereo(mc)) rval = (reg_val >> width) & mask; } - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); if (invert) ucontrol->value.integer.value[0] = max - val; @@ -3406,7 +3404,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, rval = max - rval; } - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); /* This assumes field width < (bits in unsigned int / 2) */ if (width > sizeof(unsigned int) * 8 / 2) @@ -3448,7 +3446,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, card->update = NULL; } - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); if (ret > 0) snd_soc_dpcm_runtime_update(card); @@ -3470,17 +3468,16 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); - struct snd_soc_card *card = dapm->card; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int reg_val, val; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); if (e->reg != SND_SOC_NOPM && dapm_kcontrol_is_powered(kcontrol)) { reg_val = soc_dapm_read(dapm, e->reg); } else { reg_val = dapm_kcontrol_get_value(kcontrol); } - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); val = (reg_val >> e->shift_l) & e->mask; ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); @@ -3527,7 +3524,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, mask |= e->mask << e->shift_r; } - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); change = dapm_kcontrol_set_value(kcontrol, val); @@ -3548,7 +3545,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, card->update = NULL; } - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); if (ret > 0) snd_soc_dpcm_runtime_update(card); @@ -3589,12 +3586,12 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); const char *pin = (const char *)kcontrol->private_value; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); ucontrol->value.integer.value[0] = snd_soc_dapm_get_pin_status(&card->dapm, pin); - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); return 0; } @@ -3613,10 +3610,10 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, const char *pin = (const char *)kcontrol->private_value; int ret; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); ret = __snd_soc_dapm_set_pin(&card->dapm, pin, !!ucontrol->value.integer.value[0]); - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); snd_soc_dapm_sync(&card->dapm); return ret; @@ -3789,9 +3786,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_widget *w; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); w = snd_soc_dapm_new_control_unlocked(dapm, widget); - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return w; } @@ -3814,7 +3811,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, int i; int ret = 0; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); + snd_soc_dapm_mutex_lock_root(dapm); for (i = 0; i < num; i++) { struct snd_soc_dapm_widget *w = snd_soc_dapm_new_control_unlocked(dapm, widget); if (IS_ERR(w)) { @@ -3823,7 +3820,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, } widget++; } - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); @@ -4505,9 +4502,9 @@ void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, { struct snd_soc_card *card = rtd->card; - mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(card); soc_dapm_stream_event(rtd, stream, event); - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); } void snd_soc_dapm_stream_stop(struct snd_soc_pcm_runtime *rtd, int stream) @@ -4568,11 +4565,11 @@ int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) { int ret; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); ret = snd_soc_dapm_set_pin(dapm, pin, 1); - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } @@ -4636,11 +4633,11 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, { int ret; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } @@ -4680,11 +4677,11 @@ int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, { int ret; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); ret = snd_soc_dapm_set_pin(dapm, pin, 0); - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } @@ -4731,11 +4728,11 @@ int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) { int ret; - mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + snd_soc_dapm_mutex_lock(dapm); ret = snd_soc_dapm_set_pin(dapm, pin, 0); - mutex_unlock(&dapm->card->dapm_mutex); + snd_soc_dapm_mutex_unlock(dapm); return ret; } @@ -4832,7 +4829,7 @@ static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) LIST_HEAD(down_list); int powerdown = 0; - mutex_lock(&card->dapm_mutex); + snd_soc_dapm_mutex_lock_root(card); for_each_card_widgets(dapm->card, w) { if (w->dapm != dapm) @@ -4857,7 +4854,7 @@ static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) SND_SOC_BIAS_STANDBY); } - mutex_unlock(&card->dapm_mutex); + snd_soc_dapm_mutex_unlock(card); } /* From edfef8fdc901c65044ab3774d5f45d25f30d2f37 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 17 Apr 2023 00:35:07 +0000 Subject: [PATCH 02/27] BACKPORT: ASoC: expand snd_soc_dpcm_mutex_lock/unlock() soc-pcm.c has snd_soc_dpcm_mutex_lock/unlock(), but other files can't use it because it is static function. It requests snd_soc_pcm_runtime as parameter (A), but sometimes we want to use it by snd_soc_card (B). (A) static inline void snd_soc_dpcm_mutex_lock(struct snd_soc_pcm_runtime *rtd) { mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); } ^^^^^^^^^ (B) mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass); ^^^^ We want to use it with both "rtd" and "card" for dapm lock/unlock. To enable it, this patch uses _Generic macro. This patch makes snd_soc_dpcm_mutex_{un}lock() global function, and use it on each files. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87bkk1x3ud.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown Bug: 303236405 (cherry picked from commit 38e42f6d6c6702bbfc633fce9b579fb80cec2d59) [ Yixuan Jiang: Fix minor conflict ] Change-Id: Id942841c7ca1642b44b1229a7bf4ab1bc5373707 Signed-off-by: Yixuan Jiang --- include/sound/soc.h | 45 +++++++++++++++++++++++++++++++++++++++ sound/soc/soc-component.c | 12 +++++------ sound/soc/soc-compress.c | 42 ++++++++++++++++++------------------ sound/soc/soc-core.c | 4 ++-- sound/soc/soc-pcm.c | 17 ++------------- 5 files changed, 76 insertions(+), 44 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 93be66f34585..8ff2d1234188 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1445,6 +1445,51 @@ static inline void _snd_soc_dapm_mutex_assert_held_d(struct snd_soc_dapm_context struct snd_soc_card * : _snd_soc_dapm_mutex_assert_held_c, \ struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_assert_held_d)(x) +/* + * PCM helper functions + */ +static inline void _snd_soc_dpcm_mutex_lock_c(struct snd_soc_card *card) +{ + mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass); +} + +static inline void _snd_soc_dpcm_mutex_unlock_c(struct snd_soc_card *card) +{ + mutex_unlock(&card->pcm_mutex); +} + +static inline void _snd_soc_dpcm_mutex_assert_held_c(struct snd_soc_card *card) +{ + lockdep_assert_held(&card->pcm_mutex); +} + +static inline void _snd_soc_dpcm_mutex_lock_r(struct snd_soc_pcm_runtime *rtd) +{ + _snd_soc_dpcm_mutex_lock_c(rtd->card); +} + +static inline void _snd_soc_dpcm_mutex_unlock_r(struct snd_soc_pcm_runtime *rtd) +{ + _snd_soc_dpcm_mutex_unlock_c(rtd->card); +} + +static inline void _snd_soc_dpcm_mutex_assert_held_r(struct snd_soc_pcm_runtime *rtd) +{ + _snd_soc_dpcm_mutex_assert_held_c(rtd->card); +} + +#define snd_soc_dpcm_mutex_lock(x) _Generic((x), \ + struct snd_soc_card * : _snd_soc_dpcm_mutex_lock_c, \ + struct snd_soc_pcm_runtime * : _snd_soc_dpcm_mutex_lock_r)(x) + +#define snd_soc_dpcm_mutex_unlock(x) _Generic((x), \ + struct snd_soc_card * : _snd_soc_dpcm_mutex_unlock_c, \ + struct snd_soc_pcm_runtime * : _snd_soc_dpcm_mutex_unlock_r)(x) + +#define snd_soc_dpcm_mutex_assert_held(x) _Generic((x), \ + struct snd_soc_card * : _snd_soc_dpcm_mutex_assert_held_c, \ + struct snd_soc_pcm_runtime * : _snd_soc_dpcm_mutex_assert_held_r)(x) + #include #include #include diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index e12f8244242b..06cd88d51eea 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -530,7 +530,7 @@ int snd_soc_component_compr_get_caps(struct snd_compr_stream *cstream, struct snd_soc_component *component; int i, ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); for_each_rtd_components(rtd, i, component) { if (component->driver->compress_ops && @@ -541,7 +541,7 @@ int snd_soc_component_compr_get_caps(struct snd_compr_stream *cstream, } } - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return soc_component_ret(component, ret); } @@ -554,7 +554,7 @@ int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream, struct snd_soc_component *component; int i, ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); for_each_rtd_components(rtd, i, component) { if (component->driver->compress_ops && @@ -565,7 +565,7 @@ int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream, } } - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return soc_component_ret(component, ret); } @@ -618,7 +618,7 @@ int snd_soc_component_compr_copy(struct snd_compr_stream *cstream, struct snd_soc_component *component; int i, ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); for_each_rtd_components(rtd, i, component) { if (component->driver->compress_ops && @@ -629,7 +629,7 @@ int snd_soc_component_compr_copy(struct snd_compr_stream *cstream, } } - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return soc_component_ret(component, ret); } diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index d649b0cf4744..4a4c44791959 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -62,7 +62,7 @@ static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback) struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); if (!rollback) snd_soc_runtime_deactivate(rtd, stream); @@ -84,7 +84,7 @@ static int soc_compr_clean(struct snd_compr_stream *cstream, int rollback) if (!rollback) snd_soc_dapm_stream_stop(rtd, stream); - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); snd_soc_pcm_component_pm_runtime_put(rtd, cstream, rollback); @@ -107,7 +107,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) if (ret < 0) goto err_no_lock; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); ret = snd_soc_dai_compr_startup(cpu_dai, cstream); if (ret < 0) @@ -123,7 +123,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream) snd_soc_runtime_activate(rtd, stream); err: - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); err_no_lock: if (ret < 0) soc_compr_clean(cstream, 1); @@ -149,7 +149,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) if (ret < 0) goto be_err; - mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(fe); /* calculate valid and active FE <-> BE dpcms */ dpcm_process_paths(fe, stream, &list, 1); @@ -187,7 +187,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; snd_soc_runtime_activate(fe, stream); - mutex_unlock(&fe->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(fe); mutex_unlock(&fe->card->mutex); @@ -214,7 +214,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); - mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(fe); snd_soc_runtime_deactivate(fe, stream); fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; @@ -234,7 +234,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream) dpcm_be_disconnect(fe, stream); - mutex_unlock(&fe->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(fe); fe->dpcm[stream].runtime = NULL; @@ -256,7 +256,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ int ret; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); ret = snd_soc_component_compr_trigger(cstream, cmd); if (ret < 0) @@ -276,7 +276,7 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) } out: - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return ret; } @@ -334,7 +334,7 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream, int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ int ret; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); /* * First we call set_params for the CPU DAI, then the component @@ -359,14 +359,14 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream, /* cancel any delayed stream shutdown that is pending */ rtd->pop_wait = 0; - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); cancel_delayed_work_sync(&rtd->delayed_work); return 0; err: - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return ret; } @@ -411,9 +411,9 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream, ret = snd_soc_link_compr_set_params(cstream); if (ret < 0) goto out; - mutex_lock_nested(&fe->card->pcm_mutex, fe->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(fe); dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); - mutex_unlock(&fe->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(fe); fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; out: @@ -429,7 +429,7 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream, struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); int ret = 0; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); ret = snd_soc_dai_compr_get_params(cpu_dai, cstream, params); if (ret < 0) @@ -437,7 +437,7 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream, ret = snd_soc_component_compr_get_params(cstream, params); err: - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return ret; } @@ -447,7 +447,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes) struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); int ret; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); ret = snd_soc_dai_compr_ack(cpu_dai, cstream, bytes); if (ret < 0) @@ -455,7 +455,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes) ret = snd_soc_component_compr_ack(cstream, bytes); err: - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return ret; } @@ -466,7 +466,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream, int ret; struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); ret = snd_soc_dai_compr_pointer(cpu_dai, cstream, tstamp); if (ret < 0) @@ -474,7 +474,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream, ret = snd_soc_component_compr_pointer(cstream, tstamp); out: - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); return ret; } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 49e0fa7376ba..6c10f5934919 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -348,7 +348,7 @@ void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); int playback = SNDRV_PCM_STREAM_PLAYBACK; - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); + snd_soc_dpcm_mutex_lock(rtd); dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n", @@ -364,7 +364,7 @@ void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd) SND_SOC_DAPM_STREAM_STOP); } - mutex_unlock(&rtd->card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(rtd); } EXPORT_SYMBOL_GPL(snd_soc_close_delayed_work); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index f3964060a044..be388c6a4878 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -49,19 +49,6 @@ static inline int _soc_pcm_ret(struct snd_soc_pcm_runtime *rtd, return ret; } -static inline void snd_soc_dpcm_mutex_lock(struct snd_soc_pcm_runtime *rtd) -{ - mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); -} - -static inline void snd_soc_dpcm_mutex_unlock(struct snd_soc_pcm_runtime *rtd) -{ - mutex_unlock(&rtd->card->pcm_mutex); -} - -#define snd_soc_dpcm_mutex_assert_held(rtd) \ - lockdep_assert_held(&(rtd)->card->pcm_mutex) - static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd, int stream) { @@ -2652,7 +2639,7 @@ int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) struct snd_soc_pcm_runtime *fe; int ret = 0; - mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass); + snd_soc_dpcm_mutex_lock(card); /* shutdown all old paths first */ for_each_card_rtds(card, fe) { ret = soc_dpcm_fe_runtime_update(fe, 0); @@ -2668,7 +2655,7 @@ int snd_soc_dpcm_runtime_update(struct snd_soc_card *card) } out: - mutex_unlock(&card->pcm_mutex); + snd_soc_dpcm_mutex_unlock(card); return ret; } EXPORT_SYMBOL_GPL(snd_soc_dpcm_runtime_update); From 6cb2109589c8f61c7211966c2c3cd789e075ba90 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 17 Apr 2023 00:35:18 +0000 Subject: [PATCH 03/27] BACKPORT: ASoC: add snd_soc_card_mutex_lock/unlock() ASoC need to use card->mutex with _INIT or _RUNTIME, but there is no helper function for it. This patch adds its helper function and use it. Because people might misunderstand that _init() is mutex initialization, this patch renames _INIT to _ROOT and adds new snd_soc_card_mutex_lock_root() for it. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87a5zlx3tw.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown Bug: 303236405 (cherry picked from commit 0f3b818486796ec8895fa4ccdf15edb759bff40a) [ Yixuan Jiang: Fix minor conflict ] Change-Id: Ie8cd7aeeea759576423760d25b5fb5b2c9ae0d12 Signed-off-by: Yixuan Jiang --- include/sound/soc-card.h | 17 ++++++++++++++++- sound/soc/soc-compress.c | 18 +++++++++--------- sound/soc/soc-core.c | 4 ++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/include/sound/soc-card.h b/include/sound/soc-card.h index 9d31a5c0db33..fc94dfb0021f 100644 --- a/include/sound/soc-card.h +++ b/include/sound/soc-card.h @@ -9,10 +9,25 @@ #define __SOC_CARD_H enum snd_soc_card_subclass { - SND_SOC_CARD_CLASS_INIT = 0, + SND_SOC_CARD_CLASS_ROOT = 0, SND_SOC_CARD_CLASS_RUNTIME = 1, }; +static inline void snd_soc_card_mutex_lock_root(struct snd_soc_card *card) +{ + mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_ROOT); +} + +static inline void snd_soc_card_mutex_lock(struct snd_soc_card *card) +{ + mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); +} + +static inline void snd_soc_card_mutex_unlock(struct snd_soc_card *card) +{ + mutex_unlock(&card->mutex); +} + struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, const char *name); int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 4a4c44791959..614780f5fbc7 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -142,7 +142,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ int ret; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_card_mutex_lock(fe->card); fe->dpcm[stream].runtime = fe_substream->runtime; ret = dpcm_path_get(fe, stream, &list); @@ -189,7 +189,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) snd_soc_runtime_activate(fe, stream); snd_soc_dpcm_mutex_unlock(fe); - mutex_unlock(&fe->card->mutex); + snd_soc_card_mutex_unlock(fe->card); return 0; @@ -201,7 +201,7 @@ out: dpcm_path_put(&list); be_err: fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; - mutex_unlock(&fe->card->mutex); + snd_soc_card_mutex_unlock(fe->card); return ret; } @@ -212,7 +212,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream) struct snd_soc_dpcm *dpcm; int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_card_mutex_lock(fe->card); snd_soc_dpcm_mutex_lock(fe); snd_soc_runtime_deactivate(fe, stream); @@ -244,7 +244,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream) snd_soc_dai_compr_shutdown(cpu_dai, cstream, 0); - mutex_unlock(&fe->card->mutex); + snd_soc_card_mutex_unlock(fe->card); return 0; } @@ -291,7 +291,7 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd) cmd == SND_COMPR_TRIGGER_DRAIN) return snd_soc_component_compr_trigger(cstream, cmd); - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_card_mutex_lock(fe->card); ret = snd_soc_dai_compr_trigger(cpu_dai, cstream, cmd); if (ret < 0) @@ -322,7 +322,7 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd) out: fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; - mutex_unlock(&fe->card->mutex); + snd_soc_card_mutex_unlock(fe->card); return ret; } @@ -380,7 +380,7 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream, int stream = cstream->direction; /* SND_COMPRESS_xxx is same as SNDRV_PCM_STREAM_xxx */ int ret; - mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + snd_soc_card_mutex_lock(fe->card); /* * Create an empty hw_params for the BE as the machine driver must @@ -418,7 +418,7 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream, out: fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; - mutex_unlock(&fe->card->mutex); + snd_soc_card_mutex_unlock(fe->card); return ret; } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 6c10f5934919..a04d323a004f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1936,7 +1936,7 @@ static int snd_soc_bind_card(struct snd_soc_card *card) int ret, i; mutex_lock(&client_mutex); - mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT); + snd_soc_card_mutex_lock_root(card); snd_soc_dapm_init(&card->dapm, card, NULL); @@ -2093,7 +2093,7 @@ probe_end: if (ret < 0) soc_cleanup_card_resources(card); - mutex_unlock(&card->mutex); + snd_soc_card_mutex_unlock(card); mutex_unlock(&client_mutex); return ret; From 855511173d50c5fc173e1487c19058069dd58dc0 Mon Sep 17 00:00:00 2001 From: yixuanjiang Date: Mon, 19 Jun 2023 11:31:27 +0800 Subject: [PATCH 04/27] UPSTREAM: ASoC: soc-compress: Fix deadlock in soc_compr_open_fe [ Upstream commit 2222214749a9969e09454b9ba7febfdfb09c1c8d ] Modify the error handling flow by release lock. The require mutex will keep holding if open fail. Fixes: aa9ff6a4955f ("ASoC: soc-compress: Reposition and add pcm_mutex") Signed-off-by: yixuanjiang Link: https://lore.kernel.org/r/20230619033127.2522477-1-yixuanjiang@google.com Signed-off-by: Mark Brown Bug: 303236405 Change-Id: I64172b9d40b061239c7e4087f34759c3b23cfa6a Signed-off-by: Yixuan Jiang --- sound/soc/soc-compress.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 614780f5fbc7..2da4c991eb09 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -199,6 +199,7 @@ open_err: snd_soc_dai_compr_shutdown(cpu_dai, cstream, 1); out: dpcm_path_put(&list); + snd_soc_dpcm_mutex_unlock(fe); be_err: fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; snd_soc_card_mutex_unlock(fe->card); From eb67f583227fd814a207ea88897ff6d6cf5665c1 Mon Sep 17 00:00:00 2001 From: Rick Yiu Date: Tue, 21 Nov 2023 07:18:24 +0000 Subject: [PATCH 05/27] ANDROID: sched: Add trace_android_rvh_set_user_nice_locked We will need vendor hook of set_user_nice with lock to avoid race condition. Bug: 300872872 Change-Id: I24fc1e13cc6578dcc418d956a5146ad29ff76a56 Signed-off-by: Rick Yiu --- include/trace/hooks/sched.h | 4 ++++ kernel/sched/core.c | 4 ++++ kernel/sched/vendor_hooks.c | 1 + 3 files changed, 9 insertions(+) diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index b0b039453951..4037082dbebd 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -76,6 +76,10 @@ DECLARE_RESTRICTED_HOOK(android_rvh_set_user_nice, TP_PROTO(struct task_struct *p, long *nice, bool *allowed), TP_ARGS(p, nice, allowed), 1); +DECLARE_RESTRICTED_HOOK(android_rvh_set_user_nice_locked, + TP_PROTO(struct task_struct *p, long *nice), + TP_ARGS(p, nice), 1); + DECLARE_RESTRICTED_HOOK(android_rvh_setscheduler, TP_PROTO(struct task_struct *p), TP_ARGS(p), 1); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index c9acddf7eff1..8a1564c2268f 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7234,6 +7234,10 @@ void set_user_nice(struct task_struct *p, long nice) rq = task_rq_lock(p, &rf); update_rq_clock(rq); + trace_android_rvh_set_user_nice_locked(p, &nice); + if (task_nice(p) == nice) + goto out_unlock; + /* * The RT priorities are set via sched_setscheduler(), but we still * allow the 'normal' nice value to be set - but as expected diff --git a/kernel/sched/vendor_hooks.c b/kernel/sched/vendor_hooks.c index 5a195b3e9602..b65262774f73 100644 --- a/kernel/sched/vendor_hooks.c +++ b/kernel/sched/vendor_hooks.c @@ -25,6 +25,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_finish_prio_fork); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_rtmutex_force_update); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_rtmutex_prepare_setprio); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_user_nice); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_user_nice_locked); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_setscheduler); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_find_busiest_group); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_dump_throttled_rt_tasks); From 4326c78f8494fb9d73c2cd00a65c37aeb1ea6e64 Mon Sep 17 00:00:00 2001 From: Rick Yiu Date: Thu, 30 Nov 2023 12:53:22 +0000 Subject: [PATCH 06/27] ANDROID: Update the ABI symbol list Adding the following symbols: - __traceiter_android_rvh_set_user_nice_locked - __tracepoint_android_rvh_set_user_nice_locked Bug: 300872872 Change-Id: I370d51175efc5ac1bf997bc2425cff8ab00b9b19 Signed-off-by: Rick Yiu --- android/abi_gki_aarch64.stg | 27 +++++++++++++++++++++++++++ android/abi_gki_aarch64_pixel | 2 ++ 2 files changed, 29 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index a2ec42443c2f..a35df8de61b0 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -318656,6 +318656,13 @@ function { parameter_id: 0x18bd6530 parameter_id: 0x386883b9 } +function { + id: 0x9bd6b82b + return_type_id: 0x6720d32f + parameter_id: 0x18bd6530 + parameter_id: 0x1d19a9d5 + parameter_id: 0x3593bec8 +} function { id: 0x9bd6fb19 return_type_id: 0x6720d32f @@ -334509,6 +334516,15 @@ elf_symbol { type_id: 0x9bd6ff14 full_name: "__traceiter_android_rvh_set_user_nice" } +elf_symbol { + id: 0x559e0725 + name: "__traceiter_android_rvh_set_user_nice_locked" + is_defined: true + symbol_type: FUNCTION + crc: 0x4563d02a + type_id: 0x9bd6b82b + full_name: "__traceiter_android_rvh_set_user_nice_locked" +} elf_symbol { id: 0xa01b20ce name: "__traceiter_android_rvh_setscheduler" @@ -338460,6 +338476,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_android_rvh_set_user_nice" } +elf_symbol { + id: 0x74f29f73 + name: "__tracepoint_android_rvh_set_user_nice_locked" + is_defined: true + symbol_type: OBJECT + crc: 0x8f0ba608 + type_id: 0x18ccbd2c + full_name: "__tracepoint_android_rvh_set_user_nice_locked" +} elf_symbol { id: 0xe48123a4 name: "__tracepoint_android_rvh_setscheduler" @@ -397124,6 +397149,7 @@ interface { symbol_id: 0x615c3dcf symbol_id: 0xc6a28b4a symbol_id: 0x9b0cc890 + symbol_id: 0x559e0725 symbol_id: 0xa01b20ce symbol_id: 0x73c83ef4 symbol_id: 0x46515de8 @@ -397563,6 +397589,7 @@ interface { symbol_id: 0xde470f79 symbol_id: 0xc5049f7c symbol_id: 0x42fff08e + symbol_id: 0x74f29f73 symbol_id: 0xe48123a4 symbol_id: 0x00b7ed82 symbol_id: 0xe8cacf26 diff --git a/android/abi_gki_aarch64_pixel b/android/abi_gki_aarch64_pixel index 45a5c3b85377..e6ca8e996123 100644 --- a/android/abi_gki_aarch64_pixel +++ b/android/abi_gki_aarch64_pixel @@ -2184,6 +2184,7 @@ __traceiter_android_rvh_setscheduler __traceiter_android_rvh_set_task_cpu __traceiter_android_rvh_set_user_nice + __traceiter_android_rvh_set_user_nice_locked __traceiter_android_rvh_typec_tcpci_get_vbus __traceiter_android_rvh_uclamp_eff_get __traceiter_android_rvh_update_blocked_fair @@ -2290,6 +2291,7 @@ __tracepoint_android_rvh_setscheduler __tracepoint_android_rvh_set_task_cpu __tracepoint_android_rvh_set_user_nice + __tracepoint_android_rvh_set_user_nice_locked __tracepoint_android_rvh_typec_tcpci_get_vbus __tracepoint_android_rvh_uclamp_eff_get __tracepoint_android_rvh_update_blocked_fair From aa71a02cf3629795f761e3234e8bb252c76d3e78 Mon Sep 17 00:00:00 2001 From: Fangzheng Zhang Date: Fri, 24 Nov 2023 11:05:14 +0800 Subject: [PATCH 07/27] ANDROID: vendor_hooks: mm: add hook to count the number pages allocated for each slab Add the tracing interface on the kmalloc_large allocation path, which can detect the number of pages allocated by the slab, and if exceeds a threshold, trigger a panic or other actions. Bug: 312897430 Change-Id: I5575d0e4f91dab1c6e074f3e907fee8ea9327fd7 Signed-off-by: Fangzheng Zhang --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/mm.h | 3 +++ mm/slab_common.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 71a349221f3f..8425e8709b41 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -363,3 +363,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_get_folio); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_blk_mq_rw_recovery); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sd_update_bus_speed_mode); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_slab_folio_alloced); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kmalloc_large_alloced); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 6b9353695660..0bd0c34e17b9 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -199,6 +199,9 @@ DECLARE_HOOK(android_vh_adjust_kvmalloc_flags, DECLARE_HOOK(android_vh_slab_folio_alloced, TP_PROTO(unsigned int order, gfp_t flags), TP_ARGS(order, flags)); +DECLARE_HOOK(android_vh_kmalloc_large_alloced, + TP_PROTO(struct page *page, unsigned int order, gfp_t flags), + TP_ARGS(page, order, flags)); #endif /* _TRACE_HOOK_MM_H */ /* This part must be outside protection */ diff --git a/mm/slab_common.c b/mm/slab_common.c index cfbfb2c580ea..f64ebceb848c 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1102,6 +1102,8 @@ static void *__kmalloc_large_node(size_t size, gfp_t flags, int node) PAGE_SIZE << order); } + trace_android_vh_kmalloc_large_alloced(page, order, flags); + ptr = kasan_kmalloc_large(ptr, size, flags); /* As ptr might get tagged, call kmemleak hook after KASAN. */ kmemleak_alloc(ptr, size, 1, flags); From 088f228370abb418a28b6bb4532eb5de2831c983 Mon Sep 17 00:00:00 2001 From: Fangzheng Zhang Date: Tue, 28 Nov 2023 16:24:14 +0800 Subject: [PATCH 08/27] ANDROID: update symbol for unisoc whitelist Add kmalloc_large_order_alloced 1 function symbol(s) added 'int __traceiter_android_vh_kmalloc_large_alloced(void*, struct page*, unsigned int, gfp_t)' 1 variable symbol(s) added 'struct tracepoint __tracepoint_android_vh_kmalloc_large_alloced' Bug: 312897430 Change-Id: I586956fb3cef3d9c5dde63f08de9ed46715163c6 Signed-off-by: Fangzheng Zhang --- android/abi_gki_aarch64.stg | 28 ++++++++++++++++++++++++++++ android/abi_gki_aarch64_unisoc | 2 ++ 2 files changed, 30 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index a35df8de61b0..0b6c517f8c4b 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -317649,6 +317649,14 @@ function { parameter_id: 0x33756485 parameter_id: 0x18bd6530 } +function { + id: 0x9ba710db + return_type_id: 0x6720d32f + parameter_id: 0x18bd6530 + parameter_id: 0x06835e9c + parameter_id: 0x4585663f + parameter_id: 0xf1a6dfed +} function { id: 0x9ba7ef87 return_type_id: 0x6720d32f @@ -335713,6 +335721,15 @@ elf_symbol { type_id: 0x9bdcdd91 full_name: "__traceiter_android_vh_killed_process" } +elf_symbol { + id: 0x19426a78 + name: "__traceiter_android_vh_kmalloc_large_alloced" + is_defined: true + symbol_type: FUNCTION + crc: 0x7ae87fb2 + type_id: 0x9ba710db + full_name: "__traceiter_android_vh_kmalloc_large_alloced" +} elf_symbol { id: 0x18fde973 name: "__traceiter_android_vh_kswapd_per_node" @@ -339673,6 +339690,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_android_vh_killed_process" } +elf_symbol { + id: 0xb1f4423e + name: "__tracepoint_android_vh_kmalloc_large_alloced" + is_defined: true + symbol_type: OBJECT + crc: 0x82040c9f + type_id: 0x18ccbd2c + full_name: "__tracepoint_android_vh_kmalloc_large_alloced" +} elf_symbol { id: 0x586a06d1 name: "__tracepoint_android_vh_kswapd_per_node" @@ -397282,6 +397308,7 @@ interface { symbol_id: 0x4dca46cc symbol_id: 0xf83fbd26 symbol_id: 0xe261e8cc + symbol_id: 0x19426a78 symbol_id: 0x18fde973 symbol_id: 0x0992491b symbol_id: 0xe19d2bf8 @@ -397722,6 +397749,7 @@ interface { symbol_id: 0x62c13726 symbol_id: 0xafbca760 symbol_id: 0xa48390ca + symbol_id: 0xb1f4423e symbol_id: 0x586a06d1 symbol_id: 0x8bd577fd symbol_id: 0xda2d53f2 diff --git a/android/abi_gki_aarch64_unisoc b/android/abi_gki_aarch64_unisoc index 5fd0eff13ff8..166d1680d508 100644 --- a/android/abi_gki_aarch64_unisoc +++ b/android/abi_gki_aarch64_unisoc @@ -715,6 +715,7 @@ __traceiter_android_vh_cpu_idle_exit __traceiter_android_vh_enable_thermal_power_throttle __traceiter_android_vh_get_thermal_zone_device + __traceiter_android_vh_kmalloc_large_alloced __traceiter_android_vh_modify_thermal_request_freq __traceiter_android_vh_modify_thermal_target_freq __traceiter_android_vh_regmap_update @@ -795,6 +796,7 @@ __tracepoint_android_vh_cpu_idle_exit __tracepoint_android_vh_enable_thermal_power_throttle __tracepoint_android_vh_get_thermal_zone_device + __tracepoint_android_vh_kmalloc_large_alloced __tracepoint_android_vh_modify_thermal_request_freq __tracepoint_android_vh_modify_thermal_target_freq __tracepoint_android_vh_regmap_update From e92b866e226a61d5e3e100dd5c6e211de0b697df Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Wed, 3 May 2023 13:53:49 -0700 Subject: [PATCH 09/27] UPSTREAM: f2fs: maintain six open zones for zoned devices To keep six open zone constraints, make them not to be open over six open zones. Change-Id: If5d02581073f90db4cadd8f928cef9abc5bac8a7 Signed-off-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim (cherry picked from commit e067dc3c6b9c419bac43c6a0be2d85f44681f863) --- fs/f2fs/data.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/f2fs/f2fs.h | 5 +++++ 2 files changed, 63 insertions(+) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8a3aaaca081d..2dab40e70e88 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -384,6 +384,17 @@ static void f2fs_write_end_io(struct bio *bio) bio_put(bio); } +#ifdef CONFIG_BLK_DEV_ZONED +static void f2fs_zone_write_end_io(struct bio *bio) +{ + struct f2fs_bio_info *io = (struct f2fs_bio_info *)bio->bi_private; + + bio->bi_private = io->bi_private; + complete(&io->zone_wait); + f2fs_write_end_io(bio); +} +#endif + struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi, block_t blk_addr, sector_t *sector) { @@ -644,6 +655,11 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi) INIT_LIST_HEAD(&sbi->write_io[i][j].io_list); INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list); init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock); +#ifdef CONFIG_BLK_DEV_ZONED + init_completion(&sbi->write_io[i][j].zone_wait); + sbi->write_io[i][j].zone_pending_bio = NULL; + sbi->write_io[i][j].bi_private = NULL; +#endif } } @@ -970,6 +986,26 @@ alloc_new: return 0; } +#ifdef CONFIG_BLK_DEV_ZONED +static bool is_end_zone_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr) +{ + int devi = 0; + + if (f2fs_is_multi_device(sbi)) { + devi = f2fs_target_device_index(sbi, blkaddr); + if (blkaddr < FDEV(devi).start_blk || + blkaddr > FDEV(devi).end_blk) { + f2fs_err(sbi, "Invalid block %x", blkaddr); + return false; + } + blkaddr -= FDEV(devi).start_blk; + } + return bdev_zoned_model(FDEV(devi).bdev) == BLK_ZONED_HM && + f2fs_blkz_is_seq(sbi, devi, blkaddr) && + (blkaddr % sbi->blocks_per_blkz == sbi->blocks_per_blkz - 1); +} +#endif + void f2fs_submit_page_write(struct f2fs_io_info *fio) { struct f2fs_sb_info *sbi = fio->sbi; @@ -980,6 +1016,16 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) f2fs_bug_on(sbi, is_read_io(fio->op)); f2fs_down_write(&io->io_rwsem); + +#ifdef CONFIG_BLK_DEV_ZONED + if (f2fs_sb_has_blkzoned(sbi) && btype < META && io->zone_pending_bio) { + wait_for_completion_io(&io->zone_wait); + bio_put(io->zone_pending_bio); + io->zone_pending_bio = NULL; + io->bi_private = NULL; + } +#endif + next: if (fio->in_list) { spin_lock(&io->io_lock); @@ -1043,6 +1089,18 @@ skip: if (fio->in_list) goto next; out: +#ifdef CONFIG_BLK_DEV_ZONED + if (f2fs_sb_has_blkzoned(sbi) && btype < META && + is_end_zone_blkaddr(sbi, fio->new_blkaddr)) { + bio_get(io->bio); + reinit_completion(&io->zone_wait); + io->bi_private = io->bio->bi_private; + io->bio->bi_private = io; + io->bio->bi_end_io = f2fs_zone_write_end_io; + io->zone_pending_bio = io->bio; + __submit_merged_bio(io); + } +#endif if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) || !f2fs_is_checkpoint_ready(sbi)) __submit_merged_bio(io); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 16cdf97a1f58..42b6f36f7db2 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1217,6 +1217,11 @@ struct f2fs_bio_info { struct bio *bio; /* bios to merge */ sector_t last_block_in_bio; /* last block number */ struct f2fs_io_info fio; /* store buffered io info. */ +#ifdef CONFIG_BLK_DEV_ZONED + struct completion zone_wait; /* condition value for the previous open zone to close */ + struct bio *zone_pending_bio; /* pending bio for the previous zone */ + void *bi_private; /* previous bi_private for pending bio */ +#endif struct f2fs_rwsem io_rwsem; /* blocking op for bio */ spinlock_t io_lock; /* serialize DATA/NODE IOs */ struct list_head io_list; /* track fios */ From c9e29a00732a5dcae4593b91147427a3e148bc54 Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Fri, 5 May 2023 13:40:00 -0700 Subject: [PATCH 10/27] UPSTREAM: f2fs: close unused open zones while mounting Zoned UFS allows only 6 open zones at the same time, so we need to take care of the count of open zones while mounting. Change-Id: Ie197b9e9e47b3397446ce2cf97168c9f68fea431 Signed-off-by: Daeho Jeong Signed-off-by: Jaegeuk Kim (cherry picked from commit 04abeb699ddce800837c4039ea1cc7d4d139bb36) --- fs/f2fs/segment.c | 53 +++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 49216099f3a4..1202028676ea 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4812,40 +4812,49 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi, break; } - /* - * If last valid block is beyond the write pointer, report the - * inconsistency. This inconsistency does not cause write error - * because the zone will not be selected for write operation until - * it get discarded. Just report it. - */ - if (last_valid_block >= wp_block) { - f2fs_notice(sbi, "Valid block beyond write pointer: " - "valid block[0x%x,0x%x] wp[0x%x,0x%x]", - GET_SEGNO(sbi, last_valid_block), - GET_BLKOFF_FROM_SEG0(sbi, last_valid_block), - wp_segno, wp_blkoff); + // The write pointer matches with the valid blocks + if (last_valid_block + 1 == wp_block) return 0; - } - /* - * If there is no valid block in the zone and if write pointer is - * not at zone start, reset the write pointer. - */ - if (last_valid_block + 1 == zone_block && zone->wp != zone->start) { + if (last_valid_block + 1 == zone_block) { + /* + * If there is no valid block in the zone and if write pointer + * is not at zone start, reset the write pointer. + */ f2fs_notice(sbi, "Zone without valid block has non-zero write " "pointer. Reset the write pointer: wp[0x%x,0x%x]", wp_segno, wp_blkoff); ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block, zone->len >> log_sectors_per_block); - if (ret) { + if (ret) f2fs_err(sbi, "Discard zone failed: %s (errno=%d)", fdev->path, ret); - return ret; - } + + return ret; } - return 0; + /* + * If there are valid blocks and the write pointer doesn't + * match with them, we need to report the inconsistency and + * fill the zone till the end to close the zone. This inconsistency + * does not cause write error because the zone will not be selected + * for write operation until it get discarded. + */ + f2fs_notice(sbi, "Valid blocks are not aligned with write pointer: " + "valid block[0x%x,0x%x] wp[0x%x,0x%x]", + GET_SEGNO(sbi, last_valid_block), + GET_BLKOFF_FROM_SEG0(sbi, last_valid_block), + wp_segno, wp_blkoff); + + ret = blkdev_issue_zeroout(fdev->bdev, zone->wp, + zone->len - (zone->wp - zone->start), + GFP_NOFS, 0); + if (ret) + f2fs_err(sbi, "Fill up zone failed: %s (errno=%d)", + fdev->path, ret); + + return ret; } static struct f2fs_dev_info *get_target_zoned_dev(struct f2fs_sb_info *sbi, From b2d3a555d3dc88de330b4987da363f7fe0dfe7b7 Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Mon, 12 Jun 2023 16:32:03 -0700 Subject: [PATCH 11/27] UPSTREAM: f2fs: check zone write pointer points to the end of zone We don't need to report an issue, when the zone write pointer already points to the end of the zone, since the zone mismatch is already taken care. Change-Id: Ifc967abe44521cd239ebac509353c25e36cc7a18 Signed-off-by: Daeho Jeong Signed-off-by: Jaegeuk Kim (cherry picked from commit c9667b19e2cf13735fe2620f9d97b788897cd4af) --- fs/f2fs/segment.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 1202028676ea..b38ab17da93c 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4812,8 +4812,12 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi, break; } - // The write pointer matches with the valid blocks - if (last_valid_block + 1 == wp_block) + /* + * The write pointer matches with the valid blocks or + * already points to the end of the zone. + */ + if ((last_valid_block + 1 == wp_block) || + (zone->wp == zone->start + zone->len)) return 0; if (last_valid_block + 1 == zone_block) { From 88cccede6d8077bb02b9afd5c020a51fb44ad1bd Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Thu, 24 Aug 2023 09:08:31 -0700 Subject: [PATCH 12/27] UPSTREAM: f2fs: use finish zone command when closing a zone Use the finish zone command first when a zone should be closed. Change-Id: Ie38800c2787392980f7914ad10b5f92f6d59e99b Signed-off-by: Daeho Jeong Signed-off-by: Jaegeuk Kim (cherry picked from commit 3b7166121402a5062d18dcf4e3bce083fb9e4201) --- fs/f2fs/segment.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index b38ab17da93c..5ad68261efaa 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4851,12 +4851,19 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi, GET_BLKOFF_FROM_SEG0(sbi, last_valid_block), wp_segno, wp_blkoff); - ret = blkdev_issue_zeroout(fdev->bdev, zone->wp, - zone->len - (zone->wp - zone->start), - GFP_NOFS, 0); - if (ret) - f2fs_err(sbi, "Fill up zone failed: %s (errno=%d)", - fdev->path, ret); + ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH, + zone->start, zone->len, GFP_NOFS); + if (ret == -EOPNOTSUPP) { + ret = blkdev_issue_zeroout(fdev->bdev, zone->wp, + zone->len - (zone->wp - zone->start), + GFP_NOFS, 0); + if (ret) + f2fs_err(sbi, "Fill up zone failed: %s (errno=%d)", + fdev->path, ret); + } else if (ret) { + f2fs_err(sbi, "Finishing zone failed: %s (errno=%d)", + fdev->path, ret); + } return ret; } From ccbea4f4586165e43a71dff803cde0615940177c Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Tue, 10 Oct 2023 12:36:28 -0700 Subject: [PATCH 13/27] UPSTREAM: f2fs: clean up zones when not successfully unmounted We can't trust write pointers when the previous mount was not successfully unmounted. Change-Id: If67696db9ab820a805711b43cabb50c796c9f75f Signed-off-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim (cherry picked from commit 9f792ab8e33de727993bbd84ece892e72de18c85) --- fs/f2fs/segment.c | 90 +++++++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 5ad68261efaa..fa63bb6bd4e3 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4813,22 +4813,31 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi, } /* - * The write pointer matches with the valid blocks or - * already points to the end of the zone. + * When safely unmounted in the previous mount, we can trust write + * pointers. Otherwise, finish zones. */ - if ((last_valid_block + 1 == wp_block) || - (zone->wp == zone->start + zone->len)) - return 0; + if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { + /* + * The write pointer matches with the valid blocks or + * already points to the end of the zone. + */ + if ((last_valid_block + 1 == wp_block) || + (zone->wp == zone->start + zone->len)) + return 0; + } if (last_valid_block + 1 == zone_block) { - /* - * If there is no valid block in the zone and if write pointer - * is not at zone start, reset the write pointer. - */ - f2fs_notice(sbi, - "Zone without valid block has non-zero write " - "pointer. Reset the write pointer: wp[0x%x,0x%x]", - wp_segno, wp_blkoff); + if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { + /* + * If there is no valid block in the zone and if write + * pointer is not at zone start, reset the write + * pointer. + */ + f2fs_notice(sbi, + "Zone without valid block has non-zero write " + "pointer. Reset the write pointer: wp[0x%x,0x%x]", + wp_segno, wp_blkoff); + } ret = __f2fs_issue_discard_zone(sbi, fdev->bdev, zone_block, zone->len >> log_sectors_per_block); if (ret) @@ -4838,18 +4847,20 @@ static int check_zone_write_pointer(struct f2fs_sb_info *sbi, return ret; } - /* - * If there are valid blocks and the write pointer doesn't - * match with them, we need to report the inconsistency and - * fill the zone till the end to close the zone. This inconsistency - * does not cause write error because the zone will not be selected - * for write operation until it get discarded. - */ - f2fs_notice(sbi, "Valid blocks are not aligned with write pointer: " - "valid block[0x%x,0x%x] wp[0x%x,0x%x]", - GET_SEGNO(sbi, last_valid_block), - GET_BLKOFF_FROM_SEG0(sbi, last_valid_block), - wp_segno, wp_blkoff); + if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { + /* + * If there are valid blocks and the write pointer doesn't match + * with them, we need to report the inconsistency and fill + * the zone till the end to close the zone. This inconsistency + * does not cause write error because the zone will not be + * selected for write operation until it get discarded. + */ + f2fs_notice(sbi, "Valid blocks are not aligned with write " + "pointer: valid block[0x%x,0x%x] wp[0x%x,0x%x]", + GET_SEGNO(sbi, last_valid_block), + GET_BLKOFF_FROM_SEG0(sbi, last_valid_block), + wp_segno, wp_blkoff); + } ret = blkdev_zone_mgmt(fdev->bdev, REQ_OP_ZONE_FINISH, zone->start, zone->len, GFP_NOFS); @@ -4923,18 +4934,27 @@ static int fix_curseg_write_pointer(struct f2fs_sb_info *sbi, int type) if (zone.type != BLK_ZONE_TYPE_SEQWRITE_REQ) return 0; - wp_block = zbd->start_blk + (zone.wp >> log_sectors_per_block); - wp_segno = GET_SEGNO(sbi, wp_block); - wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno); - wp_sector_off = zone.wp & GENMASK(log_sectors_per_block - 1, 0); + /* + * When safely unmounted in the previous mount, we could use current + * segments. Otherwise, allocate new sections. + */ + if (is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { + wp_block = zbd->start_blk + (zone.wp >> log_sectors_per_block); + wp_segno = GET_SEGNO(sbi, wp_block); + wp_blkoff = wp_block - START_BLOCK(sbi, wp_segno); + wp_sector_off = zone.wp & GENMASK(log_sectors_per_block - 1, 0); - if (cs->segno == wp_segno && cs->next_blkoff == wp_blkoff && - wp_sector_off == 0) - return 0; + if (cs->segno == wp_segno && cs->next_blkoff == wp_blkoff && + wp_sector_off == 0) + return 0; - f2fs_notice(sbi, "Unaligned curseg[%d] with write pointer: " - "curseg[0x%x,0x%x] wp[0x%x,0x%x]", - type, cs->segno, cs->next_blkoff, wp_segno, wp_blkoff); + f2fs_notice(sbi, "Unaligned curseg[%d] with write pointer: " + "curseg[0x%x,0x%x] wp[0x%x,0x%x]", type, cs->segno, + cs->next_blkoff, wp_segno, wp_blkoff); + } else { + f2fs_notice(sbi, "Not successfully unmounted in the previous " + "mount"); + } f2fs_notice(sbi, "Assign new section to curseg[%d]: " "curseg[0x%x,0x%x]", type, cs->segno, cs->next_blkoff); From 354b1b716cde1eacf369fdffa43be14bc64a0e6c Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Nov 2023 18:51:57 -0800 Subject: [PATCH 14/27] FROMGIT: f2fs: skip adding a discard command if exists When recovering zoned UFS, sometimes we add the same zone to discard multiple times. Simple workaround is to bypass adding it. Reviewed-by: Chao Yu Change-Id: Ic1501caa02aea8bdc9d7f00a8bd0d35be2ef4ba1 Signed-off-by: Jaegeuk Kim (cherry picked from commit bbd3efed3383e332191c665786c61653826d2ac3 https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev) --- fs/f2fs/segment.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index fa63bb6bd4e3..dd1ad74733fb 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1325,7 +1325,8 @@ static void __insert_discard_cmd(struct f2fs_sb_info *sbi, p = &(*p)->rb_right; leftmost = false; } else { - f2fs_bug_on(sbi, 1); + /* Let's skip to add, if exists */ + return; } } From cfdfc17a46d0310b2cbe3e654bd8796bf4c75ba2 Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Wed, 15 Nov 2023 14:29:23 -0800 Subject: [PATCH 15/27] ANDROID: fuse-bpf: Ignore readaheads unless they go to the daemon readpages will be triggered on the fuse fs in passthrough mode though system calls like fadvise. If the daemon isn't aware of the file, this will likely cause a hang. For the moment, simply ignore fadvise in this situation Bug: 301201239 Test: fuse_test, atest ScopedStorageDeviceTest both pass Signed-off-by: Paul Lawrence Change-Id: I524a84aeeb1b1593e51264fcc37f7cfa66757168 --- fs/fuse/file.c | 10 ++++++ .../selftests/filesystems/fuse/fuse_test.c | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 6608de8bea12..390cddc77ae9 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1026,6 +1026,16 @@ static void fuse_readahead(struct readahead_control *rac) struct fuse_conn *fc = get_fuse_conn(inode); unsigned int i, max_pages, nr_pages = 0; +#ifdef CONFIG_FUSE_BPF + /* + * Currently no meaningful readahead is possible with fuse-bpf within + * the kernel, so unless the daemon is aware of this file, ignore this + * call. + */ + if (!get_fuse_inode(inode)->nodeid) + return; +#endif + if (fuse_is_bad(inode)) return; diff --git a/tools/testing/selftests/filesystems/fuse/fuse_test.c b/tools/testing/selftests/filesystems/fuse/fuse_test.c index 01730e57dc51..528595a8e82f 100644 --- a/tools/testing/selftests/filesystems/fuse/fuse_test.c +++ b/tools/testing/selftests/filesystems/fuse/fuse_test.c @@ -2079,6 +2079,41 @@ out: return result; } +static int bpf_test_readahead(const char *mount_dir) +{ + const char *file_name = "file"; + + int result = TEST_FAILURE; + int file_fd = -1; + int src_fd = -1; + int fuse_dev = -1; + + TEST(file_fd = s_creat(s_path(s(ft_src), s(file_name)), 0777), + file_fd != -1); + TESTSYSCALL(fallocate(file_fd, 0, 0, 4096)); + TESTSYSCALL(close(file_fd)); + file_fd = -1; + + TEST(src_fd = open(ft_src, O_DIRECTORY | O_RDONLY | O_CLOEXEC), + src_fd != -1); + TEST(fuse_dev = open("/dev/fuse", O_RDWR | O_CLOEXEC), fuse_dev != -1); + TESTEQUAL(mount_fuse(mount_dir, -1, src_fd, &fuse_dev), 0); + + TEST(file_fd = s_open(s_path(s(mount_dir), s(file_name)), O_RDONLY), + file_fd != -1); + TESTSYSCALL(posix_fadvise(file_fd, 0, 4096, POSIX_FADV_WILLNEED)); + usleep(1000); + TESTSYSCALL(close(file_fd)); + file_fd = -1; + result = TEST_SUCCESS; +out: + umount(mount_dir); + close(fuse_dev); + close(src_fd); + close(file_fd); + return result; +} + static void parse_range(const char *ranges, bool *run_test, size_t tests) { size_t i; @@ -2208,6 +2243,7 @@ int main(int argc, char *argv[]) MAKE_TEST(flock_test), MAKE_TEST(bpf_test_create_and_remove_bpf), MAKE_TEST(bpf_test_mkdir_and_remove_bpf), + MAKE_TEST(bpf_test_readahead), }; #undef MAKE_TEST From 6465e29536ed740086d2e3b79106f597c977acbd Mon Sep 17 00:00:00 2001 From: luguohong Date: Fri, 1 Dec 2023 22:42:34 +0800 Subject: [PATCH 16/27] BACKPORT: HID: input: map battery system charging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HID descriptors with Battery System (0x85) Charging (0x44) usage are ignored and POWER_SUPPLY_STATUS_DISCHARGING is always reported to user space, even when the device is charging. Map this usage and when it is reported set the right charging status. In addition, add KUnit tests to make sure that the charging status is correctly set and reported. They can be run with the usual command: $ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/hid Signed-off-by: José Expósito Signed-off-by: Jiri Kosina Bug: 305125317 Change-Id: Iad6a8177ad6954ad8ac2b714cc35acffcf2f226f (cherry picked from commit a608dc1c06397dc50ab773498433432fb5938f92) Signed-off-by: luguohong --- drivers/hid/hid-input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 4900269d2c1a..5a989b55461b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -636,6 +636,7 @@ static bool hidinput_set_battery_charge_status(struct hid_device *dev, dev->battery_charge_status = value ? POWER_SUPPLY_STATUS_CHARGING : POWER_SUPPLY_STATUS_DISCHARGING; + power_supply_changed(dev->battery); return true; } From 0ad2a3cd4d1c3bee257e759f71ceba7d3de2a040 Mon Sep 17 00:00:00 2001 From: liwei Date: Wed, 29 Nov 2023 15:05:18 +0800 Subject: [PATCH 17/27] ANDROID: vendor_hooks: export tracepoint symbol trace_mm_vmscan_kswapd_wake export tracepoint symbol trace_mm_vmscan_kswapd_wake so we can hook it in our ko to capture some kswapd running info. Bug: 309352303 Change-Id: Ieb37f544502f33e708dacda6cbb552792dfbbc6b Signed-off-by: liwei --- mm/vmscan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index f2fd1b4fce15..b38ac2bd34e3 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -75,6 +75,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_begin); EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_end); +EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_kswapd_wake); struct scan_control { /* How many pages shrink_list() should reclaim */ From 924116f1b8115df9532d494c3701756a67b67f73 Mon Sep 17 00:00:00 2001 From: liwei Date: Wed, 29 Nov 2023 15:17:22 +0800 Subject: [PATCH 18/27] ANDROID: GKI: Update oplus symbol list 1 function symbol(s) added 'int __traceiter_mm_vmscan_kswapd_wake(void*, int, int, int)' 1 variable symbol(s) added 'struct tracepoint __tracepoint_mm_vmscan_kswapd_wake' Bug: 309352303 Change-Id: Id46347110c482eca8d0fb12bd1dd69a14ad8a337 Signed-off-by: liwei --- android/abi_gki_aarch64.stg | 20 ++++++++++++++++++++ android/abi_gki_aarch64_oplus | 2 ++ 2 files changed, 22 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 0b6c517f8c4b..def56ab81552 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -337197,6 +337197,15 @@ elf_symbol { type_id: 0x9b626ff1 full_name: "__traceiter_mm_vmscan_direct_reclaim_end" } +elf_symbol { + id: 0xcebde919 + name: "__traceiter_mm_vmscan_kswapd_wake" + is_defined: true + symbol_type: FUNCTION + crc: 0xe7825239 + type_id: 0x9a2b6d98 + full_name: "__traceiter_mm_vmscan_kswapd_wake" +} elf_symbol { id: 0x5c33446d name: "__traceiter_mmap_lock_acquire_returned" @@ -341166,6 +341175,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_mm_vmscan_direct_reclaim_end" } +elf_symbol { + id: 0x651b2967 + name: "__tracepoint_mm_vmscan_kswapd_wake" + is_defined: true + symbol_type: OBJECT + crc: 0xd5e35f51 + type_id: 0x18ccbd2c + full_name: "__tracepoint_mm_vmscan_kswapd_wake" +} elf_symbol { id: 0x88a08d67 name: "__tracepoint_mmap_lock_acquire_returned" @@ -397472,6 +397490,7 @@ interface { symbol_id: 0x101ec6c5 symbol_id: 0xbcec3880 symbol_id: 0xa34c49b3 + symbol_id: 0xcebde919 symbol_id: 0x5c33446d symbol_id: 0x423dad0f symbol_id: 0xc630c439 @@ -397913,6 +397932,7 @@ interface { symbol_id: 0x5c535ca7 symbol_id: 0xa7ceb432 symbol_id: 0x32564229 + symbol_id: 0x651b2967 symbol_id: 0x88a08d67 symbol_id: 0xe2682879 symbol_id: 0xdffbb8bf diff --git a/android/abi_gki_aarch64_oplus b/android/abi_gki_aarch64_oplus index 86ae9cc7ea04..a374dcf65636 100644 --- a/android/abi_gki_aarch64_oplus +++ b/android/abi_gki_aarch64_oplus @@ -175,6 +175,7 @@ __traceiter_block_rq_issue __traceiter_block_rq_merge __traceiter_block_rq_requeue + __traceiter_mm_vmscan_kswapd_wake __traceiter_net_dev_queue __traceiter_net_dev_xmit __traceiter_netif_receive_skb @@ -284,6 +285,7 @@ __tracepoint_block_rq_issue __tracepoint_block_rq_merge __tracepoint_block_rq_requeue + __tracepoint_mm_vmscan_kswapd_wake __tracepoint_net_dev_queue __tracepoint_net_dev_xmit __tracepoint_netif_receive_skb From 72bdb74622c0e6479a95d67d01829aec0b11dcca Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 21 Nov 2023 13:14:21 +0100 Subject: [PATCH 19/27] UPSTREAM: netfilter: nf_tables: remove catchall element in GC sync path [ Upstream commit 93995bf4af2c5a99e2a87f0cd5ce547d31eb7630 ] The expired catchall element is not deactivated and removed from GC sync path. This path holds mutex so just call nft_setelem_data_deactivate() and nft_setelem_catchall_remove() before queueing the GC work. Bug: 310691882 Fixes: 4a9e12ea7e70 ("netfilter: nft_set_pipapo: call nft_trans_gc_queue_sync() in catchall GC") Reported-by: lonial con Signed-off-by: Pablo Neira Ayuso Signed-off-by: Florian Westphal Signed-off-by: Sasha Levin (cherry picked from commit 13e2d49647a7f137ebc063a4a9702dda80371b2e) Signed-off-by: Lee Jones Change-Id: Ic5d1d98fe5a749e759869f0789cbb77c4ab5e6c2 --- net/netfilter/nf_tables_api.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 5e3dbe2652db..6b5f22dc1d94 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -6198,6 +6198,12 @@ static int nft_setelem_deactivate(const struct net *net, return ret; } +static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall) +{ + list_del_rcu(&catchall->list); + kfree_rcu(catchall, rcu); +} + static void nft_setelem_catchall_remove(const struct net *net, const struct nft_set *set, const struct nft_set_elem *elem) @@ -6206,8 +6212,7 @@ static void nft_setelem_catchall_remove(const struct net *net, list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { if (catchall->elem == elem->priv) { - list_del_rcu(&catchall->list); - kfree_rcu(catchall, rcu); + nft_setelem_catchall_destroy(catchall); break; } } @@ -9268,11 +9273,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, unsigned int gc_seq, bool sync) { - struct nft_set_elem_catchall *catchall; + struct nft_set_elem_catchall *catchall, *next; const struct nft_set *set = gc->set; + struct nft_elem_priv *elem_priv; struct nft_set_ext *ext; - list_for_each_entry_rcu(catchall, &set->catchall_list, list) { + list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { ext = nft_set_elem_ext(set, catchall->elem); if (!nft_set_elem_expired(ext)) @@ -9290,7 +9296,17 @@ dead_elem: if (!gc) return NULL; - nft_trans_gc_elem_add(gc, catchall->elem); + elem_priv = catchall->elem; + if (sync) { + struct nft_set_elem elem = { + .priv = elem_priv, + }; + + nft_setelem_data_deactivate(gc->net, gc->set, &elem); + nft_setelem_catchall_destroy(catchall); + } + + nft_trans_gc_elem_add(gc, elem_priv); } return gc; From 6b972d6047989e9ab5bac34235639db73ce706dd Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 14 Nov 2023 00:11:22 +0000 Subject: [PATCH 20/27] BACKPORT: fscrypt: support crypto data unit size less than filesystem block size Until now, fscrypt has always used the filesystem block size as the granularity of file contents encryption. Two scenarios have come up where a sub-block granularity of contents encryption would be useful: 1. Inline crypto hardware that only supports a crypto data unit size that is less than the filesystem block size. 2. Support for direct I/O at a granularity less than the filesystem block size, for example at the block device's logical block size in order to match the traditional direct I/O alignment requirement. (1) first came up with older eMMC inline crypto hardware that only supports a crypto data unit size of 512 bytes. That specific case ultimately went away because all systems with that hardware continued using out of tree code and never actually upgraded to the upstream inline crypto framework. But, now it's coming back in a new way: some current UFS controllers only support a data unit size of 4096 bytes, and there is a proposal to increase the filesystem block size to 16K. (2) was discussed as a "nice to have" feature, though not essential, when support for direct I/O on encrypted files was being upstreamed. Still, the fact that this feature has come up several times does suggest it would be wise to have available. Therefore, this patch implements it by using one of the reserved bytes in fscrypt_policy_v2 to allow users to select a sub-block data unit size. Supported data unit sizes are powers of 2 between 512 and the filesystem block size, inclusively. Support is implemented for both the FS-layer and inline crypto cases. This patch focuses on the basic support for sub-block data units. Some things are out of scope for this patch but may be addressed later: - Supporting sub-block data units in combination with FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64, in most cases. Unfortunately this combination usually causes data unit indices to exceed 32 bits, and thus fscrypt_supported_policy() correctly disallows it. The users who potentially need this combination are using f2fs. To support it, f2fs would need to provide an option to slightly reduce its max file size. - Supporting sub-block data units in combination with FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32. This has the same problem described above, but also it will need special code to make DUN wraparound still happen on a FS block boundary. - Supporting use case (2) mentioned above. The encrypted direct I/O code will need to stop requiring and assuming FS block alignment. This won't be hard, but it belongs in a separate patch. - Supporting this feature on filesystems other than ext4 and f2fs. (Filesystems declare support for it via their fscrypt_operations.) On UBIFS, sub-block data units don't make sense because UBIFS encrypts variable-length blocks as a result of compression. CephFS could support it, but a bit more work would be needed to make the fscrypt_*_block_inplace functions play nicely with sub-block data units. I don't think there's a use case for this on CephFS anyway. Link: https://lore.kernel.org/r/20230925055451.59499-6-ebiggers@kernel.org Signed-off-by: Eric Biggers Bug: 299136786 Bug: 302588300 (cherry picked from commit 5b11888471806edf699316d4dcb9b426caebbef2) (Reworked this commit to not change struct fscrypt_operations and not depend on other commits that changed struct fscrypt_operations. Also resolved conflicts with the HW-wrapped key support.) Change-Id: Ic3dc56ef3f42d123f812e9037e2cc6f0b24bacc1 Signed-off-by: Eric Biggers --- Documentation/filesystems/fscrypt.rst | 105 ++++++++++++++----- fs/crypto/bio.c | 39 +++---- fs/crypto/crypto.c | 141 ++++++++++++++------------ fs/crypto/fscrypt_private.h | 58 +++++++++-- fs/crypto/inline_crypt.c | 16 +-- fs/crypto/keysetup.c | 5 + fs/crypto/policy.c | 38 ++++++- fs/ext4/crypto.c | 1 + fs/f2fs/super.c | 1 + include/linux/fscrypt.h | 12 +++ include/uapi/linux/fscrypt.h | 3 +- 11 files changed, 294 insertions(+), 125 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index eccd327e6df5..1829bc18f45c 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -261,9 +261,9 @@ DIRECT_KEY policies The Adiantum encryption mode (see `Encryption modes and usage`_) is suitable for both contents and filenames encryption, and it accepts -long IVs --- long enough to hold both an 8-byte logical block number -and a 16-byte per-file nonce. Also, the overhead of each Adiantum key -is greater than that of an AES-256-XTS key. +long IVs --- long enough to hold both an 8-byte data unit index and a +16-byte per-file nonce. Also, the overhead of each Adiantum key is +greater than that of an AES-256-XTS key. Therefore, to improve performance and save memory, for Adiantum a "direct key" configuration is supported. When the user has enabled @@ -300,8 +300,8 @@ IV_INO_LBLK_32 policies IV_INO_LBLK_32 policies work like IV_INO_LBLK_64, except that for IV_INO_LBLK_32, the inode number is hashed with SipHash-2-4 (where the -SipHash key is derived from the master key) and added to the file -logical block number mod 2^32 to produce a 32-bit IV. +SipHash key is derived from the master key) and added to the file data +unit index mod 2^32 to produce a 32-bit IV. This format is optimized for use with inline encryption hardware compliant with the eMMC v5.2 standard, which supports only 32 IV bits @@ -384,31 +384,62 @@ with ciphertext expansion. Contents encryption ------------------- -For file contents, each filesystem block is encrypted independently. -Starting from Linux kernel 5.5, encryption of filesystems with block -size less than system's page size is supported. +For contents encryption, each file's contents is divided into "data +units". Each data unit is encrypted independently. The IV for each +data unit incorporates the zero-based index of the data unit within +the file. This ensures that each data unit within a file is encrypted +differently, which is essential to prevent leaking information. -Each block's IV is set to the logical block number within the file as -a little endian number, except that: +Note: the encryption depending on the offset into the file means that +operations like "collapse range" and "insert range" that rearrange the +extent mapping of files are not supported on encrypted files. -- With CBC mode encryption, ESSIV is also used. Specifically, each IV - is encrypted with AES-256 where the AES-256 key is the SHA-256 hash - of the file's data encryption key. +There are two cases for the sizes of the data units: -- With `DIRECT_KEY policies`_, the file's nonce is appended to the IV. - Currently this is only allowed with the Adiantum encryption mode. +* Fixed-size data units. This is how all filesystems other than UBIFS + work. A file's data units are all the same size; the last data unit + is zero-padded if needed. By default, the data unit size is equal + to the filesystem block size. On some filesystems, users can select + a sub-block data unit size via the ``log2_data_unit_size`` field of + the encryption policy; see `FS_IOC_SET_ENCRYPTION_POLICY`_. -- With `IV_INO_LBLK_64 policies`_, the logical block number is limited - to 32 bits and is placed in bits 0-31 of the IV. The inode number - (which is also limited to 32 bits) is placed in bits 32-63. +* Variable-size data units. This is what UBIFS does. Each "UBIFS + data node" is treated as a crypto data unit. Each contains variable + length, possibly compressed data, zero-padded to the next 16-byte + boundary. Users cannot select a sub-block data unit size on UBIFS. -- With `IV_INO_LBLK_32 policies`_, the logical block number is limited - to 32 bits and is placed in bits 0-31 of the IV. The inode number - is then hashed and added mod 2^32. +In the case of compression + encryption, the compressed data is +encrypted. UBIFS compression works as described above. f2fs +compression works a bit differently; it compresses a number of +filesystem blocks into a smaller number of filesystem blocks. +Therefore a f2fs-compressed file still uses fixed-size data units, and +it is encrypted in a similar way to a file containing holes. -Note that because file logical block numbers are included in the IVs, -filesystems must enforce that blocks are never shifted around within -encrypted files, e.g. via "collapse range" or "insert range". +As mentioned in `Key hierarchy`_, the default encryption setting uses +per-file keys. In this case, the IV for each data unit is simply the +index of the data unit in the file. However, users can select an +encryption setting that does not use per-file keys. For these, some +kind of file identifier is incorporated into the IVs as follows: + +- With `DIRECT_KEY policies`_, the data unit index is placed in bits + 0-63 of the IV, and the file's nonce is placed in bits 64-191. + +- With `IV_INO_LBLK_64 policies`_, the data unit index is placed in + bits 0-31 of the IV, and the file's inode number is placed in bits + 32-63. This setting is only allowed when data unit indices and + inode numbers fit in 32 bits. + +- With `IV_INO_LBLK_32 policies`_, the file's inode number is hashed + and added to the data unit index. The resulting value is truncated + to 32 bits and placed in bits 0-31 of the IV. This setting is only + allowed when data unit indices and inode numbers fit in 32 bits. + +The byte order of the IV is always little endian. + +If the user selects FSCRYPT_MODE_AES_128_CBC for the contents mode, an +ESSIV layer is automatically included. In this case, before the IV is +passed to AES-128-CBC, it is encrypted with AES-256 where the AES-256 +key is the SHA-256 hash of the file's contents encryption key. Filenames encryption -------------------- @@ -477,7 +508,8 @@ follows:: __u8 contents_encryption_mode; __u8 filenames_encryption_mode; __u8 flags; - __u8 __reserved[4]; + __u8 log2_data_unit_size; + __u8 __reserved[3]; __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; }; @@ -512,6 +544,29 @@ This structure must be initialized as follows: The DIRECT_KEY, IV_INO_LBLK_64, and IV_INO_LBLK_32 flags are mutually exclusive. +- ``log2_data_unit_size`` is the log2 of the data unit size in bytes, + or 0 to select the default data unit size. The data unit size is + the granularity of file contents encryption. For example, setting + ``log2_data_unit_size`` to 12 causes file contents be passed to the + underlying encryption algorithm (such as AES-256-XTS) in 4096-byte + data units, each with its own IV. + + Not all filesystems support setting ``log2_data_unit_size``. ext4 + and f2fs support it since Linux v6.7. On filesystems that support + it, the supported nonzero values are 9 through the log2 of the + filesystem block size, inclusively. The default value of 0 selects + the filesystem block size. + + The main use case for ``log2_data_unit_size`` is for selecting a + data unit size smaller than the filesystem block size for + compatibility with inline encryption hardware that only supports + smaller data unit sizes. ``/sys/block/$disk/queue/crypto/`` may be + useful for checking which data unit sizes are supported by a + particular system's inline encryption hardware. + + Leave this field zeroed unless you are certain you need it. Using + an unnecessarily small data unit size reduces performance. + - For v2 encryption policies, ``__reserved`` must be zeroed. - For v1 encryption policies, ``master_key_descriptor`` specifies how diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 62e1a3dd8357..c8cf77065272 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -111,10 +111,14 @@ out: int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { - const unsigned int blockbits = inode->i_blkbits; - const unsigned int blocksize = 1 << blockbits; - const unsigned int blocks_per_page_bits = PAGE_SHIFT - blockbits; - const unsigned int blocks_per_page = 1 << blocks_per_page_bits; + const struct fscrypt_info *ci = inode->i_crypt_info; + const unsigned int du_bits = ci->ci_data_unit_bits; + const unsigned int du_size = 1U << du_bits; + const unsigned int du_per_page_bits = PAGE_SHIFT - du_bits; + const unsigned int du_per_page = 1U << du_per_page_bits; + u64 du_index = (u64)lblk << (inode->i_blkbits - du_bits); + u64 du_remaining = (u64)len << (inode->i_blkbits - du_bits); + sector_t sector = pblk << (inode->i_blkbits - SECTOR_SHIFT); struct page *pages[16]; /* write up to 16 pages at a time */ unsigned int nr_pages; unsigned int i; @@ -130,8 +134,8 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, len); BUILD_BUG_ON(ARRAY_SIZE(pages) > BIO_MAX_VECS); - nr_pages = min_t(unsigned int, ARRAY_SIZE(pages), - (len + blocks_per_page - 1) >> blocks_per_page_bits); + nr_pages = min_t(u64, ARRAY_SIZE(pages), + (du_remaining + du_per_page - 1) >> du_per_page_bits); /* * We need at least one page for ciphertext. Allocate the first one @@ -154,21 +158,22 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, bio = bio_alloc(inode->i_sb->s_bdev, nr_pages, REQ_OP_WRITE, GFP_NOFS); do { - bio->bi_iter.bi_sector = pblk << (blockbits - 9); + bio->bi_iter.bi_sector = sector; i = 0; offset = 0; do { - err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk, - ZERO_PAGE(0), pages[i], - blocksize, offset, GFP_NOFS); + err = fscrypt_crypt_data_unit(ci, FS_ENCRYPT, du_index, + ZERO_PAGE(0), pages[i], + du_size, offset, + GFP_NOFS); if (err) goto out; - lblk++; - pblk++; - len--; - offset += blocksize; - if (offset == PAGE_SIZE || len == 0) { + du_index++; + sector += 1U << (du_bits - SECTOR_SHIFT); + du_remaining--; + offset += du_size; + if (offset == PAGE_SIZE || du_remaining == 0) { ret = bio_add_page(bio, pages[i++], offset, 0); if (WARN_ON_ONCE(ret != offset)) { err = -EIO; @@ -176,13 +181,13 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, } offset = 0; } - } while (i != nr_pages && len != 0); + } while (i != nr_pages && du_remaining != 0); err = submit_bio_wait(bio); if (err) goto out; bio_reset(bio, inode->i_sb->s_bdev, REQ_OP_WRITE); - } while (len != 0); + } while (du_remaining != 0); err = 0; out: bio_put(bio); diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 6a837e4b80dc..d98d6098e299 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -70,14 +70,14 @@ void fscrypt_free_bounce_page(struct page *bounce_page) EXPORT_SYMBOL(fscrypt_free_bounce_page); /* - * Generate the IV for the given logical block number within the given file. - * For filenames encryption, lblk_num == 0. + * Generate the IV for the given data unit index within the given file. + * For filenames encryption, index == 0. * * Keep this in sync with fscrypt_limit_io_blocks(). fscrypt_limit_io_blocks() * needs to know about any IV generation methods where the low bits of IV don't - * simply contain the lblk_num (e.g., IV_INO_LBLK_32). + * simply contain the data unit index (e.g., IV_INO_LBLK_32). */ -void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, +void fscrypt_generate_iv(union fscrypt_iv *iv, u64 index, const struct fscrypt_info *ci) { u8 flags = fscrypt_policy_flags(&ci->ci_policy); @@ -85,29 +85,29 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, memset(iv, 0, ci->ci_mode->ivsize); if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) { - WARN_ON_ONCE(lblk_num > U32_MAX); + WARN_ON_ONCE(index > U32_MAX); WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX); - lblk_num |= (u64)ci->ci_inode->i_ino << 32; + index |= (u64)ci->ci_inode->i_ino << 32; } else if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) { - WARN_ON_ONCE(lblk_num > U32_MAX); - lblk_num = (u32)(ci->ci_hashed_ino + lblk_num); + WARN_ON_ONCE(index > U32_MAX); + index = (u32)(ci->ci_hashed_ino + index); } else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) { memcpy(iv->nonce, ci->ci_nonce, FSCRYPT_FILE_NONCE_SIZE); } - iv->lblk_num = cpu_to_le64(lblk_num); + iv->index = cpu_to_le64(index); } -/* Encrypt or decrypt a single filesystem block of file contents */ -int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, - u64 lblk_num, struct page *src_page, - struct page *dest_page, unsigned int len, - unsigned int offs, gfp_t gfp_flags) +/* Encrypt or decrypt a single "data unit" of file contents. */ +int fscrypt_crypt_data_unit(const struct fscrypt_info *ci, + fscrypt_direction_t rw, u64 index, + struct page *src_page, struct page *dest_page, + unsigned int len, unsigned int offs, + gfp_t gfp_flags) { union fscrypt_iv iv; struct skcipher_request *req = NULL; DECLARE_CRYPTO_WAIT(wait); struct scatterlist dst, src; - struct fscrypt_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; int res = 0; @@ -116,7 +116,7 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, if (WARN_ON_ONCE(len % FSCRYPT_CONTENTS_ALIGNMENT != 0)) return -EINVAL; - fscrypt_generate_iv(&iv, lblk_num, ci); + fscrypt_generate_iv(&iv, index, ci); req = skcipher_request_alloc(tfm, gfp_flags); if (!req) @@ -137,28 +137,29 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); skcipher_request_free(req); if (res) { - fscrypt_err(inode, "%scryption failed for block %llu: %d", - (rw == FS_DECRYPT ? "De" : "En"), lblk_num, res); + fscrypt_err(ci->ci_inode, + "%scryption failed for data unit %llu: %d", + (rw == FS_DECRYPT ? "De" : "En"), index, res); return res; } return 0; } /** - * fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a - * pagecache page - * @page: The locked pagecache page containing the block(s) to encrypt - * @len: Total size of the block(s) to encrypt. Must be a nonzero - * multiple of the filesystem's block size. - * @offs: Byte offset within @page of the first block to encrypt. Must be - * a multiple of the filesystem's block size. - * @gfp_flags: Memory allocation flags. See details below. + * fscrypt_encrypt_pagecache_blocks() - Encrypt data from a pagecache page + * @page: the locked pagecache page containing the data to encrypt + * @len: size of the data to encrypt, in bytes + * @offs: offset within @page of the data to encrypt, in bytes + * @gfp_flags: memory allocation flags; see details below * - * A new bounce page is allocated, and the specified block(s) are encrypted into - * it. In the bounce page, the ciphertext block(s) will be located at the same - * offsets at which the plaintext block(s) were located in the source page; any - * other parts of the bounce page will be left uninitialized. However, normally - * blocksize == PAGE_SIZE and the whole page is encrypted at once. + * This allocates a new bounce page and encrypts the given data into it. The + * length and offset of the data must be aligned to the file's crypto data unit + * size. Alignment to the filesystem block size fulfills this requirement, as + * the filesystem block size is always a multiple of the data unit size. + * + * In the bounce page, the ciphertext data will be located at the same offset at + * which the plaintext data was located in the source page. Any other parts of + * the bounce page will be left uninitialized. * * This is for use by the filesystem's ->writepages() method. * @@ -176,28 +177,29 @@ struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, { const struct inode *inode = page->mapping->host; - const unsigned int blockbits = inode->i_blkbits; - const unsigned int blocksize = 1 << blockbits; + const struct fscrypt_info *ci = inode->i_crypt_info; + const unsigned int du_bits = ci->ci_data_unit_bits; + const unsigned int du_size = 1U << du_bits; struct page *ciphertext_page; - u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) + - (offs >> blockbits); + u64 index = ((u64)page->index << (PAGE_SHIFT - du_bits)) + + (offs >> du_bits); unsigned int i; int err; if (WARN_ON_ONCE(!PageLocked(page))) return ERR_PTR(-EINVAL); - if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize))) + if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, du_size))) return ERR_PTR(-EINVAL); ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags); if (!ciphertext_page) return ERR_PTR(-ENOMEM); - for (i = offs; i < offs + len; i += blocksize, lblk_num++) { - err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, - page, ciphertext_page, - blocksize, i, gfp_flags); + for (i = offs; i < offs + len; i += du_size, index++) { + err = fscrypt_crypt_data_unit(ci, FS_ENCRYPT, index, + page, ciphertext_page, + du_size, i, gfp_flags); if (err) { fscrypt_free_bounce_page(ciphertext_page); return ERR_PTR(err); @@ -224,30 +226,34 @@ EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks); * arbitrary page, not necessarily in the original pagecache page. The @inode * and @lblk_num must be specified, as they can't be determined from @page. * + * This is not compatible with FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS. + * * Return: 0 on success; -errno on failure */ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num, gfp_t gfp_flags) { - return fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, page, - len, offs, gfp_flags); + if (WARN_ON_ONCE(inode->i_sb->s_cop->flags & + FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS)) + return -EOPNOTSUPP; + return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_ENCRYPT, + lblk_num, page, page, len, offs, + gfp_flags); } EXPORT_SYMBOL(fscrypt_encrypt_block_inplace); /** - * fscrypt_decrypt_pagecache_blocks() - Decrypt filesystem blocks in a - * pagecache folio - * @folio: The locked pagecache folio containing the block(s) to decrypt - * @len: Total size of the block(s) to decrypt. Must be a nonzero - * multiple of the filesystem's block size. - * @offs: Byte offset within @folio of the first block to decrypt. Must be - * a multiple of the filesystem's block size. + * fscrypt_decrypt_pagecache_blocks() - Decrypt data from a pagecache folio + * @folio: the pagecache folio containing the data to decrypt + * @len: size of the data to decrypt, in bytes + * @offs: offset within @folio of the data to decrypt, in bytes * - * The specified block(s) are decrypted in-place within the pagecache folio, - * which must still be locked and not uptodate. - * - * This is for use by the filesystem's ->readahead() method. + * Decrypt data that has just been read from an encrypted file. The data must + * be located in a pagecache folio that is still locked and not yet uptodate. + * The length and offset of the data must be aligned to the file's crypto data + * unit size. Alignment to the filesystem block size fulfills this requirement, + * as the filesystem block size is always a multiple of the data unit size. * * Return: 0 on success; -errno on failure */ @@ -255,25 +261,26 @@ int fscrypt_decrypt_pagecache_blocks(struct folio *folio, size_t len, size_t offs) { const struct inode *inode = folio->mapping->host; - const unsigned int blockbits = inode->i_blkbits; - const unsigned int blocksize = 1 << blockbits; - u64 lblk_num = ((u64)folio->index << (PAGE_SHIFT - blockbits)) + - (offs >> blockbits); + const struct fscrypt_info *ci = inode->i_crypt_info; + const unsigned int du_bits = ci->ci_data_unit_bits; + const unsigned int du_size = 1U << du_bits; + u64 index = ((u64)folio->index << (PAGE_SHIFT - du_bits)) + + (offs >> du_bits); size_t i; int err; if (WARN_ON_ONCE(!folio_test_locked(folio))) return -EINVAL; - if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize))) + if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, du_size))) return -EINVAL; - for (i = offs; i < offs + len; i += blocksize, lblk_num++) { + for (i = offs; i < offs + len; i += du_size, index++) { struct page *page = folio_page(folio, i >> PAGE_SHIFT); - err = fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, - page, blocksize, i & ~PAGE_MASK, - GFP_NOFS); + err = fscrypt_crypt_data_unit(ci, FS_DECRYPT, index, page, + page, du_size, i & ~PAGE_MASK, + GFP_NOFS); if (err) return err; } @@ -295,14 +302,20 @@ EXPORT_SYMBOL(fscrypt_decrypt_pagecache_blocks); * arbitrary page, not necessarily in the original pagecache page. The @inode * and @lblk_num must be specified, as they can't be determined from @page. * + * This is not compatible with FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS. + * * Return: 0 on success; -errno on failure */ int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num) { - return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page, - len, offs, GFP_NOFS); + if (WARN_ON_ONCE(inode->i_sb->s_cop->flags & + FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS)) + return -EOPNOTSUPP; + return fscrypt_crypt_data_unit(inode->i_crypt_info, FS_DECRYPT, + lblk_num, page, page, len, offs, + GFP_NOFS); } EXPORT_SYMBOL(fscrypt_decrypt_block_inplace); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 0d246bf672dc..072feded76e1 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -68,7 +68,8 @@ struct fscrypt_context_v2 { u8 contents_encryption_mode; u8 filenames_encryption_mode; u8 flags; - u8 __reserved[4]; + u8 log2_data_unit_size; + u8 __reserved[3]; u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; }; @@ -186,6 +187,26 @@ fscrypt_policy_flags(const union fscrypt_policy *policy) BUG(); } +static inline int +fscrypt_policy_v2_du_bits(const struct fscrypt_policy_v2 *policy, + const struct inode *inode) +{ + return policy->log2_data_unit_size ?: inode->i_blkbits; +} + +static inline int +fscrypt_policy_du_bits(const union fscrypt_policy *policy, + const struct inode *inode) +{ + switch (policy->version) { + case FSCRYPT_POLICY_V1: + return inode->i_blkbits; + case FSCRYPT_POLICY_V2: + return fscrypt_policy_v2_du_bits(&policy->v2, inode); + } + BUG(); +} + /* * For encrypted symlinks, the ciphertext length is stored at the beginning * of the string in little-endian format. @@ -232,6 +253,16 @@ struct fscrypt_info { bool ci_inlinecrypt; #endif + /* + * log2 of the data unit size (granularity of contents encryption) of + * this file. This is computable from ci_policy and ci_inode but is + * cached here for efficiency. Only used for regular files. + */ + u8 ci_data_unit_bits; + + /* Cached value: log2 of number of data units per FS block */ + u8 ci_data_units_per_block_bits; + /* * Encryption mode used for this inode. It corresponds to either the * contents or filenames encryption mode, depending on the inode type. @@ -286,10 +317,11 @@ typedef enum { /* crypto.c */ extern struct kmem_cache *fscrypt_info_cachep; int fscrypt_initialize(struct super_block *sb); -int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, - u64 lblk_num, struct page *src_page, - struct page *dest_page, unsigned int len, - unsigned int offs, gfp_t gfp_flags); +int fscrypt_crypt_data_unit(const struct fscrypt_info *ci, + fscrypt_direction_t rw, u64 index, + struct page *src_page, struct page *dest_page, + unsigned int len, unsigned int offs, + gfp_t gfp_flags); struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags); void __printf(3, 4) __cold @@ -304,8 +336,8 @@ fscrypt_msg(const struct inode *inode, const char *level, const char *fmt, ...); union fscrypt_iv { struct { - /* logical block number within the file */ - __le64 lblk_num; + /* zero-based index of data unit within the file */ + __le64 index; /* per-file nonce; only set in DIRECT_KEY mode */ u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; @@ -314,9 +346,19 @@ union fscrypt_iv { __le64 dun[FSCRYPT_MAX_IV_SIZE / sizeof(__le64)]; }; -void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, +void fscrypt_generate_iv(union fscrypt_iv *iv, u64 index, const struct fscrypt_info *ci); +/* + * Return the number of bits used by the maximum file data unit index that is + * possible on the given filesystem, using the given log2 data unit size. + */ +static inline int +fscrypt_max_file_dun_bits(const struct super_block *sb, int du_bits) +{ + return fls64(sb->s_maxbytes - 1) - du_bits; +} + /* fname.c */ bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy, u32 orig_len, u32 max_len, diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 64fff3895a22..d282f20d4a00 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -43,7 +43,7 @@ static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci) { struct super_block *sb = ci->ci_inode->i_sb; unsigned int flags = fscrypt_policy_flags(&ci->ci_policy); - int ino_bits = 64, lblk_bits = 64; + int dun_bits; if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) return offsetofend(union fscrypt_iv, nonce); @@ -54,10 +54,9 @@ static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci) if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) return sizeof(__le32); - /* Default case: IVs are just the file logical block number */ - if (sb->s_cop->get_ino_and_lblk_bits) - sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits); - return DIV_ROUND_UP(lblk_bits, 8); + /* Default case: IVs are just the file data unit index */ + dun_bits = fscrypt_max_file_dun_bits(sb, ci->ci_data_unit_bits); + return DIV_ROUND_UP(dun_bits, 8); } /* @@ -130,7 +129,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci, * crypto configuration that the file would use. */ crypto_cfg.crypto_mode = ci->ci_mode->blk_crypto_mode; - crypto_cfg.data_unit_size = sb->s_blocksize; + crypto_cfg.data_unit_size = 1U << ci->ci_data_unit_bits; crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci); crypto_cfg.key_type = is_hw_wrapped_key ? BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : @@ -176,7 +175,7 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, err = blk_crypto_init_key(blk_key, raw_key, raw_key_size, key_type, crypto_mode, fscrypt_get_dun_bytes(ci), - sb->s_blocksize); + 1U << ci->ci_data_unit_bits); if (err) { fscrypt_err(inode, "error %d initializing blk-crypto key", err); goto fail; @@ -271,10 +270,11 @@ EXPORT_SYMBOL_GPL(__fscrypt_inode_uses_inline_crypto); static void fscrypt_generate_dun(const struct fscrypt_info *ci, u64 lblk_num, u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]) { + u64 index = lblk_num << ci->ci_data_units_per_block_bits; union fscrypt_iv iv; int i; - fscrypt_generate_iv(&iv, lblk_num, ci); + fscrypt_generate_iv(&iv, index, ci); BUILD_BUG_ON(FSCRYPT_MAX_IV_SIZE > BLK_CRYPTO_MAX_IV_SIZE); memset(dun, 0, BLK_CRYPTO_MAX_IV_SIZE); diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index eb3935380c98..69600c4250d8 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -627,6 +627,11 @@ fscrypt_setup_encryption_info(struct inode *inode, WARN_ON_ONCE(mode->ivsize > FSCRYPT_MAX_IV_SIZE); crypt_info->ci_mode = mode; + crypt_info->ci_data_unit_bits = + fscrypt_policy_du_bits(&crypt_info->ci_policy, inode); + crypt_info->ci_data_units_per_block_bits = + inode->i_blkbits - crypt_info->ci_data_unit_bits; + res = setup_file_encryption_key(crypt_info, need_dirhash_key, &mk); if (res) goto out; diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index eaec6bd6cfc4..70978f4569e1 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -158,9 +158,15 @@ static bool supported_iv_ino_lblk_policy(const struct fscrypt_policy_v2 *policy, type, sb->s_id); return false; } - if (lblk_bits > max_lblk_bits) { + + /* + * IV_INO_LBLK_64 and IV_INO_LBLK_32 both require that file data unit + * indices fit in 32 bits. + */ + if (fscrypt_max_file_dun_bits(sb, + fscrypt_policy_v2_du_bits(policy, inode)) > 32) { fscrypt_warn(inode, - "Can't use %s policy on filesystem '%s' because its block numbers are too long", + "Can't use %s policy on filesystem '%s' because its maximum file size is too large", type, sb->s_id); return false; } @@ -233,6 +239,32 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy, return false; } + if (policy->log2_data_unit_size) { + if (!(inode->i_sb->s_cop->flags & + FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS)) { + fscrypt_warn(inode, + "Filesystem does not support configuring crypto data unit size"); + return false; + } + if (policy->log2_data_unit_size > inode->i_blkbits || + policy->log2_data_unit_size < SECTOR_SHIFT /* 9 */) { + fscrypt_warn(inode, + "Unsupported log2_data_unit_size in encryption policy: %d", + policy->log2_data_unit_size); + return false; + } + if (policy->log2_data_unit_size != inode->i_blkbits && + (policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) { + /* + * Not safe to enable yet, as we need to ensure that DUN + * wraparound can only occur on a FS block boundary. + */ + fscrypt_warn(inode, + "Sub-block data units not yet supported with IV_INO_LBLK_32"); + return false; + } + } + if ((policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) && !supported_direct_key_modes(inode, policy->contents_encryption_mode, policy->filenames_encryption_mode)) @@ -330,6 +362,7 @@ static int fscrypt_new_context(union fscrypt_context *ctx_u, ctx->filenames_encryption_mode = policy->filenames_encryption_mode; ctx->flags = policy->flags; + ctx->log2_data_unit_size = policy->log2_data_unit_size; memcpy(ctx->master_key_identifier, policy->master_key_identifier, sizeof(ctx->master_key_identifier)); @@ -390,6 +423,7 @@ int fscrypt_policy_from_context(union fscrypt_policy *policy_u, policy->filenames_encryption_mode = ctx->filenames_encryption_mode; policy->flags = ctx->flags; + policy->log2_data_unit_size = ctx->log2_data_unit_size; memcpy(policy->__reserved, ctx->__reserved, sizeof(policy->__reserved)); memcpy(policy->master_key_identifier, diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c index 453d4da5de52..f23c52f06a2e 100644 --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c @@ -240,6 +240,7 @@ static void ext4_get_ino_and_lblk_bits(struct super_block *sb, } const struct fscrypt_operations ext4_cryptops = { + .flags = FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS, .key_prefix = "ext4:", .get_context = ext4_get_context, .set_context = ext4_set_context, diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 78cd1f5fff5c..97583cfba8b8 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3148,6 +3148,7 @@ static struct block_device **f2fs_get_devices(struct super_block *sb, } static const struct fscrypt_operations f2fs_cryptops = { + .flags = FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS, .key_prefix = "f2fs:", .get_context = f2fs_get_context, .set_context = f2fs_set_context, diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index e54062de0528..e827fe749785 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -67,6 +67,18 @@ struct fscrypt_name { */ #define FS_CFLG_OWN_PAGES (1U << 1) +/* + * If set, then fs/crypto/ will allow users to select a crypto data unit size + * that is less than the filesystem block size. This is done via the + * log2_data_unit_size field of the fscrypt policy. This flag is not compatible + * with filesystems that encrypt variable-length blocks (i.e. blocks that aren't + * all equal to filesystem's block size), for example as a result of + * compression. It's also not compatible with the + * fscrypt_encrypt_block_inplace() and fscrypt_decrypt_block_inplace() + * functions. + */ +#define FS_CFLG_SUPPORTS_SUBBLOCK_DATA_UNITS (1U << 2) + /* Crypto operations for filesystems */ struct fscrypt_operations { diff --git a/include/uapi/linux/fscrypt.h b/include/uapi/linux/fscrypt.h index 024def3ad43d..5156f0002a20 100644 --- a/include/uapi/linux/fscrypt.h +++ b/include/uapi/linux/fscrypt.h @@ -71,7 +71,8 @@ struct fscrypt_policy_v2 { __u8 contents_encryption_mode; __u8 filenames_encryption_mode; __u8 flags; - __u8 __reserved[4]; + __u8 log2_data_unit_size; + __u8 __reserved[3]; __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; }; From db9d7ba7061247446ea22220a32179d91d3e6021 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 14 Nov 2023 22:49:05 +0000 Subject: [PATCH 21/27] ANDROID: Update the ABI representation INFO: type 'struct fscrypt_info' changed member 'u8 ci_data_unit_bits' was added member 'u8 ci_data_units_per_block_bits' was added type 'struct fscrypt_policy_v2' changed member '__u8 log2_data_unit_size' was added member changed from '__u8 __reserved[4]' to '__u8 __reserved[3]' offset changed from 32 to 40 type changed from '__u8[4]' to '__u8[3]' number of elements changed from 4 to 3 Bug: 299136786 Bug: 302588300 Change-Id: Idbbc2123961a41d395323c72cef67d94bdd17ab0 Signed-off-by: Eric Biggers --- android/abi_gki_aarch64.stg | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index def56ab81552..a393ee0f1c95 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -41080,18 +41080,18 @@ member { type_id: 0x5522ef22 offset: 4160 } +member { + id: 0x5e4e4c08 + name: "__reserved" + type_id: 0x3e3c1b86 + offset: 40 +} member { id: 0x5e9651c5 name: "__reserved" type_id: 0xe62ebf07 offset: 32 } -member { - id: 0x5ed0cb87 - name: "__reserved" - type_id: 0xa0b4fda8 - offset: 32 -} member { id: 0x5ee63f2d name: "__reserved" @@ -60741,6 +60741,18 @@ member { type_id: 0x4585663f offset: 416 } +member { + id: 0xb757dfb6 + name: "ci_data_unit_bits" + type_id: 0x295c7202 + offset: 144 +} +member { + id: 0x059182f5 + name: "ci_data_units_per_block_bits" + type_id: 0x295c7202 + offset: 152 +} member { id: 0x5173269c name: "ci_dentry" @@ -118177,6 +118189,12 @@ member { type_id: 0x97f9278b offset: 896 } +member { + id: 0x87fb0c15 + name: "log2_data_unit_size" + type_id: 0xb3e7bac9 + offset: 32 +} member { id: 0xa0fdc6e2 name: "log2_diff_max_min_luma_coding_block_size" @@ -229554,6 +229572,8 @@ struct_union { member_id: 0x0534711c member_id: 0x81f8c824 member_id: 0x796f533e + member_id: 0xb757dfb6 + member_id: 0x059182f5 member_id: 0x5e6a6d58 member_id: 0x4025e474 member_id: 0xee6c5106 @@ -229695,7 +229715,8 @@ struct_union { member_id: 0x4bfa9ecc member_id: 0x3ff8b433 member_id: 0x2ddb6585 - member_id: 0x5ed0cb87 + member_id: 0x87fb0c15 + member_id: 0x5e4e4c08 member_id: 0xcf7375db } } From 0de2f429772afec266b900b312fcfd7aae2492ca Mon Sep 17 00:00:00 2001 From: Richard Chang Date: Wed, 29 Nov 2023 03:03:20 +0000 Subject: [PATCH 22/27] ANDROID: mm: cma: introduce __cma_alloc API This patch enhances the CMA API with support for failfast mode, utilizing the __GFP_NORETRY flag. This mode is specifically designed for high-order bulk allocation scenarios, enabling the CMA API to avoid prolonged stalls resulting from blocking pages such as those undergoing page writeback or page locking. Instead of stalling, the API will continue searching for readily migratable pages across different pageblocks. The original patch link: Link: https://lore.kernel.org/linux-mm/YAnM5PbNJZlk%2F%2FiX@google.com/T/#m36b144ff81fe0a8f0ecaf6813de4819ecc41f8fe Bug: 308881290 Change-Id: I1c623f17fb49c26005aaffc17330cf820ce6585c Signed-off-by: Richard Chang (cherry picked from commit 3390547fec36527ed15dd213ee55d397f83ffa46) --- include/linux/cma.h | 2 ++ mm/cma.c | 43 +++++++++++++++++++++++++++++++++---------- mm/page_alloc.c | 14 +++++++++++--- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/include/linux/cma.h b/include/linux/cma.h index 63873b93deaa..82e31b4da486 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -48,6 +48,8 @@ extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, unsigned int order_per_bit, const char *name, struct cma **res_cma); +extern struct page *__cma_alloc(struct cma *cma, unsigned long count, unsigned int align, + gfp_t gfp_mask); extern struct page *cma_alloc(struct cma *cma, unsigned long count, unsigned int align, bool no_warn); extern bool cma_pages_valid(struct cma *cma, const struct page *pages, unsigned long count); diff --git a/mm/cma.c b/mm/cma.c index 332f3c631b1c..b64768625d82 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -416,17 +416,18 @@ static inline void cma_debug_show_areas(struct cma *cma) { } #endif /** - * cma_alloc() - allocate pages from contiguous area + * __cma_alloc() - allocate pages from contiguous area * @cma: Contiguous memory region for which the allocation is performed. * @count: Requested number of pages. * @align: Requested alignment of pages (in PAGE_SIZE order). - * @no_warn: Avoid printing message about failed allocation + * @gfp_mask: GFP mask to use during the cma allocation. * - * This function allocates part of contiguous memory on specific - * contiguous memory area. + * This function is same with cma_alloc but supports gfp_mask. + * Currently, the gfp_mask supports only __GFP_NOWARN and __GFP_NORETRY. + * If user passes other flags, it fails the allocation. */ -struct page *cma_alloc(struct cma *cma, unsigned long count, - unsigned int align, bool no_warn) +struct page *__cma_alloc(struct cma *cma, unsigned long count, + unsigned int align, gfp_t gfp_mask) { unsigned long mask, offset; unsigned long pfn = -1; @@ -438,6 +439,10 @@ struct page *cma_alloc(struct cma *cma, unsigned long count, int num_attempts = 0; int max_retries = 5; + if (WARN_ON_ONCE((gfp_mask & GFP_KERNEL) == 0 || + (gfp_mask & ~(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY)) != 0)) + goto out; + if (!cma || !cma->count || !cma->bitmap) goto out; @@ -466,7 +471,8 @@ struct page *cma_alloc(struct cma *cma, unsigned long count, if ((num_attempts < max_retries) && (ret == -EBUSY)) { spin_unlock_irq(&cma->lock); - if (fatal_signal_pending(current)) + if (fatal_signal_pending(current) || + (gfp_mask & __GFP_NORETRY)) break; /* @@ -496,8 +502,7 @@ struct page *cma_alloc(struct cma *cma, unsigned long count, pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit); mutex_lock(&cma_mutex); - ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, - GFP_KERNEL | (no_warn ? __GFP_NOWARN : 0)); + ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, gfp_mask); mutex_unlock(&cma_mutex); if (ret == 0) { page = pfn_to_page(pfn); @@ -529,7 +534,7 @@ struct page *cma_alloc(struct cma *cma, unsigned long count, page_kasan_tag_reset(page + i); } - if (ret && !no_warn) { + if (ret && !(gfp_mask & __GFP_NOWARN)) { pr_err_ratelimited("%s: %s: alloc failed, req-size: %lu pages, ret: %d\n", __func__, cma->name, count, ret); cma_debug_show_areas(cma); @@ -548,6 +553,24 @@ out: return page; } +EXPORT_SYMBOL_GPL(__cma_alloc); + +/** + * cma_alloc() - allocate pages from contiguous area + * @cma: Contiguous memory region for which the allocation is performed. + * @count: Requested number of pages. + * @align: Requested alignment of pages (in PAGE_SIZE order). + * @no_warn: Avoid printing message about failed allocation + * + * This function allocates part of contiguous memory on specific + * contiguous memory area. + */ +struct page *cma_alloc(struct cma *cma, unsigned long count, + unsigned int align, bool no_warn) +{ + return __cma_alloc(cma, count, align, GFP_KERNEL | + (no_warn ? __GFP_NOWARN : 0)); +} EXPORT_SYMBOL_GPL(cma_alloc); bool cma_pages_valid(struct cma *cma, const struct page *pages, diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 33ad6d5e9497..dfc8658392c2 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -9336,12 +9336,16 @@ int __alloc_contig_migrate_range(struct compact_control *cc, unsigned int nr_reclaimed; unsigned long pfn = start; unsigned int tries = 0; + unsigned int max_tries = 5; int ret = 0; struct migration_target_control mtc = { .nid = zone_to_nid(cc->zone), .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL, }; + if (cc->gfp_mask & __GFP_NORETRY) + max_tries = 1; + lru_cache_disable(); while (pfn < end || !list_empty(&cc->migratepages)) { @@ -9357,7 +9361,7 @@ int __alloc_contig_migrate_range(struct compact_control *cc, break; pfn = cc->migrate_pfn; tries = 0; - } else if (++tries == 5) { + } else if (++tries == max_tries) { ret = -EBUSY; break; } @@ -9428,7 +9432,11 @@ int alloc_contig_range(unsigned long start, unsigned long end, .nr_migratepages = 0, .order = -1, .zone = page_zone(pfn_to_page(start)), - .mode = MIGRATE_SYNC, + /* + * Use MIGRATE_ASYNC for __GFP_NORETRY requests as it never + * blocks. + */ + .mode = gfp_mask & __GFP_NORETRY ? MIGRATE_ASYNC : MIGRATE_SYNC, .ignore_skip_hint = true, .no_set_skip_hint = true, .gfp_mask = current_gfp_context(gfp_mask), @@ -9474,7 +9482,7 @@ int alloc_contig_range(unsigned long start, unsigned long end, * -EBUSY is not accidentally used or returned to caller. */ ret = __alloc_contig_migrate_range(&cc, start, end); - if (ret && ret != -EBUSY) + if (ret && (ret != -EBUSY || (gfp_mask & __GFP_NORETRY))) goto done; ret = 0; From 5723833390aca77a0f2f61a24278958dec47982f Mon Sep 17 00:00:00 2001 From: Richard Chang Date: Wed, 29 Nov 2023 06:41:13 +0000 Subject: [PATCH 23/27] ANDROID: mm: lru_cache_disable skips lru cache drainnig lru_cache_disable is not trivial cost since it should run work from every cores in the system. Thus, repeated call of the function whenever alloc_contig_range in the cma's allocation loop is called is expensive. This patch makes the lru_cache_disable smarter in that it will not run __lru_add_drain_all since it knows the cache was already disabled by someone else. With that, user of alloc_contig_range can disable the lru cache in advance in their context so that subsequent alloc_contig_range for user's operation will avoid the costly function call. Bug: 313795505 Change-Id: Icbb0e6dbf74644d45f562fd1d845888ca1f1f347 Signed-off-by: Richard Chang (cherry picked from commit 816567b17866ca3f9a11e670bd52c82335cbb448) --- mm/swap.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mm/swap.c b/mm/swap.c index 955930f41d20..32bc97b73831 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -933,6 +933,7 @@ void lru_add_drain_all(void) #endif /* CONFIG_SMP */ atomic_t lru_disable_count = ATOMIC_INIT(0); +EXPORT_SYMBOL_GPL(lru_disable_count); /* * lru_cache_disable() needs to be called before we start compiling @@ -944,7 +945,12 @@ atomic_t lru_disable_count = ATOMIC_INIT(0); */ void lru_cache_disable(void) { - atomic_inc(&lru_disable_count); + /* + * If someone is already disabled lru_cache, just return with + * increasing the lru_disable_count. + */ + if (atomic_inc_not_zero(&lru_disable_count)) + return; /* * Readers of lru_disable_count are protected by either disabling * preemption or rcu_read_lock: @@ -964,7 +970,9 @@ void lru_cache_disable(void) #else lru_add_and_bh_lrus_drain(); #endif + atomic_inc(&lru_disable_count); } +EXPORT_SYMBOL_GPL(lru_cache_disable); /** * release_pages - batched put_page() From 3c9cb9c06fb99d6e685bc643250ae804050da8eb Mon Sep 17 00:00:00 2001 From: Seiya Wang Date: Wed, 6 Dec 2023 09:24:40 +0800 Subject: [PATCH 24/27] ANDROID: GKI: Update symbol list for mtk ABI impact 8 function symbol(s) added 'struct mii_bus* devm_mdiobus_alloc_size(struct device*, int)' 'struct phy_device* of_phy_get_and_connect(struct net_device*, struct device_node*, void(*)(struct net_device*))' 'int pci_enable_device_mem(struct pci_dev*)' 'int pci_prepare_to_sleep(struct pci_dev*)' 'int pci_select_bars(struct pci_dev*, unsigned long)' 'void phy_support_asym_pause(struct phy_device*)' 'int ptp_find_pin(struct ptp_clock*, enum ptp_pin_function, unsigned int)' 'int ptp_schedule_worker(struct ptp_clock*, unsigned long)' 1 variable symbol(s) added 'struct efi efi' Add following symbols devm_alloc_etherdev_mqs devm_mdiobus_alloc_size efi eth_prepare_mac_addr_change of_get_mac_address of_phy_get_and_connect pci_disable_msi pci_disable_msix pci_enable_device_mem pci_enable_msi pci_enable_msix_range pci_prepare_to_sleep pci_release_selected_regions pci_request_selected_regions pci_select_bars pci_set_power_state phy_connect_direct phy_ethtool_get_eee phy_ethtool_get_wol phy_ethtool_set_eee phy_ethtool_set_wol phy_find_first phy_init_eee phy_mii_ioctl phy_remove_link_mode phy_start_aneg phy_support_asym_pause ptp_clock_event ptp_clock_index ptp_clock_register ptp_clock_unregister ptp_find_pin ptp_schedule_worker Bug: 315023870 Signed-off-by: Seiya Wang Change-Id: I046b656fe9049a701ca6a440111eb4bfa420cf52 --- android/abi_gki_aarch64.stg | 1154 +++++++++++++++++++++++++++++++++++ android/abi_gki_aarch64_mtk | 37 +- 2 files changed, 1189 insertions(+), 2 deletions(-) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index a393ee0f1c95..1e54366d133a 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -2578,6 +2578,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x0c50d752 } +pointer_reference { + id: 0x098a183d + kind: POINTER + pointee_type_id: 0x0c688668 +} pointer_reference { id: 0x099bbff0 kind: POINTER @@ -3483,6 +3488,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x1b573ecd } +pointer_reference { + id: 0x0c461eae + kind: POINTER + pointee_type_id: 0x1b589c24 +} pointer_reference { id: 0x0c467c34 kind: POINTER @@ -4288,6 +4298,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x1e7452a1 } +pointer_reference { + id: 0x0d0d381b + kind: POINTER + pointee_type_id: 0x1e7406f0 +} pointer_reference { id: 0x0d0ed0eb kind: POINTER @@ -4723,6 +4738,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x1f202bf3 } +pointer_reference { + id: 0x0d5919cc + kind: POINTER + pointee_type_id: 0x1f2481af +} pointer_reference { id: 0x0d599e4a kind: POINTER @@ -8328,6 +8348,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x60a0624a } +pointer_reference { + id: 0x12bb09bf + kind: POINTER + pointee_type_id: 0x60acc062 +} pointer_reference { id: 0x12bb35ff kind: POINTER @@ -9103,6 +9128,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x7091586a } +pointer_reference { + id: 0x16c24c4b + kind: POINTER + pointee_type_id: 0x7149d7b2 +} pointer_reference { id: 0x16c47ce6 kind: POINTER @@ -9443,6 +9473,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x4a83930e } +pointer_reference { + id: 0x18332140 + kind: POINTER + pointee_type_id: 0x4a8c639c +} pointer_reference { id: 0x18374f23 kind: POINTER @@ -9713,6 +9748,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x4ff92706 } +pointer_reference { + id: 0x19775fd3 + kind: POINTER + pointee_type_id: 0x4f9d99d2 +} pointer_reference { id: 0x1977e57b kind: POINTER @@ -10293,6 +10333,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x5a93fcf2 } +pointer_reference { + id: 0x1c3d637d + kind: POINTER + pointee_type_id: 0x5ab56b69 +} pointer_reference { id: 0x1c4f6f14 kind: POINTER @@ -10413,6 +10458,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x5934cfbb } +pointer_reference { + id: 0x1cde2620 + kind: POINTER + pointee_type_id: 0x59387e1c +} pointer_reference { id: 0x1ce0cd04 kind: POINTER @@ -10853,6 +10903,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x53d09af0 } +pointer_reference { + id: 0x1e7406f0 + kind: POINTER + pointee_type_id: 0x5390fd5f +} pointer_reference { id: 0x1e7a7830 kind: POINTER @@ -11398,6 +11453,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xa9083bc9 } +pointer_reference { + id: 0x20d5467c + kind: POINTER + pointee_type_id: 0xa915ff6e +} pointer_reference { id: 0x20e2ed71 kind: POINTER @@ -12048,6 +12108,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xa5348d85 } +pointer_reference { + id: 0x23e1331e + kind: POINTER + pointee_type_id: 0xa5c42ae6 +} pointer_reference { id: 0x23e765f6 kind: POINTER @@ -12078,6 +12143,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xa5a4159e } +pointer_reference { + id: 0x2404a5b9 + kind: POINTER + pointee_type_id: 0xba52707a +} pointer_reference { id: 0x24159bc9 kind: POINTER @@ -12823,6 +12893,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xb52b1ec7 } +pointer_reference { + id: 0x27e94f78 + kind: POINTER + pointee_type_id: 0xb5e5db7c +} pointer_reference { id: 0x27f7746a kind: POINTER @@ -13453,6 +13528,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x863aeeaf } +pointer_reference { + id: 0x2b1e9432 + kind: POINTER + pointee_type_id: 0x863ab655 +} pointer_reference { id: 0x2b1ef221 kind: POINTER @@ -13538,6 +13618,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x87b3d0e4 } +pointer_reference { + id: 0x2b7f9bcf + kind: POINTER + pointee_type_id: 0x87be89a0 +} pointer_reference { id: 0x2b820c5e kind: POINTER @@ -13663,6 +13748,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x85d54423 } +pointer_reference { + id: 0x2be72e40 + kind: POINTER + pointee_type_id: 0x85dc5f9c +} pointer_reference { id: 0x2bf214c5 kind: POINTER @@ -23578,6 +23668,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xe6a4c2b9 } +pointer_reference { + id: 0x3339abb1 + kind: POINTER + pointee_type_id: 0xe6a6485a +} pointer_reference { id: 0x333a16a5 kind: POINTER @@ -24948,6 +25043,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xfda4bf28 } +pointer_reference { + id: 0x35fa9cee + kind: POINTER + pointee_type_id: 0xfdaa9525 +} pointer_reference { id: 0x35feb7e2 kind: POINTER @@ -26008,6 +26108,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xca9a982e } +pointer_reference { + id: 0x38397349 + kind: POINTER + pointee_type_id: 0xcaa52bbb +} pointer_reference { id: 0x383b946e kind: POINTER @@ -26783,6 +26888,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xcd30372f } +pointer_reference { + id: 0x39e2de2e + kind: POINTER + pointee_type_id: 0xcdcb9e25 +} pointer_reference { id: 0x39e76e0a kind: POINTER @@ -29978,6 +30088,126 @@ typedef { name: "drmres_release_t" referred_type_id: 0x0d1edb4c } +typedef { + id: 0x60acc062 + name: "efi_bool_t" + referred_type_id: 0x295c7202 +} +typedef { + id: 0x5390fd5f + name: "efi_capsule_header_t" + referred_type_id: 0x176e427f +} +typedef { + id: 0x87be89a0 + name: "efi_char16_t" + referred_type_id: 0x914dbfdc +} +typedef { + id: 0xba52707a + name: "efi_get_next_high_mono_count_t" + referred_type_id: 0x7a9510d5 +} +typedef { + id: 0xa915ff6e + name: "efi_get_next_variable_t" + referred_type_id: 0x75996794 +} +typedef { + id: 0x1f2481af + name: "efi_get_time_t" + referred_type_id: 0x7c02d9fb +} +typedef { + id: 0x5ab56b69 + name: "efi_get_variable_t" + referred_type_id: 0x7e158c17 +} +typedef { + id: 0xcdcb9e25 + name: "efi_get_wakeup_time_t" + referred_type_id: 0x704d4a08 +} +typedef { + id: 0x4f9d99d2 + name: "efi_guid_t" + referred_type_id: 0xbb354ed2 +} +typedef { + id: 0xcaa52bbb + name: "efi_memory_desc_t" + referred_type_id: 0x0f515b9c +} +typedef { + id: 0x59387e1c + name: "efi_query_capsule_caps_t" + referred_type_id: 0x7724ccc4 +} +typedef { + id: 0x85dc5f9c + name: "efi_query_variable_info_t" + referred_type_id: 0x4650cb40 +} +typedef { + id: 0x863ab655 + name: "efi_reset_system_t" + referred_type_id: 0x0bd54e18 +} +typedef { + id: 0x637b0d47 + name: "efi_runtime_services_32_t" + referred_type_id: 0x1290e0da +} +typedef { + id: 0xeade97e2 + name: "efi_runtime_services_t" + referred_type_id: 0x5f35183b +} +typedef { + id: 0x4a8c639c + name: "efi_set_time_t" + referred_type_id: 0x7c59d0ca +} +typedef { + id: 0x0c688668 + name: "efi_set_variable_t" + referred_type_id: 0x7e292e71 +} +typedef { + id: 0xfdaa9525 + name: "efi_set_virtual_address_map_t" + referred_type_id: 0x7883b251 +} +typedef { + id: 0x1b589c24 + name: "efi_set_wakeup_time_t" + referred_type_id: 0x6c0528d9 +} +typedef { + id: 0xa256f9e0 + name: "efi_status_t" + referred_type_id: 0x33756485 +} +typedef { + id: 0x18c2371d + name: "efi_table_hdr_t" + referred_type_id: 0x13b9015a +} +typedef { + id: 0x7149d7b2 + name: "efi_time_cap_t" + referred_type_id: 0x07bac27a +} +typedef { + id: 0xa5c42ae6 + name: "efi_time_t" + referred_type_id: 0x0e61f205 +} +typedef { + id: 0xb5e5db7c + name: "efi_update_capsule_t" + referred_type_id: 0x7723dac0 +} typedef { id: 0x160ba102 name: "errseq_t" @@ -33473,6 +33703,11 @@ qualified { qualifier: CONST qualified_type_id: 0xea5f49fa } +qualified { + id: 0xe6a6485a + qualifier: CONST + qualified_type_id: 0xeade97e2 +} qualified { id: 0xe6b1c981 qualifier: CONST @@ -38674,6 +38909,10 @@ member { id: 0x27604dcc type_id: 0x12af4722 } +member { + id: 0x276fa87a + type_id: 0x1290d1fa +} member { id: 0x277f4bd0 type_id: 0x12d35f52 @@ -42692,6 +42931,18 @@ member { type_id: 0xe62ebf07 offset: 128 } +member { + id: 0xa5dcc6e6 + name: "acpi" + type_id: 0x33756485 + offset: 128 +} +member { + id: 0x143bea26 + name: "acpi20" + type_id: 0x33756485 + offset: 192 +} member { id: 0x4ff7664a name: "acpi_match" @@ -50052,6 +50303,12 @@ member { type_id: 0x5d8155a5 offset: 72 } +member { + id: 0xa9e9695c + name: "attribute" + type_id: 0x92233392 + offset: 256 +} member { id: 0x031bf6f0 name: "attributes" @@ -62804,6 +63061,12 @@ member { type_id: 0x30fbef83 offset: 10880 } +member { + id: 0xce011157 + name: "coco_secret" + type_id: 0x33756485 + offset: 640 +} member { id: 0x5406c379 name: "code" @@ -65456,6 +65719,18 @@ member { type_id: 0x1aa00f75 offset: 256 } +member { + id: 0x3164d396 + name: "convert_pointer" + type_id: 0xc9082b19 + offset: 352 +} +member { + id: 0x31b56999 + name: "convert_pointer" + type_id: 0x18bd6530 + offset: 512 +} member { id: 0x3c519ec3 name: "convert_rgb" @@ -67205,6 +67480,12 @@ member { type_id: 0xa7b169d5 offset: 12288 } +member { + id: 0xc3af16b1 + name: "crc32" + type_id: 0xc9082b19 + offset: 128 +} member { id: 0xeff5afc8 name: "crcount" @@ -70816,6 +71097,18 @@ member { type_id: 0xc272516a offset: 1600 } +member { + id: 0x9d61f5a9 + name: "day" + type_id: 0x295c7202 + offset: 24 +} +member { + id: 0x2b8c4071 + name: "daylight" + type_id: 0x295c7202 + offset: 112 +} member { id: 0xf540eeb1 name: "db_off" @@ -73048,6 +73341,12 @@ member { type_id: 0x86728ee6 offset: 640 } +member { + id: 0xa99ce2eb + name: "desc_size" + type_id: 0x33756485 + offset: 320 +} member { id: 0xbf901141 name: "desc_submitted" @@ -73072,6 +73371,12 @@ member { type_id: 0x295c7202 offset: 176 } +member { + id: 0x6a37229f + name: "desc_version" + type_id: 0x33756485 + offset: 256 +} member { id: 0x703132a7 name: "describe" @@ -83451,6 +83756,12 @@ member { name: "esp_ip6_spec" type_id: 0x6df98672 } +member { + id: 0x3185ff82 + name: "esrt" + type_id: 0x33756485 + offset: 384 +} member { id: 0x951f933e name: "essid" @@ -90180,6 +90491,12 @@ member { type_id: 0xc9082b19 offset: 32 } +member { + id: 0x2da18195 + name: "flags" + type_id: 0xc9082b19 + offset: 160 +} member { id: 0x2da18312 name: "flags" @@ -95565,6 +95882,24 @@ member { type_id: 0x072c4dd8 offset: 768 } +member { + id: 0x496161cd + name: "get_next_high_mono_count" + type_id: 0x2404a5b9 + offset: 768 +} +member { + id: 0x49616e33 + name: "get_next_high_mono_count" + type_id: 0x2404a5b9 + offset: 1472 +} +member { + id: 0x498c645d + name: "get_next_high_mono_count" + type_id: 0xc9082b19 + offset: 480 +} member { id: 0x09a37e30 name: "get_next_id" @@ -95577,6 +95912,24 @@ member { type_id: 0x2f805571 offset: 448 } +member { + id: 0x1674d2aa + name: "get_next_variable" + type_id: 0x20d5467c + offset: 640 +} +member { + id: 0x1674d3cc + name: "get_next_variable" + type_id: 0x20d5467c + offset: 1024 +} +member { + id: 0x169d0bde + name: "get_next_variable" + type_id: 0xc9082b19 + offset: 416 +} member { id: 0x7bcf7568 name: "get_nextdqblk" @@ -96055,12 +96408,30 @@ member { type_id: 0x2f8d0c79 offset: 128 } +member { + id: 0xce251045 + name: "get_time" + type_id: 0xc9082b19 + offset: 192 +} member { id: 0xcec1755a name: "get_time" type_id: 0x2d646f41 offset: 384 } +member { + id: 0xcee14177 + name: "get_time" + type_id: 0x0d5919cc + offset: 192 +} +member { + id: 0xcee14b83 + name: "get_time" + type_id: 0x0d5919cc + offset: 704 +} member { id: 0x8899228d name: "get_time_info" @@ -96193,6 +96564,24 @@ member { type_id: 0x2f9d83f0 offset: 384 } +member { + id: 0xf823afc2 + name: "get_variable" + type_id: 0xc9082b19 + offset: 384 +} +member { + id: 0xf8f6926a + name: "get_variable" + type_id: 0x1c3d637d + offset: 576 +} +member { + id: 0xf8f693eb + name: "get_variable" + type_id: 0x1c3d637d + offset: 960 +} member { id: 0xf2712792 name: "get_vblank_counter" @@ -96235,6 +96624,24 @@ member { type_id: 0x1e0272bf offset: 832 } +member { + id: 0xeb0dd87f + name: "get_wakeup_time" + type_id: 0x39e2de2e + offset: 320 +} +member { + id: 0xeb0ddc02 + name: "get_wakeup_time" + type_id: 0x39e2de2e + offset: 832 +} +member { + id: 0xebfd35e6 + name: "get_wakeup_time" + type_id: 0xc9082b19 + offset: 256 +} member { id: 0xd6627db5 name: "get_wireless_stats" @@ -97388,6 +97795,11 @@ member { offset: 2817 bitsize: 1 } +member { + id: 0x3c0f35cf + name: "guid" + type_id: 0x4f9d99d2 +} member { id: 0x3cad5ec0 name: "guid" @@ -98847,6 +99259,11 @@ member { name: "hdr" type_id: 0x34544a3f } +member { + id: 0x2b3cdf2c + name: "hdr" + type_id: 0x18c2371d +} member { id: 0x2b9cf3b8 name: "hdr" @@ -99357,6 +99774,18 @@ member { type_id: 0x4585663f offset: 64 } +member { + id: 0x07022d2e + name: "headersize" + type_id: 0xc9082b19 + offset: 128 +} +member { + id: 0x07022d6f + name: "headersize" + type_id: 0xc9082b19 + offset: 96 +} member { id: 0x3e17b5ef name: "headroom" @@ -100530,6 +100959,12 @@ member { type_id: 0xdba44af3 offset: 26944 } +member { + id: 0x354661e5 + name: "hour" + type_id: 0x295c7202 + offset: 32 +} member { id: 0x386f84a8 name: "hours" @@ -104743,6 +105178,12 @@ member { type_id: 0xecb578cc offset: 192 } +member { + id: 0xd085c3bb + name: "imagesize" + type_id: 0xc9082b19 + offset: 192 +} member { id: 0x29fda9b7 name: "imb_numa_nr" @@ -120024,6 +120465,12 @@ member { type_id: 0x18bd6530 offset: 896 } +member { + id: 0x8deec833 + name: "map" + type_id: 0x18bd6530 + offset: 64 +} member { id: 0x8df0341e name: "map" @@ -120170,6 +120617,12 @@ member { type_id: 0x2c7bd73f offset: 576 } +member { + id: 0xffcfe84d + name: "map_end" + type_id: 0x18bd6530 + offset: 128 +} member { id: 0x3d93c0fb name: "map_extra" @@ -124931,6 +125384,12 @@ member { name: "memcpy_count" type_id: 0x33756485 } +member { + id: 0x61add198 + name: "memmap" + type_id: 0x6d3133ff + offset: 1600 +} member { id: 0x1f4a9078 name: "memory" @@ -126275,6 +126734,12 @@ member { offset: 290 bitsize: 1 } +member { + id: 0x5e451a8d + name: "minute" + type_id: 0x295c7202 + offset: 40 +} member { id: 0x096ecb61 name: "minutes" @@ -126381,6 +126846,11 @@ member { type_id: 0x3a3eb2f9 offset: 128 } +member { + id: 0x50bf919b + name: "mixed_mode" + type_id: 0x637b0d47 +} member { id: 0x20799ec4 name: "mixer_list" @@ -127931,6 +128401,12 @@ member { type_id: 0x4585663f offset: 32 } +member { + id: 0xb24eefd4 + name: "mokvar_table" + type_id: 0x33756485 + offset: 576 +} member { id: 0xf30fcad7 name: "monitor" @@ -128027,6 +128503,12 @@ member { type_id: 0x5d8155a5 offset: 208 } +member { + id: 0x646c9078 + name: "month" + type_id: 0x295c7202 + offset: 16 +} member { id: 0x90205d1d name: "more" @@ -130629,6 +131111,12 @@ member { type_id: 0x295c7202 offset: 11200 } +member { + id: 0x82684d30 + name: "nanosecond" + type_id: 0xc9082b19 + offset: 64 +} member { id: 0x0db69ff9 name: "nanosleep" @@ -135503,6 +135991,12 @@ member { type_id: 0xc9082b19 offset: 8160 } +member { + id: 0xd5423e30 + name: "nr_map" + type_id: 0x6720d32f + offset: 192 +} member { id: 0x183eb746 name: "nr_maps" @@ -137459,6 +137953,12 @@ member { type_id: 0x914dbfdc offset: 448 } +member { + id: 0x9636a0da + name: "num_pages" + type_id: 0x92233392 + offset: 192 +} member { id: 0x9697faa5 name: "num_pages" @@ -142928,6 +143428,12 @@ member { type_id: 0x7dc8196c offset: 44704 } +member { + id: 0x6b1d84ac + name: "pad" + type_id: 0xc9082b19 + offset: 32 +} member { id: 0x6b32a238 name: "pad" @@ -142986,6 +143492,12 @@ member { type_id: 0xc9082b19 offset: 512 } +member { + id: 0x66ddb2cc + name: "pad1" + type_id: 0x295c7202 + offset: 56 +} member { id: 0x66ddb3c1 name: "pad1" @@ -142997,6 +143509,12 @@ member { type_id: 0x295c7202 offset: 16 } +member { + id: 0xba1fb973 + name: "pad2" + type_id: 0x295c7202 + offset: 120 +} member { id: 0xbaffe3eb name: "pad2" @@ -147071,6 +147589,12 @@ member { name: "phys_addr" type_id: 0xe02e14d6 } +member { + id: 0xbdd9d264 + name: "phys_addr" + type_id: 0x92233392 + offset: 64 +} member { id: 0xbdd9d476 name: "phys_addr" @@ -147141,6 +147665,11 @@ member { name: "phys_id" type_id: 0x295c7202 } +member { + id: 0xb865a736 + name: "phys_map" + type_id: 0xbdd18903 +} member { id: 0xda31db2e name: "physfn" @@ -155835,6 +156364,24 @@ member { name: "query" type_id: 0x2d07e8c3 } +member { + id: 0x2030d39d + name: "query_capsule_caps" + type_id: 0xc9082b19 + offset: 576 +} +member { + id: 0x20e50411 + name: "query_capsule_caps" + type_id: 0x1cde2620 + offset: 960 +} +member { + id: 0x20e50e11 + name: "query_capsule_caps" + type_id: 0x1cde2620 + offset: 1408 +} member { id: 0xb20e9921 name: "query_dv_timings" @@ -155858,6 +156405,30 @@ member { type_id: 0x2fbd64da offset: 448 } +member { + id: 0xdf4e61c6 + name: "query_variable_info" + type_id: 0xc9082b19 + offset: 608 +} +member { + id: 0xdfac892e + name: "query_variable_info" + type_id: 0x2be72e40 + offset: 1024 +} +member { + id: 0xdfac8cf5 + name: "query_variable_info" + type_id: 0x2be72e40 + offset: 1216 +} +member { + id: 0xcda14674 + name: "query_variable_info_nonblocking" + type_id: 0x2be72e40 + offset: 1280 +} member { id: 0xb2749bb6 name: "querystd" @@ -163736,6 +164307,12 @@ member { type_id: 0xc9082b19 offset: 32 } +member { + id: 0xd4aaa9b1 + name: "reserved" + type_id: 0xc9082b19 + offset: 160 +} member { id: 0xd4acfe44 name: "reserved" @@ -164413,6 +164990,24 @@ member { type_id: 0x2ced3956 offset: 512 } +member { + id: 0xf24ab676 + name: "reset_system" + type_id: 0x2b1e9432 + offset: 832 +} +member { + id: 0xf24abf2b + name: "reset_system" + type_id: 0x2b1e9432 + offset: 1536 +} +member { + id: 0xf2a8a86b + name: "reset_system" + type_id: 0xc9082b19 + offset: 512 +} member { id: 0xa4c83369 name: "reset_time" @@ -164557,6 +165152,11 @@ member { type_id: 0xc9082b19 offset: 320 } +member { + id: 0x7f319ce7 + name: "resolution" + type_id: 0xc9082b19 +} member { id: 0x7fcbe549 name: "resolution" @@ -165525,6 +166125,12 @@ member { type_id: 0x914dbfdc offset: 64 } +member { + id: 0x9461d051 + name: "revision" + type_id: 0xc9082b19 + offset: 64 +} member { id: 0x9481899b name: "revision" @@ -167650,6 +168256,11 @@ member { type_id: 0x92233392 offset: 512 } +member { + id: 0x2909be74 + name: "runtime" + type_id: 0x3339abb1 +} member { id: 0x29148356 name: "runtime" @@ -167718,6 +168329,12 @@ member { type_id: 0x495d0861 offset: 2080 } +member { + id: 0x660fc4ac + name: "runtime_supported_mask" + type_id: 0x4585663f + offset: 96 +} member { id: 0x9615b712 name: "runtime_suspend" @@ -167742,6 +168359,12 @@ member { type_id: 0x071b6d64 offset: 5248 } +member { + id: 0x4bd4c3ca + name: "runtime_version" + type_id: 0x4585663f + offset: 64 +} member { id: 0xb1650641 name: "rvdevs" @@ -171542,6 +172165,12 @@ member { type_id: 0x35fdd62d offset: 1376 } +member { + id: 0x7d99a861 + name: "second" + type_id: 0x295c7202 + offset: 48 +} member { id: 0xcae5ab59 name: "second_chroma_qp_index_offset" @@ -174358,12 +174987,30 @@ member { type_id: 0x2d66bab9 offset: 768 } +member { + id: 0x6a0000ef + name: "set_time" + type_id: 0x18332140 + offset: 768 +} +member { + id: 0x6a0008ea + name: "set_time" + type_id: 0x18332140 + offset: 256 +} member { id: 0x6a35d0ba name: "set_time" type_id: 0x2de218bf offset: 128 } +member { + id: 0x6ad1306f + name: "set_time" + type_id: 0xc9082b19 + offset: 224 +} member { id: 0x05571fa2 name: "set_timeout" @@ -174465,6 +175112,30 @@ member { type_id: 0x2fac8db0 offset: 2560 } +member { + id: 0x0f6b33b0 + name: "set_variable" + type_id: 0x098a183d + offset: 1088 +} +member { + id: 0x0f6b3cfb + name: "set_variable" + type_id: 0x098a183d + offset: 704 +} +member { + id: 0x0fabbb82 + name: "set_variable" + type_id: 0xc9082b19 + offset: 448 +} +member { + id: 0x6b538354 + name: "set_variable_nonblocking" + type_id: 0x098a183d + offset: 1152 +} member { id: 0xfef444a6 name: "set_vbus" @@ -174501,6 +175172,18 @@ member { type_id: 0x2e0b807c offset: 512 } +member { + id: 0x22096f18 + name: "set_virtual_address_map" + type_id: 0x35fa9cee + offset: 448 +} +member { + id: 0x22f59d1f + name: "set_virtual_address_map" + type_id: 0xc9082b19 + offset: 320 +} member { id: 0xde8621f7 name: "set_voltage" @@ -174544,6 +175227,24 @@ member { type_id: 0x2dc1540f offset: 2560 } +member { + id: 0xc76f0215 + name: "set_wakeup_time" + type_id: 0x0c461eae + offset: 896 +} +member { + id: 0xc76f0921 + name: "set_wakeup_time" + type_id: 0x0c461eae + offset: 384 +} +member { + id: 0xc7aa425f + name: "set_wakeup_time" + type_id: 0xc9082b19 + offset: 288 +} member { id: 0xf4be2934 name: "set_wedge" @@ -174619,6 +175320,12 @@ member { name: "sets" type_id: 0xea789c46 } +member { + id: 0x3bedbbf9 + name: "sets_to_zero" + type_id: 0x295c7202 + offset: 64 +} member { id: 0x85254c52 name: "setsockopt" @@ -176278,6 +176985,11 @@ member { type_id: 0x6d7f5ff6 offset: 2640 } +member { + id: 0x2fc17015 + name: "signature" + type_id: 0x92233392 +} member { id: 0x58d2d9eb name: "signum" @@ -178611,6 +179323,18 @@ member { type_id: 0x2e0f9112 offset: 448 } +member { + id: 0x0628a254 + name: "smbios" + type_id: 0x33756485 + offset: 256 +} +member { + id: 0xb4183bf1 + name: "smbios3" + type_id: 0x33756485 + offset: 320 +} member { id: 0x20b3b280 name: "smbus_xfer" @@ -190343,6 +191067,12 @@ member { type_id: 0x80904a3b offset: 192 } +member { + id: 0x9fcea18f + name: "timezone" + type_id: 0x29bf06ba + offset: 96 +} member { id: 0xe1406108 name: "timing" @@ -191337,6 +192067,18 @@ member { offset: 3370 bitsize: 1 } +member { + id: 0x3b4ba6b3 + name: "tpm_final_log" + type_id: 0x33756485 + offset: 512 +} +member { + id: 0x1dc560eb + name: "tpm_log" + type_id: 0x33756485 + offset: 448 +} member { id: 0x14f2c5a7 name: "tq" @@ -197737,6 +198479,24 @@ member { name: "update_bits" type_id: 0x2cbe4f96 } +member { + id: 0x3e3992db + name: "update_capsule" + type_id: 0x27e94f78 + offset: 1344 +} +member { + id: 0x3e3992fe + name: "update_capsule" + type_id: 0x27e94f78 + offset: 896 +} +member { + id: 0x3ed777e3 + name: "update_capsule" + type_id: 0xc9082b19 + offset: 544 +} member { id: 0x56b05005 name: "update_curr" @@ -202272,6 +203032,12 @@ member { name: "virt" type_id: 0x14e40ca3 } +member { + id: 0x14aa07f5 + name: "virt_addr" + type_id: 0x92233392 + offset: 128 +} member { id: 0xc21c7538 name: "virt_base" @@ -207352,6 +208118,11 @@ member { type_id: 0xe62ebf07 offset: 800 } +member { + id: 0x58522abd + name: "year" + type_id: 0x914dbfdc +} member { id: 0xd01d6076 name: "yes_ranges" @@ -207970,6 +208741,16 @@ struct_union { member_id: 0x2d0fa9b6 } } +struct_union { + id: 0x07bac27a + kind: STRUCT + definition { + bytesize: 12 + member_id: 0x7f319ce7 + member_id: 0x6bbd8f78 + member_id: 0x3bedbbf9 + } +} struct_union { id: 0x07d0e9f2 kind: STRUCT @@ -208487,6 +209268,24 @@ struct_union { member_id: 0x96fedfda } } +struct_union { + id: 0x0e61f205 + kind: STRUCT + definition { + bytesize: 16 + member_id: 0x58522abd + member_id: 0x646c9078 + member_id: 0x9d61f5a9 + member_id: 0x354661e5 + member_id: 0x5e451a8d + member_id: 0x7d99a861 + member_id: 0x66ddb2cc + member_id: 0x82684d30 + member_id: 0x9fcea18f + member_id: 0x2b8c4071 + member_id: 0xba1fb973 + } +} struct_union { id: 0x0e7661fa kind: STRUCT @@ -208553,6 +209352,19 @@ struct_union { member_id: 0x6037a967 } } +struct_union { + id: 0x0f515b9c + kind: STRUCT + definition { + bytesize: 40 + member_id: 0x5c9fdd55 + member_id: 0x6b1d84ac + member_id: 0xbdd9d264 + member_id: 0x14aa07f5 + member_id: 0x9636a0da + member_id: 0xa9e9695c + } +} struct_union { id: 0x0f55086a kind: STRUCT @@ -208760,6 +209572,50 @@ struct_union { member_id: 0x283653a1 } } +struct_union { + id: 0x1290d1fa + kind: STRUCT + definition { + bytesize: 136 + member_id: 0x2b3cdf2c + member_id: 0xcee14177 + member_id: 0x6a0008ea + member_id: 0xeb0dd87f + member_id: 0xc76f0921 + member_id: 0x22096f18 + member_id: 0x31b56999 + member_id: 0xf8f6926a + member_id: 0x1674d2aa + member_id: 0x0f6b3cfb + member_id: 0x496161cd + member_id: 0xf24ab676 + member_id: 0x3e3992fe + member_id: 0x20e50411 + member_id: 0xdfac892e + } +} +struct_union { + id: 0x1290e0da + kind: STRUCT + definition { + bytesize: 80 + member_id: 0x2b3cdf2c + member_id: 0xce251045 + member_id: 0x6ad1306f + member_id: 0xebfd35e6 + member_id: 0xc7aa425f + member_id: 0x22f59d1f + member_id: 0x3164d396 + member_id: 0xf823afc2 + member_id: 0x169d0bde + member_id: 0x0fabbb82 + member_id: 0x498c645d + member_id: 0xf2a8a86b + member_id: 0x3ed777e3 + member_id: 0x2030d39d + member_id: 0xdf4e61c6 + } +} struct_union { id: 0x12af4722 kind: STRUCT @@ -208938,6 +209794,18 @@ struct_union { member_id: 0x91a23ae0 } } +struct_union { + id: 0x13b9015a + kind: STRUCT + definition { + bytesize: 24 + member_id: 0x2fc17015 + member_id: 0x9461d051 + member_id: 0x07022d6f + member_id: 0xc3af16b1 + member_id: 0xd4aaa9b1 + } +} struct_union { id: 0x13be4e13 kind: STRUCT @@ -209211,6 +210079,17 @@ struct_union { member_id: 0xd0323df9 } } +struct_union { + id: 0x176e427f + kind: STRUCT + definition { + bytesize: 28 + member_id: 0x3c0f35cf + member_id: 0x07022d2e + member_id: 0x2da18195 + member_id: 0xd085c3bb + } +} struct_union { id: 0x17a8337c kind: STRUCT @@ -212845,6 +213724,15 @@ struct_union { member_id: 0x36aedf4a } } +struct_union { + id: 0x5f35183b + kind: UNION + definition { + bytesize: 136 + member_id: 0x276fa87a + member_id: 0x50bf919b + } +} struct_union { id: 0x5f360cda kind: UNION @@ -226514,6 +227402,57 @@ struct_union { member_id: 0x2a729a89 } } +struct_union { + id: 0x33fc912b + kind: STRUCT + name: "efi" + definition { + bytesize: 264 + member_id: 0x2909be74 + member_id: 0x4bd4c3ca + member_id: 0x660fc4ac + member_id: 0xa5dcc6e6 + member_id: 0x143bea26 + member_id: 0x0628a254 + member_id: 0xb4183bf1 + member_id: 0x3185ff82 + member_id: 0x1dc560eb + member_id: 0x3b4ba6b3 + member_id: 0xb24eefd4 + member_id: 0xce011157 + member_id: 0xcee14b83 + member_id: 0x6a0000ef + member_id: 0xeb0ddc02 + member_id: 0xc76f0215 + member_id: 0xf8f693eb + member_id: 0x1674d3cc + member_id: 0x0f6b33b0 + member_id: 0x6b538354 + member_id: 0xdfac8cf5 + member_id: 0xcda14674 + member_id: 0x3e3992db + member_id: 0x20e50e11 + member_id: 0x49616e33 + member_id: 0xf24abf2b + member_id: 0x61add198 + member_id: 0x2d5bf6b8 + } +} +struct_union { + id: 0x6d3133ff + kind: STRUCT + name: "efi_memory_map" + definition { + bytesize: 56 + member_id: 0xb865a736 + member_id: 0x8deec833 + member_id: 0xffcfe84d + member_id: 0xd5423e30 + member_id: 0x6a37229f + member_id: 0xa99ce2eb + member_id: 0x2d5bf0a8 + } +} struct_union { id: 0x498e9c84 kind: STRUCT @@ -286456,6 +287395,14 @@ function { return_type_id: 0x48b5725f parameter_id: 0x6d7f5ff6 } +function { + id: 0x0bd54e18 + return_type_id: 0x48b5725f + parameter_id: 0x6720d32f + parameter_id: 0xa256f9e0 + parameter_id: 0x33756485 + parameter_id: 0x2b7f9bcf +} function { id: 0x0bdc9e9d return_type_id: 0x48b5725f @@ -299648,6 +300595,14 @@ function { parameter_id: 0x2e18f543 parameter_id: 0x6720d32f } +function { + id: 0x4650cb40 + return_type_id: 0xa256f9e0 + parameter_id: 0xc9082b19 + parameter_id: 0x2e18f543 + parameter_id: 0x2e18f543 + parameter_id: 0x2e18f543 +} function { id: 0x4677b893 return_type_id: 0x00a43052 @@ -301872,6 +302827,12 @@ function { parameter_id: 0x054f691a parameter_id: 0x0baa70a7 } +function { + id: 0x6c0528d9 + return_type_id: 0xa256f9e0 + parameter_id: 0x60acc062 + parameter_id: 0x23e1331e +} function { id: 0x6c109ae9 return_type_id: 0x249959de @@ -302117,6 +303078,13 @@ function { parameter_id: 0x3e10b518 parameter_id: 0xa52a0930 } +function { + id: 0x704d4a08 + return_type_id: 0xa256f9e0 + parameter_id: 0x12bb09bf + parameter_id: 0x12bb09bf + parameter_id: 0x23e1331e +} function { id: 0x706a01e7 return_type_id: 0x150d4db0 @@ -302285,6 +303253,13 @@ function { return_type_id: 0x249959de parameter_id: 0x6720d32f } +function { + id: 0x75996794 + return_type_id: 0xa256f9e0 + parameter_id: 0x064d6086 + parameter_id: 0x2b7f9bcf + parameter_id: 0x19775fd3 +} function { id: 0x75b5d4f6 return_type_id: 0x34990483 @@ -302314,11 +303289,34 @@ function { parameter_id: 0x191de370 parameter_id: 0x20054a7b } +function { + id: 0x7723dac0 + return_type_id: 0xa256f9e0 + parameter_id: 0x0d0d381b + parameter_id: 0x33756485 + parameter_id: 0x33756485 +} +function { + id: 0x7724ccc4 + return_type_id: 0xa256f9e0 + parameter_id: 0x0d0d381b + parameter_id: 0x33756485 + parameter_id: 0x2e18f543 + parameter_id: 0x13580d6c +} function { id: 0x77ba21a4 return_type_id: 0xc9082b19 parameter_id: 0xc9082b19 } +function { + id: 0x7883b251 + return_type_id: 0xa256f9e0 + parameter_id: 0x33756485 + parameter_id: 0x33756485 + parameter_id: 0xc9082b19 + parameter_id: 0x38397349 +} function { id: 0x7885d99e return_type_id: 0x356691bc @@ -302397,6 +303395,11 @@ function { parameter_id: 0x322c8c4b parameter_id: 0x3e10b518 } +function { + id: 0x7a9510d5 + return_type_id: 0xa256f9e0 + parameter_id: 0x38d23361 +} function { id: 0x7aa931ca return_type_id: 0x347303b4 @@ -302462,6 +303465,17 @@ function { parameter_id: 0x6720d32f parameter_id: 0x6720d32f } +function { + id: 0x7c02d9fb + return_type_id: 0xa256f9e0 + parameter_id: 0x23e1331e + parameter_id: 0x16c24c4b +} +function { + id: 0x7c59d0ca + return_type_id: 0xa256f9e0 + parameter_id: 0x23e1331e +} function { id: 0x7c92c1e0 return_type_id: 0x20e8fc5a @@ -302489,6 +303503,15 @@ function { return_type_id: 0x0d835382 parameter_id: 0x32a623d7 } +function { + id: 0x7e158c17 + return_type_id: 0xa256f9e0 + parameter_id: 0x2b7f9bcf + parameter_id: 0x19775fd3 + parameter_id: 0x38d23361 + parameter_id: 0x064d6086 + parameter_id: 0x18bd6530 +} function { id: 0x7e1a7d05 return_type_id: 0x24e24923 @@ -302499,6 +303522,15 @@ function { return_type_id: 0x097315c2 parameter_id: 0x0258f96e } +function { + id: 0x7e292e71 + return_type_id: 0xa256f9e0 + parameter_id: 0x2b7f9bcf + parameter_id: 0x19775fd3 + parameter_id: 0xc9082b19 + parameter_id: 0x33756485 + parameter_id: 0x18bd6530 +} function { id: 0x7e8c435e return_type_id: 0x24e24923 @@ -311430,6 +312462,13 @@ function { parameter_id: 0x29c600bb parameter_id: 0x1a2c7f0e } +function { + id: 0x979ed47c + return_type_id: 0x6720d32f + parameter_id: 0x2ba06eea + parameter_id: 0x39d36c32 + parameter_id: 0x4585663f +} function { id: 0x979f6a1e return_type_id: 0x6720d32f @@ -311450,6 +312489,12 @@ function { parameter_id: 0x2efe8065 parameter_id: 0x6720d32f } +function { + id: 0x97a52d07 + return_type_id: 0x6720d32f + parameter_id: 0x2ba06eea + parameter_id: 0x33756485 +} function { id: 0x97a9f709 return_type_id: 0xf435685e @@ -313145,6 +314190,12 @@ function { parameter_id: 0x6d7f5ff6 parameter_id: 0x6d7f5ff6 } +function { + id: 0x9934972e + return_type_id: 0x6720d32f + parameter_id: 0x11e6864c + parameter_id: 0x33756485 +} function { id: 0x99361691 return_type_id: 0x6720d32f @@ -326297,6 +327348,12 @@ function { parameter_id: 0x015f6fbc parameter_id: 0x13580d6c } +function { + id: 0xaf8309b1 + return_type_id: 0x35d510c3 + parameter_id: 0x0258f96e + parameter_id: 0x6720d32f +} function { id: 0xafbe8077 return_type_id: 0xfc0e1dbd @@ -326805,6 +327862,13 @@ function { parameter_id: 0x0d9c4ffe parameter_id: 0xeeed68e6 } +function { + id: 0xbfa57bbb + return_type_id: 0x3176a085 + parameter_id: 0x32a623d7 + parameter_id: 0x347303b4 + parameter_id: 0x0d9c4ffe +} function { id: 0xbfa66420 return_type_id: 0x3176a085 @@ -351472,6 +352536,15 @@ elf_symbol { type_id: 0x9df52a21 full_name: "devm_mbox_controller_register" } +elf_symbol { + id: 0x407c1985 + name: "devm_mdiobus_alloc_size" + is_defined: true + symbol_type: FUNCTION + crc: 0x9fa63a80 + type_id: 0xaf8309b1 + full_name: "devm_mdiobus_alloc_size" +} elf_symbol { id: 0x888f691d name: "devm_memremap" @@ -357954,6 +359027,15 @@ elf_symbol { type_id: 0x13309e7e full_name: "edac_device_handle_ue_count" } +elf_symbol { + id: 0x7a956b27 + name: "efi" + is_defined: true + symbol_type: OBJECT + crc: 0x1dfaa4dd + type_id: 0x33fc912b + full_name: "efi" +} elf_symbol { id: 0x03c26bf9 name: "ehci_handshake" @@ -372489,6 +373571,15 @@ elf_symbol { type_id: 0x1cde4dc9 full_name: "of_phy_get" } +elf_symbol { + id: 0x763a65a9 + name: "of_phy_get_and_connect" + is_defined: true + symbol_type: FUNCTION + crc: 0x354c8fe6 + type_id: 0xbfa57bbb + full_name: "of_phy_get_and_connect" +} elf_symbol { id: 0x783e3f26 name: "of_phy_is_fixed_link" @@ -373599,6 +374690,15 @@ elf_symbol { type_id: 0x99f942bc full_name: "pci_enable_device" } +elf_symbol { + id: 0xf1728c3f + name: "pci_enable_device_mem" + is_defined: true + symbol_type: FUNCTION + crc: 0x768edbe7 + type_id: 0x99f942bc + full_name: "pci_enable_device_mem" +} elf_symbol { id: 0xf6382d08 name: "pci_enable_msi" @@ -373986,6 +375086,15 @@ elf_symbol { type_id: 0x0d750257 full_name: "pci_pio_to_address" } +elf_symbol { + id: 0x4d0b5a53 + name: "pci_prepare_to_sleep" + is_defined: true + symbol_type: FUNCTION + crc: 0x48ca07a1 + type_id: 0x99f942bc + full_name: "pci_prepare_to_sleep" +} elf_symbol { id: 0x162de729 name: "pci_read_config_byte" @@ -374148,6 +375257,15 @@ elf_symbol { type_id: 0x99f942bc full_name: "pci_save_state" } +elf_symbol { + id: 0xc62d75dd + name: "pci_select_bars" + is_defined: true + symbol_type: FUNCTION + crc: 0x158de67a + type_id: 0x9934972e + full_name: "pci_select_bars" +} elf_symbol { id: 0x9595d229 name: "pci_set_master" @@ -375120,6 +376238,15 @@ elf_symbol { type_id: 0x1cc5f9b2 full_name: "phy_stop" } +elf_symbol { + id: 0x6d95635a + name: "phy_support_asym_pause" + is_defined: true + symbol_type: FUNCTION + crc: 0x44c22a15 + type_id: 0x1cc5f9b2 + full_name: "phy_support_asym_pause" +} elf_symbol { id: 0xf1503ace name: "phy_support_sym_pause" @@ -377298,6 +378425,15 @@ elf_symbol { type_id: 0x9768f895 full_name: "ptp_clock_unregister" } +elf_symbol { + id: 0xa07a6e08 + name: "ptp_find_pin" + is_defined: true + symbol_type: FUNCTION + crc: 0x68ec234a + type_id: 0x979ed47c + full_name: "ptp_find_pin" +} elf_symbol { id: 0x683db5bf name: "ptp_parse_header" @@ -377307,6 +378443,15 @@ elf_symbol { type_id: 0x9587d027 full_name: "ptp_parse_header" } +elf_symbol { + id: 0x496c5195 + name: "ptp_schedule_worker" + is_defined: true + symbol_type: FUNCTION + crc: 0xa2d0a911 + type_id: 0x97a52d07 + full_name: "ptp_schedule_worker" +} elf_symbol { id: 0x177fa0e0 name: "public_key_verify_signature" @@ -399096,6 +400241,7 @@ interface { symbol_id: 0x0f9aedf8 symbol_id: 0x92b974cd symbol_id: 0x57498e16 + symbol_id: 0x407c1985 symbol_id: 0x888f691d symbol_id: 0x86c1623f symbol_id: 0x36e39cf6 @@ -399814,6 +400960,7 @@ interface { symbol_id: 0x20ac879e symbol_id: 0xd85f1ace symbol_id: 0x1b003d7c + symbol_id: 0x7a956b27 symbol_id: 0x03c26bf9 symbol_id: 0x5d5a2134 symbol_id: 0x53a8b40e @@ -401429,6 +402576,7 @@ interface { symbol_id: 0x76fed243 symbol_id: 0x3ea82fd1 symbol_id: 0xb8340e79 + symbol_id: 0x763a65a9 symbol_id: 0x783e3f26 symbol_id: 0xeb2dab5b symbol_id: 0x5516ad40 @@ -401552,6 +402700,7 @@ interface { symbol_id: 0x96b46225 symbol_id: 0x35a3d772 symbol_id: 0x86bcc4a0 + symbol_id: 0xf1728c3f symbol_id: 0xf6382d08 symbol_id: 0x433f7035 symbol_id: 0x8238784d @@ -401595,6 +402744,7 @@ interface { symbol_id: 0x9d3ae050 symbol_id: 0x2f7fc8d4 symbol_id: 0x180e6903 + symbol_id: 0x4d0b5a53 symbol_id: 0x162de729 symbol_id: 0x5983afac symbol_id: 0x8c3e2fab @@ -401613,6 +402763,7 @@ interface { symbol_id: 0xd2a1df18 symbol_id: 0x18bfee32 symbol_id: 0x53d0da35 + symbol_id: 0xc62d75dd symbol_id: 0x9595d229 symbol_id: 0xe770d8d1 symbol_id: 0xa321b388 @@ -401721,6 +402872,7 @@ interface { symbol_id: 0x6e315775 symbol_id: 0x10d51eda symbol_id: 0x7a9c49cb + symbol_id: 0x6d95635a symbol_id: 0xf1503ace symbol_id: 0x2c0117f0 symbol_id: 0xa3314c5c @@ -401963,7 +403115,9 @@ interface { symbol_id: 0x8becb370 symbol_id: 0x42a88d96 symbol_id: 0xb36e22d3 + symbol_id: 0xa07a6e08 symbol_id: 0x683db5bf + symbol_id: 0x496c5195 symbol_id: 0x177fa0e0 symbol_id: 0xd38a2f2a symbol_id: 0x11d4227b diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk index ad1f5f4cac16..d6dd01bc8c43 100644 --- a/android/abi_gki_aarch64_mtk +++ b/android/abi_gki_aarch64_mtk @@ -454,6 +454,7 @@ devlink_unregister dev_load devm_add_action + devm_alloc_etherdev_mqs __devm_alloc_percpu devm_backlight_device_register devm_bitmap_zalloc @@ -503,6 +504,7 @@ devm_led_classdev_register_ext devm_led_classdev_unregister devm_mbox_controller_register + devm_mdiobus_alloc_size devm_memremap devm_mfd_add_devices devm_nvmem_cell_get @@ -877,6 +879,7 @@ dst_cache_set_ip6 dst_release dump_stack + efi em_cpu_get em_dev_register_perf_domain enable_irq @@ -888,6 +891,7 @@ eth_header_parse eth_mac_addr eth_platform_get_mac_address + eth_prepare_mac_addr_change ethtool_convert_legacy_u32_to_link_mode ethtool_convert_link_mode_to_legacy_u32 __ethtool_get_link_ksettings @@ -1689,6 +1693,7 @@ __of_get_address of_get_child_by_name of_get_cpu_node + of_get_mac_address of_get_named_gpio_flags of_get_next_available_child of_get_next_child @@ -1717,6 +1722,7 @@ of_pci_get_max_link_speed of_phandle_iterator_init of_phandle_iterator_next + of_phy_get_and_connect of_phy_simple_xlate of_platform_depopulate of_platform_device_create @@ -1784,9 +1790,14 @@ pci_dev_put pci_disable_ats pci_disable_device + pci_disable_msi + pci_disable_msix pcie_capability_clear_and_set_word pcie_capability_read_word pci_enable_ats + pci_enable_device_mem + pci_enable_msi + pci_enable_msix_range pci_find_ext_capability pci_free_irq pci_free_irq_vectors @@ -1806,14 +1817,19 @@ pci_msi_mask_irq pci_msi_unmask_irq pci_pio_to_address + pci_prepare_to_sleep pci_read_config_dword pci_read_config_word __pci_register_driver + pci_release_selected_regions pci_remove_root_bus pci_request_irq + pci_request_selected_regions pci_restore_state pci_save_state + pci_select_bars pci_set_master + pci_set_power_state pci_stop_root_bus pci_store_saved_state pci_unlock_rescan_remove @@ -1839,14 +1855,21 @@ pfn_is_map_memory phy_attached_info phy_connect + phy_connect_direct phy_disconnect phy_do_ioctl_running + phy_ethtool_get_eee phy_ethtool_get_link_ksettings + phy_ethtool_get_wol phy_ethtool_nway_reset + phy_ethtool_set_eee phy_ethtool_set_link_ksettings + phy_ethtool_set_wol phy_exit + phy_find_first phy_get phy_init + phy_init_eee phylink_connect_phy phylink_create phylink_destroy @@ -1858,13 +1881,17 @@ phylink_start phylink_stop phylink_suspend + phy_mii_ioctl phy_power_off phy_power_on phy_print_status phy_put + phy_remove_link_mode phy_set_mode_ext phy_start + phy_start_aneg phy_stop + phy_support_asym_pause phy_suspend pick_migrate_task pid_task @@ -1984,6 +2011,12 @@ pstore_register pstore_type_to_name pstore_unregister + ptp_clock_event + ptp_clock_index + ptp_clock_register + ptp_clock_unregister + ptp_find_pin + ptp_schedule_worker put_cmsg __put_cred put_device @@ -2694,10 +2727,10 @@ __traceiter_android_vh_iommu_iovad_alloc_iova __traceiter_android_vh_iommu_iovad_free_iova __traceiter_android_vh_is_fpsimd_save - __traceiter_android_vh_mmc_update_mmc_queue __traceiter_android_vh_mm_alloc_pages_direct_reclaim_enter __traceiter_android_vh_mm_alloc_pages_direct_reclaim_exit __traceiter_android_vh_mm_alloc_pages_may_oom_exit + __traceiter_android_vh_mmc_update_mmc_queue __traceiter_android_vh_rwsem_init __traceiter_android_vh_rwsem_wake __traceiter_android_vh_rwsem_write_finished @@ -2802,10 +2835,10 @@ __tracepoint_android_vh_iommu_iovad_alloc_iova __tracepoint_android_vh_iommu_iovad_free_iova __tracepoint_android_vh_is_fpsimd_save - __tracepoint_android_vh_mmc_update_mmc_queue __tracepoint_android_vh_mm_alloc_pages_direct_reclaim_enter __tracepoint_android_vh_mm_alloc_pages_direct_reclaim_exit __tracepoint_android_vh_mm_alloc_pages_may_oom_exit + __tracepoint_android_vh_mmc_update_mmc_queue __tracepoint_android_vh_rwsem_init __tracepoint_android_vh_rwsem_wake __tracepoint_android_vh_rwsem_write_finished From c9b5c232e7152ac1ad5e61148b17588215bf5bdf Mon Sep 17 00:00:00 2001 From: Taylor Nelms Date: Thu, 7 Dec 2023 16:38:17 +0000 Subject: [PATCH 25/27] ANDROID: Update the ABI symbol list Adding the following symbols: - devm_drm_of_get_bridge - drm_kms_helper_connector_hotplug_event - of_find_mipi_dsi_host_by_node - of_get_parent - of_graph_get_remote_node 1 function symbol(s) added 'void drm_kms_helper_connector_hotplug_event(struct drm_connector*)' Bug: 303500701 Change-Id: Ief76bed701a62cb89cad78cc3d141ee6c6a84dad Signed-off-by: Taylor Nelms --- android/abi_gki_aarch64.stg | 10 ++++++++++ android/abi_gki_aarch64_pixel | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 1e54366d133a..2a708ffe2af0 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -357299,6 +357299,15 @@ elf_symbol { type_id: 0xfa1de4ef full_name: "drm_is_current_master" } +elf_symbol { + id: 0xc8af6225 + name: "drm_kms_helper_connector_hotplug_event" + is_defined: true + symbol_type: FUNCTION + crc: 0x826aa0b9 + type_id: 0x1cf53808 + full_name: "drm_kms_helper_connector_hotplug_event" +} elf_symbol { id: 0x8a043efe name: "drm_kms_helper_hotplug_event" @@ -400768,6 +400777,7 @@ interface { symbol_id: 0x25989156 symbol_id: 0x3a6e27e9 symbol_id: 0xec79cf1c + symbol_id: 0xc8af6225 symbol_id: 0x8a043efe symbol_id: 0xb6107be5 symbol_id: 0x3c6b600d diff --git a/android/abi_gki_aarch64_pixel b/android/abi_gki_aarch64_pixel index e6ca8e996123..8da36c314c22 100644 --- a/android/abi_gki_aarch64_pixel +++ b/android/abi_gki_aarch64_pixel @@ -410,6 +410,7 @@ devm_device_add_groups devm_device_remove_group __devm_drm_dev_alloc + devm_drm_of_get_bridge devm_drm_panel_bridge_add_typed devm_extcon_dev_allocate devm_extcon_dev_register @@ -727,6 +728,7 @@ drm_helper_mode_fill_fb_struct drm_helper_probe_single_connector_modes drm_ioctl + drm_kms_helper_connector_hotplug_event drm_kms_helper_hotplug_event drm_kms_helper_poll_fini drm_kms_helper_poll_init @@ -1407,6 +1409,7 @@ of_find_i2c_adapter_by_node of_find_i2c_device_by_node of_find_matching_node_and_match + of_find_mipi_dsi_host_by_node of_find_node_by_name of_find_node_by_phandle of_find_node_by_type @@ -1421,11 +1424,13 @@ of_get_next_available_child of_get_next_child of_get_next_parent + of_get_parent of_get_property of_get_regulator_init_data of_graph_get_next_endpoint of_graph_get_port_parent of_graph_get_remote_endpoint + of_graph_get_remote_node of_graph_is_present of_graph_parse_endpoint of_iomap From ddf142e5a817e3a260e5dedce0cd29db6fbaa010 Mon Sep 17 00:00:00 2001 From: Jong eon Park Date: Wed, 29 Nov 2023 16:50:44 +0900 Subject: [PATCH 26/27] ANDROID: netlink: add netlink poll and hooks In huge uevents generating system, especially for user apps who have small size of rcvbuf socket, it has been reported that netlink overrun happens quite frequently. Moreover, if there's no POLLERR (caused by this netlink overrun) handler in user apps, the system can almost be stucked by calling 'poll' repeatedly. Regarding this issue, I have sent a kernel netlink patch to linux maintainers and got replied that this is absolutely user app's problem, must not addressing kernel. Until Android team look into this issue and some modification comes out, we need kernel patch for temporary. To minimize the effect by this patch to the others who have never met this issue, I would like to just add netlink's dedicated poll and its hooks. Please refer to below v1/v2 patch links for history. v1: https://lore.kernel.org/netdev/20231110110002.7279f895@kernel.org/T/#t v2: https://lore.kernel.org/netdev/d599922fd89b3e61c7cf531a03ea8b81cbcb003e.camel@redhat.com/T/#t Bug: 300009377 Link: https://lore.kernel.org/netdev/d599922fd89b3e61c7cf531a03ea8b81cbcb003e.camel@redhat.com/T/#t Change-Id: I4f11399d61c10332ba05bac64cfa1e92bb111565 Signed-off-by: Jong eon Park --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/net.h | 7 +++++++ net/netlink/af_netlink.c | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8425e8709b41..789fa7beea83 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -364,3 +364,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_blk_mq_rw_recovery); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sd_update_bus_speed_mode); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_slab_folio_alloced); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kmalloc_large_alloced); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_netlink_poll); diff --git a/include/trace/hooks/net.h b/include/trace/hooks/net.h index 50988f672216..835943c31f3d 100644 --- a/include/trace/hooks/net.h +++ b/include/trace/hooks/net.h @@ -25,6 +25,13 @@ DECLARE_RESTRICTED_HOOK(android_rvh_sk_alloc, DECLARE_RESTRICTED_HOOK(android_rvh_sk_free, TP_PROTO(struct sock *sock), TP_ARGS(sock), 1); +struct poll_table_struct; +typedef struct poll_table_struct poll_table; +DECLARE_HOOK(android_vh_netlink_poll, + TP_PROTO(struct file *file, struct socket *sock, poll_table *wait, + __poll_t *mask), + TP_ARGS(file, sock, wait, mask)); + /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_NET_VH_H */ diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index cb833302270a..5b328a82ea70 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -71,7 +71,8 @@ #include #define CREATE_TRACE_POINTS #include - +#undef CREATE_TRACE_POINTS +#include #include "af_netlink.h" struct listeners { @@ -1966,6 +1967,15 @@ out: return err ? : copied; } +static __poll_t netlink_poll(struct file *file, struct socket *sock, + poll_table *wait) +{ + __poll_t mask = datagram_poll(file, sock, wait); + + trace_android_vh_netlink_poll(file, sock, wait, &mask); + return mask; +} + static void netlink_data_ready(struct sock *sk) { BUG(); @@ -2766,7 +2776,7 @@ static const struct proto_ops netlink_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = netlink_getname, - .poll = datagram_poll, + .poll = netlink_poll, .ioctl = netlink_ioctl, .listen = sock_no_listen, .shutdown = sock_no_shutdown, From 2d8a5ddebb22fd1dab4c2fe3a7ba978be62423a3 Mon Sep 17 00:00:00 2001 From: Richard Chang Date: Thu, 7 Dec 2023 07:31:31 +0000 Subject: [PATCH 27/27] ANDROID: Update the ABI symbol list Adding the following symbol: - __cma_alloc Bug: 308881290 Change-Id: I5b3ffb0c804dc636355c1462aaa6e96b1189446b Signed-off-by: Richard Chang --- android/abi_gki_aarch64.stg | 18 ++++++++++++++++++ android/abi_gki_aarch64_pixel | 1 + 2 files changed, 19 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 2a708ffe2af0..b6bcc62d2c90 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -327602,6 +327602,14 @@ function { parameter_id: 0x4585663f parameter_id: 0x6d7f5ff6 } +function { + id: 0xb94f7fed + return_type_id: 0x06835e9c + parameter_id: 0x1023f4f6 + parameter_id: 0x33756485 + parameter_id: 0x4585663f + parameter_id: 0xf1a6dfed +} function { id: 0xb957d705 return_type_id: 0x6720d32f @@ -331936,6 +331944,15 @@ elf_symbol { type_id: 0x9b8e2bf2 full_name: "__clocksource_register_scale" } +elf_symbol { + id: 0xc7d06fb9 + name: "__cma_alloc" + is_defined: true + symbol_type: FUNCTION + crc: 0x5dbf1ea9 + type_id: 0xb94f7fed + full_name: "__cma_alloc" +} elf_symbol { id: 0xac1ff1ce name: "__const_udelay" @@ -397960,6 +397977,7 @@ interface { symbol_id: 0x6a30419a symbol_id: 0x021741b4 symbol_id: 0x9339caba + symbol_id: 0xc7d06fb9 symbol_id: 0xac1ff1ce symbol_id: 0xba429af2 symbol_id: 0xe495eb53 diff --git a/android/abi_gki_aarch64_pixel b/android/abi_gki_aarch64_pixel index 8da36c314c22..d19d3f7e39aa 100644 --- a/android/abi_gki_aarch64_pixel +++ b/android/abi_gki_aarch64_pixel @@ -188,6 +188,7 @@ clockevents_config_and_register clocks_calc_mult_shift __clocksource_register_scale + __cma_alloc cma_alloc cma_for_each_area cma_get_name