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: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: "Stefan Richter" <stefanr@s5r6.in-berlin.de>
This commit is contained in:
parent
dbc9880fa7
commit
e71084af58
|
@ -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. */
|
/* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */
|
||||||
if (card->reset_jiffies != 0 &&
|
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))
|
if (!schedule_delayed_work(&card->br_work, 2 * HZ))
|
||||||
fw_card_put(card);
|
fw_card_put(card);
|
||||||
return;
|
return;
|
||||||
|
@ -316,7 +316,8 @@ static void bm_work(struct work_struct *work)
|
||||||
irm_id = card->irm_node->node_id;
|
irm_id = card->irm_node->node_id;
|
||||||
local_id = card->local_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) &&
|
if ((is_next_generation(generation, card->bm_generation) &&
|
||||||
!card->bm_abdicate) ||
|
!card->bm_abdicate) ||
|
||||||
|
|
|
@ -1205,7 +1205,8 @@ static void iso_resource_work(struct work_struct *work)
|
||||||
todo = r->todo;
|
todo = r->todo;
|
||||||
/* Allow 1000ms grace period for other reallocations. */
|
/* Allow 1000ms grace period for other reallocations. */
|
||||||
if (todo == ISO_RES_ALLOC &&
|
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));
|
schedule_iso_resource(r, DIV_ROUND_UP(HZ, 3));
|
||||||
skip = true;
|
skip = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -747,7 +747,8 @@ static void fw_device_shutdown(struct work_struct *work)
|
||||||
container_of(work, struct fw_device, work.work);
|
container_of(work, struct fw_device, work.work);
|
||||||
int minor = MINOR(device->device.devt);
|
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)) {
|
&& !list_empty(&device->card->link)) {
|
||||||
schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
|
schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -545,7 +545,7 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
|
||||||
*/
|
*/
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
card->generation = generation;
|
card->generation = generation;
|
||||||
card->reset_jiffies = jiffies;
|
card->reset_jiffies = get_jiffies_64();
|
||||||
card->bm_node_id = 0xffff;
|
card->bm_node_id = 0xffff;
|
||||||
card->bm_abdicate = bm_abdicate;
|
card->bm_abdicate = bm_abdicate;
|
||||||
fw_schedule_bm_work(card, 0);
|
fw_schedule_bm_work(card, 0);
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct fw_card {
|
||||||
int current_tlabel;
|
int current_tlabel;
|
||||||
u64 tlabel_mask;
|
u64 tlabel_mask;
|
||||||
struct list_head transaction_list;
|
struct list_head transaction_list;
|
||||||
unsigned long reset_jiffies;
|
u64 reset_jiffies;
|
||||||
|
|
||||||
u32 split_timeout_hi;
|
u32 split_timeout_hi;
|
||||||
u32 split_timeout_lo;
|
u32 split_timeout_lo;
|
||||||
|
|
Loading…
Reference in a new issue