Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e71084af authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Stefan Richter
Browse files

firewire: core: fix card->reset_jiffies overflow



On a 32-bit machine with, e.g., HZ=1000, jiffies will overflow after
about 50 days, so if there are between 25 and 50 days between bus
resets, the card->reset_jiffies comparisons can get wrong results.

To fix this, ensure that this timestamp always uses 64 bits.

Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Signed-off-by: default avatar"Stefan Richter" <stefanr@s5r6.in-berlin.de>
parent dbc9880f
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -233,7 +233,7 @@ static void br_work(struct work_struct *work)

	/* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */
	if (card->reset_jiffies != 0 &&
	    time_is_after_jiffies(card->reset_jiffies + 2 * HZ)) {
	    time_before64(get_jiffies_64(), card->reset_jiffies + 2 * HZ)) {
		if (!schedule_delayed_work(&card->br_work, 2 * HZ))
			fw_card_put(card);
		return;
@@ -316,7 +316,8 @@ static void bm_work(struct work_struct *work)
	irm_id   = card->irm_node->node_id;
	local_id = card->local_node->node_id;

	grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8));
	grace = time_after64(get_jiffies_64(),
			     card->reset_jiffies + DIV_ROUND_UP(HZ, 8));

	if ((is_next_generation(generation, card->bm_generation) &&
	     !card->bm_abdicate) ||
+2 −1
Original line number Diff line number Diff line
@@ -1205,7 +1205,8 @@ static void iso_resource_work(struct work_struct *work)
	todo = r->todo;
	/* Allow 1000ms grace period for other reallocations. */
	if (todo == ISO_RES_ALLOC &&
	    time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
	    time_before64(get_jiffies_64(),
			  client->device->card->reset_jiffies + HZ)) {
		schedule_iso_resource(r, DIV_ROUND_UP(HZ, 3));
		skip = true;
	} else {
+2 −1
Original line number Diff line number Diff line
@@ -747,7 +747,8 @@ static void fw_device_shutdown(struct work_struct *work)
		container_of(work, struct fw_device, work.work);
	int minor = MINOR(device->device.devt);

	if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY)
	if (time_before64(get_jiffies_64(),
			  device->card->reset_jiffies + SHUTDOWN_DELAY)
	    && !list_empty(&device->card->link)) {
		schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
		return;
+1 −1
Original line number Diff line number Diff line
@@ -545,7 +545,7 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
	 */
	smp_wmb();
	card->generation = generation;
	card->reset_jiffies = jiffies;
	card->reset_jiffies = get_jiffies_64();
	card->bm_node_id  = 0xffff;
	card->bm_abdicate = bm_abdicate;
	fw_schedule_bm_work(card, 0);
+1 −1
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ struct fw_card {
	int current_tlabel;
	u64 tlabel_mask;
	struct list_head transaction_list;
	unsigned long reset_jiffies;
	u64 reset_jiffies;

	u32 split_timeout_hi;
	u32 split_timeout_lo;