Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] v4l2-async: Don't use dynamic static allocation

Dynamic static allocation is evil, as Kernel stack is too low, and
compilation complains about it on some archs:
drivers/media/v4l2-core/v4l2-async.c:238:1: warning: 'v4l2_async_notifier_unregister' uses dynamic stack allocation [enabled by default]
Instead, let's enforce a limit for the buffer.
In this specific case, there's a hard limit imposed by V4L2_MAX_SUBDEVS,
with is currently 128. That means that the buffer size can be up to
128x8 = 1024 bytes (on a 64bits kernel), with is too big for stack.
Worse than that, someone could increase it and cause real troubles.
So, let's use dynamically allocated data, instead.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

+27 -3
+27 -3
drivers/media/v4l2-core/v4l2-async.c
··· 189 189 struct v4l2_subdev *sd, *tmp; 190 190 unsigned int notif_n_subdev = notifier->num_subdevs; 191 191 unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS); 192 - struct device *dev[n_subdev]; 192 + struct device **dev; 193 193 int i = 0; 194 194 195 195 if (!notifier->v4l2_dev) 196 196 return; 197 + 198 + dev = kmalloc(n_subdev * sizeof(*dev), GFP_KERNEL); 199 + if (!dev) { 200 + dev_err(notifier->v4l2_dev->dev, 201 + "Failed to allocate device cache!\n"); 202 + } 197 203 198 204 mutex_lock(&list_lock); 199 205 200 206 list_del(&notifier->list); 201 207 202 208 list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) { 203 - dev[i] = get_device(sd->dev); 209 + struct device *d; 210 + 211 + d = get_device(sd->dev); 204 212 205 213 v4l2_async_cleanup(sd); 206 214 207 215 /* If we handled USB devices, we'd have to lock the parent too */ 208 - device_release_driver(dev[i++]); 216 + device_release_driver(d); 209 217 210 218 if (notifier->unbind) 211 219 notifier->unbind(notifier, sd, sd->asd); 220 + 221 + /* 222 + * Store device at the device cache, in order to call 223 + * put_device() on the final step 224 + */ 225 + if (dev) 226 + dev[i++] = d; 227 + else 228 + put_device(d); 212 229 } 213 230 214 231 mutex_unlock(&list_lock); 215 232 233 + /* 234 + * Call device_attach() to reprobe devices 235 + * 236 + * NOTE: If dev allocation fails, i is 0, and the whole loop won't be 237 + * executed. 238 + */ 216 239 while (i--) { 217 240 struct device *d = dev[i]; 218 241 ··· 251 228 } 252 229 put_device(d); 253 230 } 231 + kfree(dev); 254 232 255 233 notifier->v4l2_dev = NULL; 256 234