Commit 77515eba authored by Duoming Zhou's avatar Duoming Zhou Committed by Greg Kroah-Hartman
Browse files

devcoredump: remove the useless gfp_t parameter in dev_coredumpv and dev_coredumpm



The dev_coredumpv() and dev_coredumpm() could not be used in atomic
context, because they call kvasprintf_const() and kstrdup() with
GFP_KERNEL parameter. The process is shown below:

dev_coredumpv(.., gfp_t gfp)
  dev_coredumpm(.., gfp_t gfp)
    dev_set_name
      kobject_set_name_vargs
        kvasprintf_const(GFP_KERNEL, ...); //may sleep
          kstrdup(s, GFP_KERNEL); //may sleep

This patch removes gfp_t parameter of dev_coredumpv() and dev_coredumpm()
and changes the gfp_t parameter of kzalloc() in dev_coredumpm() to
GFP_KERNEL in order to show they could not be used in atomic context.

Fixes: 833c9545 ("device coredump: add new device coredump class")
Reviewed-by: default avatarBrian Norris <briannorris@chromium.org>
Reviewed-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarDuoming Zhou <duoming@zju.edu.cn>
Link: https://lore.kernel.org/r/df72af3b1862bac7d8e793d1f3931857d3779dfd.1654569290.git.duoming@zju.edu.cn


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c21b0837
Loading
Loading
Loading
Loading
+6 −10
Original line number Diff line number Diff line
@@ -173,15 +173,13 @@ static void devcd_freev(void *data)
 * @dev: the struct device for the crashed device
 * @data: vmalloc data containing the device coredump
 * @datalen: length of the data
 * @gfp: allocation flags
 *
 * This function takes ownership of the vmalloc'ed data and will free
 * it when it is no longer used. See dev_coredumpm() for more information.
 */
void dev_coredumpv(struct device *dev, void *data, size_t datalen,
		   gfp_t gfp)
void dev_coredumpv(struct device *dev, void *data, size_t datalen)
{
	dev_coredumpm(dev, NULL, data, datalen, gfp, devcd_readv, devcd_freev);
	dev_coredumpm(dev, NULL, data, datalen, devcd_readv, devcd_freev);
}
EXPORT_SYMBOL_GPL(dev_coredumpv);

@@ -236,7 +234,6 @@ static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset,
 * @owner: the module that contains the read/free functions, use %THIS_MODULE
 * @data: data cookie for the @read/@free functions
 * @datalen: length of the data
 * @gfp: allocation flags
 * @read: function to read from the given buffer
 * @free: function to free the given buffer
 *
@@ -246,7 +243,7 @@ static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset,
 * function will be called to free the data.
 */
void dev_coredumpm(struct device *dev, struct module *owner,
		   void *data, size_t datalen, gfp_t gfp,
		   void *data, size_t datalen,
		   ssize_t (*read)(char *buffer, loff_t offset, size_t count,
				   void *data, size_t datalen),
		   void (*free)(void *data))
@@ -268,7 +265,7 @@ void dev_coredumpm(struct device *dev, struct module *owner,
	if (!try_module_get(owner))
		goto free;

	devcd = kzalloc(sizeof(*devcd), gfp);
	devcd = kzalloc(sizeof(*devcd), GFP_KERNEL);
	if (!devcd)
		goto put_module;

@@ -318,7 +315,6 @@ EXPORT_SYMBOL_GPL(dev_coredumpm);
 * @dev: the struct device for the crashed device
 * @table: the dump data
 * @datalen: length of the data
 * @gfp: allocation flags
 *
 * Creates a new device coredump for the given device. If a previous one hasn't
 * been read yet, the new coredump is discarded. The data lifetime is determined
@@ -326,9 +322,9 @@ EXPORT_SYMBOL_GPL(dev_coredumpm);
 * it will free the data.
 */
void dev_coredumpsg(struct device *dev, struct scatterlist *table,
		    size_t datalen, gfp_t gfp)
		    size_t datalen)
{
	dev_coredumpm(dev, NULL, table, datalen, gfp, devcd_read_from_sgtable,
	dev_coredumpm(dev, NULL, table, datalen, devcd_read_from_sgtable,
		      devcd_free_sgtable);
}
EXPORT_SYMBOL_GPL(dev_coredumpsg);
+1 −1
Original line number Diff line number Diff line
@@ -1515,7 +1515,7 @@ static void btmrvl_sdio_coredump(struct device *dev)
	/* fw_dump_data will be free in device coredump release function
	 * after 5 min
	 */
	dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL);
	dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len);
	BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
}

+1 −1
Original line number Diff line number Diff line
@@ -1120,7 +1120,7 @@ static void qca_controller_memdump(struct work_struct *work)
				    qca_memdump->ram_dump_size);
			memdump_buf = qca_memdump->memdump_buf_head;
			dev_coredumpv(&hu->serdev->dev, memdump_buf,
				      qca_memdump->received_dump, GFP_KERNEL);
				      qca_memdump->received_dump);
			cancel_delayed_work(&qca->ctrl_memdump_timeout);
			kfree(qca->qca_memdump);
			qca->qca_memdump = NULL;
+1 −1
Original line number Diff line number Diff line
@@ -225,5 +225,5 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit)

	etnaviv_core_dump_header(&iter, ETDUMP_BUF_END, iter.data);

	dev_coredumpv(gpu->dev, iter.start, iter.data - iter.start, GFP_KERNEL);
	dev_coredumpv(gpu->dev, iter.start, iter.data - iter.start);
}
+2 −2
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ static void _msm_disp_snapshot_work(struct kthread_work *work)
	 * If there is a codedump pending for the device, the dev_coredumpm()
	 * will also free new coredump state.
	 */
	dev_coredumpm(disp_state->dev, THIS_MODULE, disp_state, 0, GFP_KERNEL,
	dev_coredumpm(disp_state->dev, THIS_MODULE, disp_state, 0,
		      disp_devcoredump_read, msm_disp_state_free);
}

Loading